cz 1 gadu atpakaļ
vecāks
revīzija
544ef7d93b

BIN
public/favicon.ico


+ 33 - 89
src/components/PDF/contractPDFOne.vue

@@ -1,66 +1,32 @@
 <template>
   <div>
-    <div
-      id="pdfDom"
-      ref="pdfDom"
-      style="padding: 30px 60px"
-      v-loading="loading"
-    >
-      <table border="1" style="width: 100%" class="table">
-        <tr>
-          <td style="width: 120px">
-            <img
-              :src="pdfData.companyPic"
-              alt=""
-              fit="scale-down"
-              style="height: 60px; width: 60px"
-            />
-          </td>
-          <td style="padding: 10px">
-            <div style="font-size: 18px" class="color-class">
-              {{ pdfData.sellCorporationNameEn }}
-            </div>
-            <div style="font-size: 18px" class="color-class">
-              {{ pdfData.sellCorporationName }}
-            </div>
+    <div id="pdfDom" ref="pdfDom" style="padding: 30px 60px" v-loading="loading">
+      <div>
+        福建三梵体育用品实业有限公司
+        <div>
+          销售订单
+        </div>
+        <div style="display:flex;font-weight:700">
+          <div style="width:50%">
+            <div class="row">
+              <div style="width:100px">
 
-            <div style="font-size: 14px; color: #000">
-              Address: {{ pdfData.sellDetailedAddressEn }}
-            </div>
-            <div style="font-size: 14px; color: #000; margin-top: 5px">
-              {{ pdfData.sellCityNameEn }} , {{ pdfData.sellProvinceNameEn }} ,
-              {{ pdfData.sellCountryNameEn }}
-            </div>
+              </div>
+              <div>
 
-            <div style="font-size: 14px; color: #000; margin-top: 10px">
-              地址: {{ pdfData.sellCountryName }} ,
-              {{ pdfData.sellProvinceName }} , {{ pdfData.sellCityName }}
-            </div>
-            <div style="font-size: 14px; color: #000; margin-top: 5px">
-              {{ pdfData.sellDetailedAddress }}
-            </div>
-            <div style="margin: 8px 0; color: black">
-              Tel: <span>{{ pdfData.sellContactNumber }}</span>
-              <!-- Fax:
-              <span>{{ pdfData.fax }}</span>
-               Website:
-              <span>{{ pdfData.Website }}</span> -->
+              </div>
             </div>
-          </td>
-        </tr>
-        <tr>
-          <td colspan="2">
-            <div
-              class="color-class"
-              style="text-align: center; font-size: 18px"
-            >
-              Proforma Invoice
+          </div>
+          <div style="width:50%">
+            <div class="row">
+
             </div>
-          </td>
-        </tr>
-      </table>
-      <div style="height: 15px; background: #7f197f"></div>
-      <table border="1" style="width: 100%" class="table">
+
+          </div>
+        </div>
+      </div>
+
+      <!-- <table border="1" style="width: 100%" class="table">
         <tr>
           <td style="width: 50%; text-align: left">
             Buyer: {{ pdfData.buyCorporationName }}
@@ -69,7 +35,7 @@
             Seller: {{ pdfData.sellCorporationNameEn }}
           </td>
         </tr>
-      </table>
+      </table> -->
       <table border="1" style="width: 100%; border-top: none" class="table">
         <tr>
           <td style="width: 15%">PI No.</td>
@@ -100,19 +66,11 @@
           <td style="width: 13%">Total <br />Amount</td>
         </tr>
 
-        <tr
-          v-if="pdfData.productInfoList && pdfData.productInfoList.length > 0"
-          v-for="(item, index) in pdfData.productInfoList"
-          :key="item.productId"
-        >
+        <tr v-if="pdfData.productInfoList && pdfData.productInfoList.length > 0" v-for="(item, index) in pdfData.productInfoList"
+            :key="item.productId">
           <td style="width: 15%">
-            <img
-              :src="item.fileList[0].fileUrl"
-              alt=""
-              fit="scale-down"
-              style="height: 60px; width: 60px"
-              v-if="item.fileList && item.fileList.length > 0"
-            />
+            <img :src="item.fileList[0].fileUrl" alt="" fit="scale-down" style="height: 60px; width: 60px"
+                 v-if="item.fileList && item.fileList.length > 0" />
           </td>
           <td style="width: 20%">{{ item.productName }}</td>
           <td style="width: 15%">
@@ -129,26 +87,18 @@
             {{ pdfData.currency }} {{ moneyFormat(item.amount, 2) }}
           </td>
         </tr>
-        <template
-          v-if="
+        <template v-if="
             pdfData.contractProjectList &&
             pdfData.contractProjectList.length > 0
-          "
-        >
+          ">
           <tr>
             <td colspan="6" style="text-align: right">
-              <div
-                v-for="(item, index) in pdfData.contractProjectList"
-                :key="item.id"
-              >
+              <div v-for="(item, index) in pdfData.contractProjectList" :key="item.id">
                 {{ item.payName }}:
               </div>
             </td>
             <td>
-              <div
-                v-for="(item, index) in pdfData.contractProjectList"
-                :key="item.id"
-              >
+              <div v-for="(item, index) in pdfData.contractProjectList" :key="item.id">
                 {{ pdfData.currency }}
                 {{ moneyFormat(item.amount, 2) }}
               </div>
@@ -261,13 +211,7 @@
           <td style="width: 50%; text-align: left">
             The Seller's Signature
             <div style="width: 200px; height: 200px">
-              <img
-                v-if="pdfData.companySeal"
-                :src="pdfData.companySeal"
-                alt=""
-                fit="scale-down"
-                style="height: 200px; width: 200px"
-              />
+              <img v-if="pdfData.companySeal" :src="pdfData.companySeal" alt="" fit="scale-down" style="height: 200px; width: 200px" />
             </div>
           </td>
         </tr>

+ 54 - 0
src/components/process/SF/Contract.vue

@@ -287,6 +287,12 @@
           </el-table>
         </div>
       </template>
+
+      <template #templateContent>
+        <div style="width: 100%">
+          <Editor :value="formData.data.templateContent" @updateValue="updateContent" />
+        </div>
+      </template>
     </byForm>
 
     <el-dialog v-if="openProductCompany" v-model="openProductCompany" title="公司产品库" width="90%" append-to-body>
@@ -305,6 +311,7 @@
 import byForm from "@/components/byForm/index";
 import SelectCompanyProduct from "@/components/product/SelectCompanyProduct.vue";
 import SelectProduct from "@/components/product/SelectProduct.vue";
+import Editor from "@/components/Editor/index.vue";
 
 // import SelectCustomerProduct from "@/components/product/SelectCustomerProduct.vue";
 import selectCity from "@/components/selectCity/index.vue";
@@ -331,6 +338,7 @@ const shippingMethod = computed(
 const companyId = computed(() => proxy.useUserStore().user.companyId);
 const accountList = ref([]);
 const customerList = ref([]);
+const templateList = ref([]);
 const corporationList = ref([]);
 const customerUserList = ref([]);
 const countryData = ref([]);
@@ -636,6 +644,31 @@ const formConfig = computed(() => {
       itemWidth: 25,
       disabled: true,
     },
+    {
+      type: "title",
+      title: "合同模板",
+      haveLine: true,
+    },
+    {
+      type: "select",
+      prop: "contractType",
+      label: "合同模板",
+      data: templateList.value,
+      itemWidth: 50,
+      fn: (val) => {
+        proxy.post("/contractTemplate/detail", { id: val }).then((res) => {
+          formData.data.remark = res.templateContent;
+        });
+      },
+    },
+    {
+      type: "slot",
+      slotName: "templateContent",
+      prop: "amount",
+      label: "模板内容",
+      itemWidth: 100,
+      disabled: false,
+    },
   ];
 });
 const rules = ref({
@@ -681,6 +714,19 @@ const rules = ref({
 });
 const getDict = () => {
   proxy
+    .post("/contractTemplate/page", {
+      pageNum: 1,
+      pageSize: 999,
+      templateType: "1",
+    })
+    .then((res) => {
+      templateList.value = res.rows.map((x) => ({
+        label: x.templateName,
+        value: x.id,
+      }));
+    });
+
+  proxy
     .post("/customer/selPage", {
       pageNum: 1,
       pageSize: 50,
@@ -917,6 +963,9 @@ const changeProductPrice = () => {
       });
   }
 };
+const updateContent = (val) => {
+  formData.data.templateContent = val;
+};
 const onPicture = (path) => {
   window.open(path, "_blank");
 };
@@ -1176,6 +1225,7 @@ const getPriceSheetData = (id) => {
   proxy.post("/extQuotation/detail", { id }).then((res) => {
     formData.data = res;
     formData.data = {
+      quotationId: res.id,
       companyId: res.companyId,
       buyCorporationId: res.buyCorporationId,
       buyAddress: res.buyAddress,
@@ -1193,6 +1243,7 @@ const getPriceSheetData = (id) => {
       formData.data.contractType = "1";
     }
     formData.data.contractProductList = res.quotationProductList.map((x) => ({
+      quotationProductId: x.id,
       fileUrl: "",
       productId: x.productId,
       productCnName: x.productName,
@@ -1351,4 +1402,7 @@ const clickCopy = (type) => {
   text-align: center;
   border: 1px dashed var(--el-border-color);
 }
+.ql-editor {
+  padding: 0px;
+}
 </style>

+ 2 - 2
src/components/process/SF/Purchase.vue

@@ -270,7 +270,7 @@
       </template>
 
       <template #contractClause>
-        <div style="width: 100%">
+        <div style="width: 100%;height:auto">
           <el-row style=" width: 100%">
             <el-col :span="8">
               <el-form-item label="合同模板" prop="contractTemplateId" class="wid100">
@@ -282,7 +282,7 @@
           </el-row>
           <div style=" width: 100%">
             <el-form-item label="条款内容" prop="remark" class="margin-b-0 wid100">
-              <Editor style="width: 100%" :value="formData.data.remark" @updateValue="updateContent" :readOnly="judgeStatus()" ref="remarkEditor" />
+              <Editor :value="formData.data.remark" @updateValue="updateContent" :readOnly="judgeStatus()" ref="remarkEditor" />
             </el-form-item>
           </div>
         </div>

+ 147 - 51
src/views/EHSD/saleContract/contractEHSD/index.vue

@@ -34,6 +34,16 @@
             <a style="color: #409eff; cursor: pointer" @click="clickCorporationName(item)">{{ item.buyCorporationName }}</a>
           </div>
         </template>
+
+        <template #prodTag="{ item }">
+          <div style="width: 100%">
+            <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.prodTags" closable :key="index"
+                    @close="prodTagClose(index, item)">
+              {{ dictKeyValue(tag, contractTag) }}
+            </el-tag>
+          </div>
+        </template>
+
         <template #tags="{ item }">
           <div style="width: 100%">
             <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.tags" closable :key="index" @close="tagClose(tag, item)">
@@ -69,14 +79,14 @@
     </div>
 
     <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="920">
-      <!-- <ContractPDFOne :rowData="rowData"></ContractPDFOne> -->
-      <ContractPDFOneNew :rowData="rowData" ref="PdfDom"></ContractPDFOneNew>
-      <template #footer>
+      <ContractPDFOne :rowData="rowData"></ContractPDFOne>
+      <!-- <ContractPDFOneNew :rowData="rowData" ref="PdfDom"></ContractPDFOneNew> -->
+      <!-- <template #footer>
         <el-button @click="openPrint = false" size="default">取消</el-button>
         <el-button type="primary" v-print="printObj" size="default">打印</el-button>
         <el-button type="primary" @click="clickDownload()" size="default">下载PDF</el-button>
         <el-button type="primary" @click="exportExcel()" size="default">导出Excel</el-button>
-      </template>
+      </template> -->
     </el-dialog>
 
     <el-dialog title="交接单" v-if="openHandoverSlip" v-model="openHandoverSlip" width="600">
@@ -179,6 +189,16 @@
       </template>
     </el-dialog>
 
+    <el-dialog :title="'生产指示'" v-model="tagDialog" width="500px" destroy-on-close>
+      <byForm :formConfig="tagFormConfig" :formOption="formOption" v-model="formData.tagData" :rules="tagRules" ref="tagFormDom"
+              v-loading="formLoading">
+      </byForm>
+      <template #footer>
+        <el-button @click="tagDialog =false" size="default" v-debounce>取 消</el-button>
+        <el-button @click="submitTag" type="primary" size="default" v-debounce>提 交</el-button>
+      </template>
+    </el-dialog>
+
   </div>
 </template>
 
@@ -193,6 +213,10 @@ import ContractPDFOne from "@/components/PDF/contractPDFOne.vue";
 import ContractPDFOneNew from "@/components/PDF/contractPDFOneNew.vue";
 
 const route = useRoute();
+
+const contractTag = computed(
+  () => proxy.useUserStore().allDict["contract_prod_tag"]
+);
 const { proxy } = getCurrentInstance();
 const accountCurrency = ref([]);
 const tradeMethods = ref([]);
@@ -356,7 +380,7 @@ const config = computed(() => {
       attrs: {
         label: "归属公司",
         prop: "companyName",
-        "min-width": 150,
+        width: 120,
       },
     },
     {
@@ -380,7 +404,7 @@ const config = computed(() => {
       attrs: {
         label: "客户名称",
         slot: "buyCorporationName",
-        "min-width": 140,
+        "min-width": 180,
       },
     },
     // {
@@ -470,6 +494,13 @@ const config = computed(() => {
     },
     {
       attrs: {
+        label: "生产指示",
+        slot: "prodTag",
+        "min-width": 160,
+      },
+    },
+    {
+      attrs: {
         label: "操作",
         width: 200,
         align: "center",
@@ -488,19 +519,19 @@ const config = computed(() => {
           //     clickHandoverSlip(row);
           //   },
           // },
-          row.status == 30
-            ? {
-                attrs: {
-                  label: "变更",
-                  type: "primary",
-                  text: true,
-                },
-                el: "button",
-                click() {
-                  clickAlteration(row);
-                },
-              }
-            : {},
+          // row.status == 30
+          //   ? {
+          //       attrs: {
+          //         label: "变更",
+          //         type: "primary",
+          //         text: true,
+          //       },
+          //       el: "button",
+          //       click() {
+          //         clickAlteration(row);
+          //       },
+          //     }
+          //   : {},
           row.status == 30
             ? {
                 attrs: {
@@ -588,47 +619,58 @@ const config = computed(() => {
             : {},
           {
             attrs: {
-              label: "售后",
+              label: "生产指示",
               type: "primary",
               text: true,
             },
             el: "button",
             click() {
-              openRecords.value = true;
-              getRecordsData(row);
+              handleEditTag(row);
             },
           },
+          // {
+          //   attrs: {
+          //     label: "售后",
+          //     type: "primary",
+          //     text: true,
+          //   },
+          //   el: "button",
+          //   click() {
+          //     openRecords.value = true;
+          //     getRecordsData(row);
+          //   },
+          // },
         ];
       },
     },
   ];
 });
 const getDict = () => {
-  proxy
-    .getDictOne([
-      "customer_tag",
-      "trade_mode",
-      "account_currency",
-      "shipping_method",
-    ])
-    .then((res) => {
-      customerTag.value = res["customer_tag"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-      tradeMethods.value = res["trade_mode"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-      accountCurrency.value = res["account_currency"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-      shippingMethod.value = res["shipping_method"].map((x) => ({
-        label: x.dictValue,
-        value: x.dictKey,
-      }));
-    });
+  // proxy
+  //   .getDictOne([
+  //     "customer_tag",
+  //     "trade_mode",
+  //     "account_currency",
+  //     "shipping_method",
+  //   ])
+  //   .then((res) => {
+  //     customerTag.value = res["customer_tag"].map((x) => ({
+  //       label: x.dictValue,
+  //       value: x.dictKey,
+  //     }));
+  //     tradeMethods.value = res["trade_mode"].map((x) => ({
+  //       label: x.dictValue,
+  //       value: x.dictKey,
+  //     }));
+  //     accountCurrency.value = res["account_currency"].map((x) => ({
+  //       label: x.dictValue,
+  //       value: x.dictKey,
+  //     }));
+  //     shippingMethod.value = res["shipping_method"].map((x) => ({
+  //       label: x.dictValue,
+  //       value: x.dictKey,
+  //     }));
+  //   });
   // proxy.post("/corporation/page", { pageNum: 1, pageSize: 999 }).then((res) => {
   //   corporationList.value = res.rows.map((item) => {
   //     return {
@@ -683,11 +725,16 @@ const getList = async (req) => {
   loading.value = true;
   proxy.post("/contract/page", sourceList.value.pagination).then((res) => {
     res.rows.forEach((x) => {
-      x.addTagShow = false;
-      if (x.tag) {
-        x.tags = x.tag.split(",");
+      // x.addTagShow = false;
+      // if (x.tag) {
+      //   x.tags = x.tag.split(",");
+      // } else {
+      //   x.tags = [];
+      // }
+      if (x.prodTag) {
+        x.prodTags = x.prodTag.split(",");
       } else {
-        x.tags = [];
+        x.prodTags = [];
       }
     });
     sourceList.value.data = res.rows;
@@ -1010,6 +1057,7 @@ const exportExcel = () => {
 const formData = reactive({
   recordsFormData: {},
   data: {},
+  tagData: {},
 });
 const formLoading = ref(false);
 const openRecords = ref(false);
@@ -1239,6 +1287,54 @@ const submitProduction = () => {
     });
   });
 };
+
+const handleEditTag = (row) => {
+  formData.tagData = {
+    id: row.id,
+    prodTag: row.prodTags,
+  };
+  tagDialog.value = true;
+};
+const tagFormDom = ref(null);
+const tagDialog = ref(false);
+const tagFormConfig = computed(() => [
+  {
+    type: "select",
+    prop: "prodTag",
+    label: "生产指示",
+    multiple: true,
+    data: contractTag.value,
+    itemWidth: 100,
+  },
+]);
+const tagRules = ref({
+  prodTag: [{ required: true, message: "请选择生产指示", trigger: "change" }],
+});
+const submitTag = () => {
+  tagFormDom.value.handleSubmit(() => {
+    const data = {
+      id: formData.tagData.id,
+      prodTag: formData.tagData.prodTag.join(","),
+    };
+    formLoading.value = true;
+    proxy.post("/contract/updateProductionTag", data).then((res) => {
+      proxy.msgTip("操作成功");
+      formLoading.value = false;
+      tagDialog.value = false;
+      getList();
+    });
+  });
+};
+
+const prodTagClose = (index, row) => {
+  row.prodTags.splice(index, 1);
+  proxy
+    .post("/contract/updateProductionTag", {
+      id: row.id,
+      prodTag: row.prodTags.join(","),
+    })
+    .then((res) => {});
+};
 </script>
 
 <style lang="scss" scoped>

+ 16 - 9
src/views/EHSD/saleContract/priceSheetEHSD/index.vue

@@ -63,9 +63,9 @@
             </span>
             <span>
               <el-button type="primary" text v-debounce v-if="item.quotationStatus==2" @click="handleBack(item)">退回</el-button>
-              <el-button type="primary" text v-debounce v-if="item.quotationStatus==2" @click="handleForeign(item)">转对外</el-button>
               <el-button type="primary" text v-debounce v-if="item.status == 30 && item.quotationStatus==2"
                          @click="getDtl(item, false,true)">变更</el-button>
+              <el-button type="primary" text v-debounce v-if="item.quotationStatus==2" @click="handleForeign(item)">转对外</el-button>
               <el-button type="danger" text v-debounce v-if="item.status !=0 && item.status !=88"
                          @click="handleRepeal(item,'/saleQuotation/cancellation')">作废</el-button>
             </span>
@@ -74,7 +74,7 @@
       </byTable>
     </div>
 
-    <el-dialog v-if="openAddDialog" v-model="openAddDialog" title="报价单" width="80%" append-to-body>
+    <el-dialog v-if="openAddDialog" v-model="openAddDialog" title="报价单" width="90%" append-to-body>
       <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom" v-loading="submitLoading">
         <template #chart>
           <div style="width:100%;padding-left:25px">
@@ -145,7 +145,8 @@
 
         <template #commodity>
           <div style="width: 100%;padding-left:25px">
-            <el-button type="primary" @click="openProductCompany = true" plain style="margin-bottom: 16px" v-if="!isDetail">产品库</el-button>
+            <el-button type="primary" @click="openProductCompany = true" plain style="margin-bottom: 16px" v-if="!isDetail"
+                       :disabled="!formData.data.companyId">产品库</el-button>
             <el-table :data="formData.data.quotationProductList" style="width: 100%;" default-expand-all row-key="productId">
               <el-table-column type="expand" width="50" align="center">
                 <template #default="scope">
@@ -204,8 +205,7 @@
                           <div style="width: 100%">
                             <el-form-item :prop="'quotationProductList.' + scope.$index + '.quotationProductBomList.' + $index + '.remark'"
                                           :rules="rules.remark" :inline-message="true" class="margin-b-0 wid100">
-                              <el-input-number onmousewheel="return false;" v-model="row.remark" placeholder="请输入" style="width: 100%" :precision="0"
-                                               :controls="false" :min="0" />
+                              <el-input v-model="row.remark" placeholder="请输入" style="width: 100%" :min="0" />
                             </el-form-item>
                           </div>
                         </template>
@@ -282,7 +282,7 @@
       </template>
     </el-dialog>
 
-    <el-dialog v-if="foreignDialog" v-model="foreignDialog" title="转对外报价单" width="80%" append-to-body>
+    <el-dialog v-if="foreignDialog" v-model="foreignDialog" title="转对外报价单" width="90%" append-to-body>
       <byForm :formConfig="formConfigOne" :formOption="formOptionOne" v-model="formData.data" :rules="rulesOne" ref="formDomOne"
               v-loading="submitLoading">
         <template #commodity>
@@ -593,7 +593,7 @@ const config = computed(() => {
         label: "操作",
         width: 200,
         slot: "btn",
-        align: "center",
+        align: "right",
         fixed: "right",
       },
     },
@@ -711,7 +711,7 @@ const getDtl = (row, flag, change = false) => {
     changeQuantity();
 
     //折线图
-    if (flag && res.quotationTrendList && res.quotationTrendList.length > 0) {
+    if (flag && res.quotationTrendList && res.quotationTrendList.length >= 2) {
       nextTick(() => {
         myChart = echarts.init(chartDom.value);
         window.addEventListener("resize", () => {
@@ -734,6 +734,8 @@ const getDtl = (row, flag, change = false) => {
         myChart.setOption(chartOption.data);
         myChart.resize();
       });
+    } else {
+      isShowChart.value = false;
     }
   });
 };
@@ -1496,7 +1498,12 @@ const handleSubmitOne = () => {
   cursor: pointer;
   vertical-align: middle;
 }
-::deep(.bom-table .el-table tr) {
+
+:deep(.bom-table .el-table__body-wrapper .el-table__body .el-table__row) {
   background: #fbfbfb !important;
 }
+:deep(.bom-table .el-table-fixed-column--right) {
+  // background: #fbfbfb !important;
+}
 </style>
+

+ 6 - 7
src/views/EHSD/saleContract/priceSheetEstimate/index.vue

@@ -54,7 +54,7 @@
 
     </byTable>
 
-    <el-dialog v-if="openAddDialog" v-model="openAddDialog" title="报价评估" width="80%" append-to-body>
+    <el-dialog v-if="openAddDialog" v-model="openAddDialog" title="报价评估" width="90%" append-to-body>
       <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom">
         <template #commodity>
           <div style="width: 100%;padding-left:25px">
@@ -110,11 +110,6 @@
                       </el-table-column>
                       <el-table-column label="备注" width="180" prop="remark">
                       </el-table-column>
-                      <el-table-column label="操作" width="60" align="center" fixed="right" v-if="!isDetail">
-                        <template #default="{ $index }">
-                          <el-button type="primary" link @click="handleDeleteMaterial(scope.$index,$index)">删除</el-button>
-                        </template>
-                      </el-table-column>
                     </el-table>
                   </div>
                 </template>
@@ -175,6 +170,7 @@ const sourceList = ref({
     quotationTimeEnd: "",
     beginTime: "",
     endTime: "",
+    isEstimate: "1",
   },
 });
 const loading = ref(false);
@@ -290,7 +286,7 @@ const config = computed(() => {
       },
       renderHTML(row) {
         return [
-          row.quotationStatus < 2
+          row.quotationStatus < 2 && row.status == 30
             ? {
                 attrs: {
                   label: "报价",
@@ -424,6 +420,9 @@ const changeQuantity = () => {
       if (iele.quantity) {
         for (let j = 0; j < iele.quotationProductBomList.length; j++) {
           const jele = iele.quotationProductBomList[j];
+          if (!jele.price) {
+            jele.price = jele.costPrice;
+          }
           jele.allQuantity = iele.quantity * jele.quantity;
         }
       }

+ 250 - 3
src/views/EHSD/saleContract/priceSheetForeign/index.vue

@@ -26,7 +26,10 @@
 
       <template #follow="{ item }">
         <div style="width: 100%">
-          <div style="width: 100%; display: flex">
+          <div style="width: 100%; display: flex;align-items:center">
+            <el-icon :size="20" style="cursor:pointer;margin-right: 8px;" @click="handleFollow(item)">
+              <Edit />
+            </el-icon>
             <template v-if="
                 item.extQuotationFollowList &&
                 item.extQuotationFollowList.length > 0
@@ -90,8 +93,9 @@
 
       <template #btn="{item}">
         <div style="width: 100%">
-          <el-button type="primary" text v-debounce @click="handleFollow(item)">跟进</el-button>
+          <!-- <el-button type="primary" text v-debounce @click="handleFollow(item)">跟进</el-button> -->
           <el-button type="primary" text v-debounce @click="handleGenerate(item)">生成订单</el-button>
+          <el-button type="primary" text v-debounce @click="getDtl(item)">变更</el-button>
           <el-button type="danger" text v-debounce v-if="item.status !=0" @click="handleRepeal(item)">作废</el-button>
         </div>
       </template>
@@ -123,6 +127,90 @@
         <el-button @click="openRecordMore = false" size="default" v-debounce>关 闭</el-button>
       </template>
     </el-dialog>
+
+    <el-dialog v-if="openAddDialog" v-model="openAddDialog" title="报价变更" width="90%" append-to-body>
+      <byForm :formConfig="updateFormConfig" :formOption="updateFormOption" v-model="formData.updateData" :rules="updateRules" ref="formDomOne">
+        <template #commodity>
+          <div style="width: 100%;padding-left:25px">
+            <el-table :data="formData.updateData.quotationProductList" style="width: 100%;" default-expand-all row-key="productId">
+              <el-table-column type="expand" width="50" align="center">
+                <template #default="scope">
+                  <div style="padding-left:50px">
+                    <div style="margin-bottom:10px;margin-left:-20px">
+                      <TitleInfo content='BOM单:'></TitleInfo>
+                    </div>
+                    <el-table :data="scope.row.quotationProductBomList" style="width: 100%;" border class="bom-table">
+                      <el-table-column label="图片" width="80">
+                        <template #default="{ row }">
+                          <div v-if="row.fileUrl">
+                            <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
+                          </div>
+                          <div v-else></div>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="productCode" label="物料编码" width="190" />
+                      <el-table-column prop="productName" label="物料名称" min-width="200" />
+                      <el-table-column label="尺寸 cm*cm*cm" width="150">
+                        <template #default="{ row, $index }">
+                          <div style="width: 100%">
+                            {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
+                          </div>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="quantity" label="数量" width="80">
+                      </el-table-column>
+                      <el-table-column prop="allQuantity" label="总量" width="80" />
+                      <el-table-column label="单价" width="110">
+                        <template #default="{ row, $index }">
+                          <div style="width: 100%">
+                            <el-form-item :prop="'quotationProductList.' + scope.$index + '.quotationProductBomList.' + $index + '.price'"
+                                          :rules="rules.price" :inline-message="true" class="margin-b-0 wid100">
+                              <el-input-number onmousewheel="return false;" v-model="row.price" placeholder="请输入" style="width: 100%" :precision="2"
+                                               :controls="false" :min="0" @change="totalAmount()" />
+                            </el-form-item>
+                          </div>
+                        </template>
+                      </el-table-column>
+                      <el-table-column prop="amount" label="小计" width="110">
+                      </el-table-column>
+                      <el-table-column label="备注" width="180" prop="remark">
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="图片" width="80">
+                <template #default="{ row }">
+                  <div v-if="row.fileUrl">
+                    <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
+                  </div>
+                  <div v-else></div>
+                </template>
+              </el-table-column>
+              <el-table-column prop="productCode" label="商品编码" width="190" />
+              <el-table-column prop="productName" label="商品名称" min-width="200" />
+              <el-table-column label="尺寸 cm*cm*cm" width="150">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="数量" width="120" prop="quantity">
+              </el-table-column>
+              <el-table-column label="单价" width="120" prop="price">
+              </el-table-column>
+              <el-table-column prop="amount" label="小计" width="120">
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <template #footer v-if="!isDetail">
+        <el-button @click="openAddDialog = false" size="default" v-debounce>关 闭</el-button>
+        <el-button type="primary" @click="handleSubmitOne()" size="default" v-debounce>提 交</el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -274,7 +362,7 @@ const config = computed(() => {
       attrs: {
         label: "跟进",
         slot: "follow",
-        "min-width": 360,
+        "min-width": 400,
       },
     },
     {
@@ -337,6 +425,7 @@ const followDialog = ref(false);
 const submitLoading = ref(false);
 const formData = reactive({
   data: {},
+  updateData: {},
 });
 const formOption = reactive({
   inline: true,
@@ -454,6 +543,164 @@ const handleRepeal = (row) => {
     })
     .catch((err) => {});
 };
+
+const formDomOne = ref(null);
+const updateFormOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  disabled: false,
+});
+const updateFormConfig = computed(() => {
+  return [
+    {
+      type: "title1",
+      title: "商品信息",
+      haveLine: true,
+    },
+    {
+      type: "slot",
+      slotName: "commodity",
+      label: "",
+    },
+    {
+      type: "title1",
+      title: "报价总金额",
+      haveLine: true,
+    },
+    {
+      type: "input",
+      prop: "amount",
+      label: "报价总金额",
+      itemWidth: 25,
+      disabled: true,
+    },
+  ];
+});
+const updateRules = ref({
+  price: [{ required: true, message: "请输入单价", trigger: "blur" }],
+});
+const isDetail = ref(false);
+const openAddDialog = ref(false);
+const getDtl = (row, flag = false) => {
+  formOption.disabled = flag;
+  isDetail.value = flag;
+  openAddDialog.value = true;
+  proxy.post("/extQuotation/detail", { id: row.id }).then((res) => {
+    formData.updateData = res;
+    // 价格计算
+    changeQuantity();
+    // 文件数据回显
+    let ids = [];
+    formData.updateData.quotationProductList.map((x) => {
+      ids.push(x.productId);
+      x.quotationProductBomList.map((y) => {
+        ids.push(y.materialId);
+      });
+    });
+    ids = Array.from(new Set(ids));
+    proxy
+      .post("/fileInfo/getList", {
+        businessIdList: ids,
+      })
+      .then((fileObj) => {
+        formData.updateData.quotationProductList.map((x) => {
+          x.fileList = fileObj[x.productId] || [];
+          if (x.fileList && x.fileList.length > 0) {
+            x.fileUrl = x.fileList[0].fileUrl;
+          }
+          x.quotationProductBomList.map((y) => {
+            y.fileList = fileObj[y.materialId] || [];
+            if (y.fileList && y.fileList.length > 0) {
+              y.fileUrl = y.fileList[0].fileUrl;
+            }
+          });
+        });
+      });
+  });
+};
+
+const changeQuantity = () => {
+  if (
+    formData.updateData.quotationProductList &&
+    formData.updateData.quotationProductList.length > 0
+  ) {
+    for (let i = 0; i < formData.updateData.quotationProductList.length; i++) {
+      let iele = formData.updateData.quotationProductList[i];
+      if (iele.quantity) {
+        for (let j = 0; j < iele.quotationProductBomList.length; j++) {
+          const jele = iele.quotationProductBomList[j];
+          if (!jele.price) {
+            jele.price = jele.costPrice;
+          }
+          jele.allQuantity = iele.quantity * jele.quantity;
+        }
+      }
+    }
+    totalAmount();
+  }
+};
+
+const totalAmount = () => {
+  let money = 0;
+  if (
+    formData.updateData.quotationProductList &&
+    formData.updateData.quotationProductList.length > 0
+  ) {
+    // 先算单个产品的价格
+    for (let i = 0; i < formData.updateData.quotationProductList.length; i++) {
+      let iele = formData.updateData.quotationProductList[i];
+      let productPrice = 0;
+      for (let j = 0; j < iele.quotationProductBomList.length; j++) {
+        const jele = iele.quotationProductBomList[j];
+        productPrice += Number(
+          parseFloat(Number(jele.quantity) * Number(jele.price)).toFixed(2)
+        );
+      }
+      iele.price = parseFloat(productPrice).toFixed(2);
+    }
+
+    for (let i = 0; i < formData.updateData.quotationProductList.length; i++) {
+      let iele = formData.updateData.quotationProductList[i];
+      iele.amount = parseFloat(
+        Number(iele.quantity) * Number(iele.price)
+      ).toFixed(2);
+      money += Number(iele.amount);
+      for (let j = 0; j < iele.quotationProductBomList.length; j++) {
+        const jele = iele.quotationProductBomList[j];
+        jele.amount = parseFloat(
+          Number(jele.allQuantity) * Number(jele.price)
+        ).toFixed(2);
+      }
+    }
+  }
+
+  formData.updateData.amount = parseFloat(money).toFixed(2);
+};
+
+const handleSubmitOne = (type) => {
+  formDomOne.value.handleSubmit(() => {
+    if (
+      formData.updateData.quotationProductList &&
+      formData.updateData.quotationProductList.length > 0
+    ) {
+      submitLoading.value = true;
+      proxy.post("/extQuotation/change", formData.updateData).then(
+        (res) => {
+          proxy.msgTip("操作成功", 1);
+          openAddDialog.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          submitLoading.value = false;
+        }
+      );
+    } else {
+      return proxy.msgTip("请添加至少一件商品", 2);
+    }
+  });
+};
 </script>
 
 <style lang="scss" scoped>

+ 2 - 2
src/views/login.vue

@@ -219,8 +219,8 @@ getCookie();
       }
       .left-logo {
         position: absolute;
-        top: 10px;
-        left: 20px;
+        top: 30px;
+        left: 40px;
         img {
           width: 100px;
           object-fit: contain;

+ 82 - 46
src/views/publicModule/contractTemplate/index.vue

@@ -36,32 +36,51 @@ import Editor from "@/components/Editor/index.vue";
 
 const { proxy } = getCurrentInstance();
 const loading = ref(false);
-const companyList = ref({});
+const companyList = ref([]);
+const typeData = ref([
+  {
+    dictKey: "1",
+    dictValue: "销售合同",
+  },
+  {
+    dictKey: "2",
+    dictValue: "采购合同",
+  },
+]);
+
 const sourceList = ref({
   data: [],
   pagination: {
     total: 0,
     pageNum: 1,
     pageSize: 10,
-    corporationId: "",
+    templateType: "",
     keyword: "",
   },
 });
 const selectConfig = computed(() => {
   return [
     {
-      label: "公司名称",
-      prop: "corporationId",
-      data: companyList.value,
+      label: "模板类型",
+      prop: "templateType",
+      data: typeData.value,
     },
+    // {
+    //   label: "公司名称",
+    //   prop: "corporationId",
+    //   data: companyList.value,
+    // },
   ];
 });
 const config = computed(() => {
   return [
     {
       attrs: {
-        label: "公司名称",
-        prop: "corporationName",
+        label: "模板类型",
+        prop: "templateType",
+      },
+      render(val) {
+        return proxy.dictKeyValue(val, typeData.value);
       },
     },
     {
@@ -70,18 +89,18 @@ const config = computed(() => {
         prop: "templateName",
       },
     },
-    {
-      attrs: {
-        label: "联系人",
-        prop: "contactName",
-      },
-    },
-    {
-      attrs: {
-        label: "联系电话",
-        prop: "contactNumber",
-      },
-    },
+    // {
+    //   attrs: {
+    //     label: "联系人",
+    //     prop: "contactName",
+    //   },
+    // },
+    // {
+    //   attrs: {
+    //     label: "联系电话",
+    //     prop: "contactNumber",
+    //   },
+    // },
     {
       attrs: {
         label: "操作",
@@ -160,7 +179,7 @@ const getList = async (req) => {
       }, 200);
     });
 };
-getDict();
+// getDict();
 getList();
 const modalType = ref("add");
 const dialogVisible = ref(false);
@@ -180,44 +199,53 @@ const formOption = reactive({
 const formConfig = computed(() => {
   return [
     {
-      label: "基础信息",
-    },
-    {
-      type: "input",
-      prop: "templateName",
-      label: "模板名称",
-      itemType: "text",
-      placeholder: "请输入模板名称",
+      type: "title1",
+      title: "基础信息",
     },
     {
       type: "select",
-      label: "公司名称",
-      prop: "corporationId",
-      data: companyList.value,
-    },
-    {
-      label: "联系信息",
+      label: "模板类型",
+      prop: "templateType",
+      data: typeData.value,
     },
     {
       type: "input",
-      prop: "contactName",
-      label: "业务联系人",
+      prop: "templateName",
+      label: "模板名称",
       itemType: "text",
-      placeholder: "请输入联系人",
-      itemWidth: 30,
+      placeholder: "请输入模板名称",
     },
+    // {
+    //   type: "select",
+    //   label: "公司名称",
+    //   prop: "corporationId",
+    //   data: companyList.value,
+    // },
     {
-      type: "input",
-      prop: "contactNumber",
-      label: "  ",
-      itemType: "text",
-      placeholder: "请输入联系电话",
-      itemWidth: 70,
+      type: "title1",
+      title: "模板内容",
     },
+    // {
+    //   type: "input",
+    //   prop: "contactName",
+    //   label: "业务联系人",
+    //   itemType: "text",
+    //   placeholder: "请输入联系人",
+    //   itemWidth: 50,
+    // },
+    // {
+    //   type: "input",
+    //   prop: "contactNumber",
+    //   label: "",
+    //   itemType: "text",
+    //   placeholder: "请输入联系电话",
+    //   itemWidth: 50,
+    // },
     {
       type: "slot",
+      prop: "templateContent",
       slotName: "templateContent",
-      label: "合同模板",
+      label: "模板内容",
     },
   ];
 });
@@ -225,7 +253,12 @@ let rules = ref({
   templateName: [
     { required: true, message: "请输入模板名称", trigger: "blur" },
   ],
-  corporationId: [{ required: true, message: "请选择公司", trigger: "change" }],
+  templateType: [
+    { required: true, message: "请选择模板类型", trigger: "change" },
+  ],
+  templateContent: [
+    { required: true, message: "请输入模板内容", trigger: "blur" },
+  ],
 });
 const openModal = () => {
   modalType.value = "add";
@@ -272,4 +305,7 @@ const updateContent = (val) => {
 .tenant {
   padding: 20px;
 }
+.ql-editor {
+  padding: 0px;
+}
 </style>