浏览代码

合同详情页面增加新需求

cz 1 年之前
父节点
当前提交
673e460428

+ 15 - 4
src/api/system/user.js

@@ -1,5 +1,7 @@
 import request from '@/utils/request'
-import { parseStrEmpty } from "@/utils/ruoyi";
+import {
+  parseStrEmpty
+} from "@/utils/ruoyi";
 
 // 查询用户列表
 export function listUser(query) {
@@ -28,14 +30,23 @@ export function addUser(data) {
 }
 
 // 修改用户
+// export function updateUser(data) {
+//   return request({
+//     url: '/system/user',
+//     method: 'put',
+//     data: data
+//   })
+// }
+
 export function updateUser(data) {
   return request({
-    url: '/system/user',
-    method: 'put',
+    url: '/tenantUser/editUserCode',
+    method: 'post',
     data: data
   })
 }
 
+
 // 删除用户
 export function delUser(userId) {
   return request({
@@ -132,4 +143,4 @@ export function deptTreeSelect() {
     url: '/system/user/deptTree',
     method: 'get'
   })
-}
+}

+ 59 - 10
src/components/contractCom/contractDetails.vue

@@ -10,8 +10,26 @@
       <el-tab-pane label="销售合同" name="first"></el-tab-pane>
       <el-tab-pane label="采购合同" name="second"></el-tab-pane>
       <el-tab-pane label="交易明细" name="third"></el-tab-pane>
+      <el-tab-pane label="外销跟单" name="four"> </el-tab-pane>
+      <el-tab-pane
+        label="预算表"
+        name="five"
+        v-if="isShowSalesFinancemanArrange"
+      >
+      </el-tab-pane>
+      <el-tab-pane
+        label="结算表"
+        name="six"
+        v-if="isShowSalesFinancemanArrange"
+      >
+      </el-tab-pane>
+      <el-tab-pane
+        label="单证"
+        name="seven"
+        v-if="isShowSalesFinancemanArrange"
+      ></el-tab-pane>
     </el-tabs>
-    <div class="content-box" v-if="activeName !== 'third'">
+    <div class="content-box" v-if="['first', 'second'].includes(activeName)">
       <div class="left">
         <div
           v-for="i in leftList"
@@ -72,6 +90,18 @@
         </template>
       </byTable>
     </div>
+    <div v-if="activeName === 'four'">
+      <ExportTracking> </ExportTracking>
+    </div>
+    <div v-if="activeName === 'five'">
+      <ProfitBudgetEHSD> </ProfitBudgetEHSD>
+    </div>
+    <div v-if="activeName === 'six'">
+      <ProfitSettlementEHSD> </ProfitSettlementEHSD>
+    </div>
+    <div v-if="activeName === 'seven'">
+      <Document> </Document>
+    </div>
 
     <el-dialog title="PDF查看" v-if="pdfDialog" v-model="pdfDialog" width="920">
       <!-- <ContractPDFOne :rowData="rowData"></ContractPDFOne> -->
@@ -89,8 +119,13 @@ import PurchasePDFOneNew from "@/components/PDF/purchasePDFOneNew.vue";
 import ContractPDFOne from "@/components/PDF/contractPDFOne.vue";
 import ContractPDFOneNew from "@/components/PDF/contractPDFOneNew.vue";
 import ApprovalDetails from "@/views/process/processApproval/index.vue";
-
+import ExportTracking from "@/components/detailCom/exportTracking/index.vue";
+import ProfitBudgetEHSD from "@/components/detailCom/profitBudgetEHSD/index.vue";
+import ProfitSettlementEHSD from "@/components/detailCom/profitSettlementEHSD/index.vue";
+import Document from "@/components/detailCom/document/index.vue";
 import byTable from "@/components/byTable/index";
+import useUserStore from "@/store/modules/user";
+const userInfo = useUserStore();
 const { proxy } = getCurrentInstance();
 import { useRoute } from "vue-router";
 const route = useRoute();
@@ -234,14 +269,16 @@ const pushProcessApproval = (row) => {
 // };
 
 const handleChange = (val) => {
-  if (val === "first") {
-    leftList.value = contractDataList.value;
-  }
-  if (val === "second") {
-    leftList.value = purchaseDataList.value;
-  }
-  if (leftList.value && leftList.value.length > 0) {
-    handleItemClick(leftList.value[0]);
+  if (["first", "second"].includes(val)) {
+    if (val === "first") {
+      leftList.value = contractDataList.value;
+    }
+    if (val === "second") {
+      leftList.value = purchaseDataList.value;
+    }
+    if (leftList.value && leftList.value.length > 0) {
+      handleItemClick(leftList.value[0]);
+    }
   }
 };
 const getDetailsData = (id) => {
@@ -272,6 +309,18 @@ if (props.contractId) {
 if (route.query.currentContractId) {
   getDetailsData(route.query.currentContractId);
 }
+const isShowSalesFinancemanArrange = ref(false);
+const checkShow = () => {
+  // 当前账号角色如果是业务总监、总经理、业务员、财务,则可查看
+  if (
+    userInfo.roles.includes("salesDirector") ||
+    userInfo.roles.includes("ceo") ||
+    userInfo.roles.includes("financeOfficer")
+  ) {
+    isShowSalesFinancemanArrange.value = true;
+  }
+};
+checkShow();
 </script>
 
 <style lang="scss" scoped>

+ 2720 - 0
src/components/detailCom/document/index.vue

@@ -0,0 +1,2720 @@
+<template>
+  <div class="tenant">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :action-list="[]"
+        @get-list="getList"
+        :hidePagination="true"
+        :hideSearch="true"
+      >
+        <template #acceptCode="{ item }">
+          <div>
+            <div style="color: #409eff" v-if="item.acceptCode">
+              {{ item.acceptCarriage }} ({{ item.acceptCode }})
+            </div>
+            <div v-else>
+              <el-button
+                type="warning"
+                style="background-color: var(--el-button-bg-color) !important"
+                @click="clickAddAcceptCode(item)"
+                >填写</el-button
+              >
+            </div>
+          </div>
+        </template>
+        <template #toView="{ item }">
+          <div>
+            <el-button
+              type="warning"
+              style="background-color: var(--el-button-bg-color) !important"
+              @click="clickToView(item)"
+              >查看</el-button
+            >
+          </div>
+        </template>
+      </byTable>
+    </div>
+
+    <el-dialog
+      title="创建单证"
+      v-if="dialogVisible"
+      v-model="dialogVisible"
+      width="1000"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="submit"
+        v-loading="loadingDialog"
+      >
+        <template #details>
+          <div style="width: 100%">
+            <el-table
+              :data="formData.data.documentsProductList"
+              style="width: 100%; margin-top: 16px"
+            >
+              <el-table-column label="货物描述" min-width="240">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item
+                      :prop="'documentsProductList.' + $index + '.describes'"
+                      :rules="rules.describes"
+                      :inline-message="true"
+                    >
+                      <el-input
+                        v-model="row.describes"
+                        placeholder="请输入货物描述"
+                      />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="副描述" min-width="200">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item
+                      :prop="'documentsProductList.' + $index + '.subDescribe'"
+                      :rules="rules.subDescribe"
+                      :inline-message="true"
+                    >
+                      <el-input
+                        v-model="row.subDescribe"
+                        placeholder="请输入副描述"
+                      />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="海关编码" width="160">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item
+                      :prop="'documentsProductList.' + $index + '.customsCode'"
+                      :rules="rules.customsCode"
+                      :inline-message="true"
+                    >
+                      <el-input
+                        v-model="row.customsCode"
+                        placeholder="请输入海关编码"
+                      />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="数量" width="160">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item
+                      :prop="'documentsProductList.' + $index + '.quantity'"
+                      :rules="rules.quantity"
+                      :inline-message="true"
+                    >
+                      <el-input-number
+                        v-model="row.quantity"
+                        placeholder="请输入数量"
+                        style="width: 100%"
+                        :precision="0"
+                        :controls="false"
+                        :min="0"
+                      />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="单价" width="160">
+                <template #default="{ row, $index }">
+                  <div style="width: 100%">
+                    <el-form-item
+                      :prop="'documentsProductList.' + $index + '.price'"
+                      :rules="rules.price"
+                      :inline-message="true"
+                    >
+                      <el-input-number
+                        v-model="row.price"
+                        placeholder="请输入单价"
+                        style="width: 100%"
+                        :precision="2"
+                        :controls="false"
+                        :min="0"
+                      />
+                    </el-form-item>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      title="货运详情"
+      v-if="openAddAcceptCode"
+      v-model="openAddAcceptCode"
+      width="600"
+    >
+      <byForm
+        :formConfig="formConfigTwo"
+        :formOption="formOption"
+        v-model="formDataTwo.data"
+        :rules="rulesTwo"
+        ref="submitTwo"
+        v-loading="loadingTwo"
+      >
+        <template #departureTime>
+          <div>
+            <el-date-picker
+              v-model="formDataTwo.data.departureTime"
+              type="datetime"
+              placeholder="请选择起运时间"
+              value-format="YYYY-MM-DD HH:mm:ss"
+            />
+          </div>
+        </template>
+        <template #file>
+          <div style="width: 100%">
+            <el-upload
+              v-model:fileList="fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-preview="onPreviewFile"
+            >
+              <el-button>选择</el-button>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openAddAcceptCode = false" size="large"
+          >取 消</el-button
+        >
+        <el-button type="primary" @click="submitTwoForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      title="打印"
+      v-if="openSelectPrint"
+      v-model="openSelectPrint"
+      width="600"
+    >
+      <div>
+        <el-button @click="clickPrint(1)" type="primary">装箱单</el-button>
+        <el-button @click="clickPrint(2)" type="primary">商业发票</el-button>
+        <el-button @click="clickPrint(3)" type="primary">销售确认书</el-button>
+        <el-button @click="clickPrint(4)" type="primary">报关单</el-button>
+      </div>
+      <template #footer>
+        <el-button @click="openSelectPrint = false" size="large"
+          >关闭</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="860">
+      <div
+        id="pdfDom"
+        style="width: 800px; padding: 16px; font-size: 12px !important"
+      >
+        <div v-if="openStatus === 1">
+          <div class="public-title">装箱单</div>
+          <div class="title-decoration">PACKING LIST</div>
+        </div>
+        <div v-else-if="openStatus === 2">
+          <div class="public-title">商业发票</div>
+          <div class="title-decoration">COMMERCIAL INVOICE</div>
+        </div>
+        <div v-else-if="openStatus === 3">
+          <div class="public-title">合同</div>
+          <div class="title-decoration">CONTRACT</div>
+        </div>
+        <div style="padding-top: 8px" v-if="[1, 2].includes(openStatus)">
+          <div>C.I. NO. : {{ printDetails.contract.code }}</div>
+          <div>C.I. DATE: {{ printDetails.date }}</div>
+        </div>
+        <div style="padding-top: 8px" v-else-if="[3].includes(openStatus)">
+          <div>P.I. NO. : {{ printDetails.contract.code }}</div>
+          <div>P.I. DATE: {{ printDetails.date }}</div>
+        </div>
+        <!-- 装箱和商业发票-->
+        <div
+          style="border: 1px solid black; display: flex"
+          v-if="[1, 2].includes(openStatus)"
+        >
+          <div
+            style="width: 50%; border-right: 1px solid black; padding-left: 4px"
+          >
+            <div class="public-color">卖方 VENDOR:</div>
+            <div>{{ printDetails.corporation.name }}</div>
+            <div>{{ printDetails.corporation.nameEn }}</div>
+            <div style="padding: 16px 0">
+              {{ printDetails.contract.sellAddress }},{{
+                printDetails.contract.sellCityName
+              }},{{ printDetails.contract.sellProvinceName }},{{
+                printDetails.contract.sellCountryName
+              }}
+            </div>
+            <div>CONTRACT: {{ printDetails.contract.sellContactName }}</div>
+            <div>TEL.: {{ printDetails.contract.sellContactNumber }}</div>
+          </div>
+          <div style="width: 50%; padding-left: 4px">
+            <div class="public-color">买方 SOLD TO MESSRS:</div>
+            <div>{{ printDetails.customer.name }}</div>
+            <div style="padding: 16px 0">
+              {{ printDetails.contract.buyAddress }},{{
+                printDetails.contract.buyPostalCode
+              }},{{ printDetails.contract.buyCityName }},{{
+                printDetails.contract.buyProvinceName
+              }},{{ printDetails.contract.buyCountryName }}
+            </div>
+            <div>CONTRACT: {{ printDetails.contract.buyContactName }}</div>
+            <div>TEL.: {{ printDetails.contract.buyContactNumber }}</div>
+          </div>
+        </div>
+        <!-- 合同 -->
+        <div
+          style="border: 1px solid black; display: flex"
+          v-else-if="[3].includes(openStatus)"
+        >
+          <div
+            style="width: 50%; border-right: 1px solid black; padding-left: 4px"
+          >
+            <div class="public-color">卖方 VENDOR:</div>
+            <div>{{ printDetails.corporation.name }}</div>
+            <div>{{ printDetails.corporation.nameEn }}</div>
+            <div style="padding: 16px 0">
+              {{ printDetails.contract.sellAddress }},{{
+                printDetails.contract.sellCityName
+              }},{{ printDetails.contract.sellProvinceName }},{{
+                printDetails.contract.sellCountryName
+              }}
+            </div>
+            <div>CONTRACT: {{ printDetails.contract.sellContactName }}</div>
+            <div>TEL.: {{ printDetails.contract.sellContactNumber }}</div>
+          </div>
+          <div style="width: 50%; padding-left: 4px">
+            <div class="public-color">买方 BUYER:</div>
+            <div>{{ printDetails.customer.name }}</div>
+            <div style="padding: 16px 0">
+              {{ printDetails.contract.buyAddress }},{{
+                printDetails.contract.buyPostalCode
+              }},{{ printDetails.contract.buyCityName }},{{
+                printDetails.contract.buyProvinceName
+              }},{{ printDetails.contract.buyCountryName }}
+            </div>
+            <div>CONTRACT: {{ printDetails.contract.buyContactName }}</div>
+            <div>TEL.: {{ printDetails.contract.buyContactNumber }}</div>
+          </div>
+        </div>
+        <div style="height: 16px"></div>
+        <!-- 装箱和商业发票其他信息 -->
+        <div style="border: 1px solid black" v-if="[1, 2].includes(openStatus)">
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                原产国 COUNTRY OF ORIGIN:
+              </div>
+              <div>{{ printDetails.contract.sellCountryName }}</div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                目的国 COUNTRY OF DESTINATION:
+              </div>
+              <div>{{ printDetails.documents.countryName }}</div>
+            </div>
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                贸易方式 TERMS OF DELIVERY:
+              </div>
+              <div>
+                {{
+                  dictValueLabel(
+                    printDetails.contract.tradeMethods,
+                    tradeMethods
+                  )
+                }}
+              </div>
+            </div>
+          </div>
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                付款方式 TERMS OF PAYMENT:
+              </div>
+              <div>
+                {{ printDetails.contract.remark }}
+              </div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                交货期 DELIVERY TIME:
+              </div>
+              <div>{{ printDetails.contract.deliveryTime }}</div>
+            </div>
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                运输方式 EXPORT BY/VIA:
+              </div>
+              <div>
+                {{
+                  dictValueLabel(
+                    printDetails.contract.transportMethod,
+                    shippingMethod
+                  )
+                }}
+              </div>
+            </div>
+          </div>
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                装卸港 PLACE OF DISCHARGE:
+              </div>
+              <div>{{ printDetails.contract.transportRemark }}</div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+              v-if="[3].includes(openStatus)"
+            >
+              <div class="public-color public-padding-bottom">
+                目的港 FINAL DESTINATION:
+              </div>
+              <div>{{ printDetails.documents.portOfDestination }}</div>
+            </div>
+            <div
+              style="width: 33%; padding-left: 4px"
+              v-if="[3].includes(openStatus)"
+            >
+              <div class="public-color public-padding-bottom">
+                质保期 WARRANTY:
+              </div>
+              <div>
+                <span v-if="printDetails.contract.warranty"
+                  >{{ printDetails.contract.warranty }}天</span
+                >
+              </div>
+            </div>
+          </div>
+        </div>
+        <!-- 合同其他信息 -->
+        <div
+          style="border: 1px solid black"
+          v-else-if="[3].includes(openStatus)"
+        >
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                COUNTRY OF ORIGIN:
+              </div>
+              <div>{{ printDetails.contract.sellCountryName }}</div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                COUNTRY OF DESTINATION:
+              </div>
+              <div>{{ printDetails.documents.countryName }}</div>
+            </div>
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                PLACE OF DISCHARGE:
+              </div>
+              <div>{{ printDetails.contract.transportRemark }}</div>
+            </div>
+          </div>
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                TERMS OF DELIVERY:
+              </div>
+              <div>
+                {{
+                  dictValueLabel(
+                    printDetails.contract.tradeMethods,
+                    tradeMethods
+                  )
+                }}
+              </div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-bottom: 1px solid black;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">CURRENCY:</div>
+              <div>
+                {{ printDetails.contract.currency }}
+              </div>
+            </div>
+            <div
+              style="
+                width: 33%;
+                border-bottom: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                EXPORT BY/VIA:
+              </div>
+              <div>
+                {{
+                  dictValueLabel(
+                    printDetails.contract.transportMethod,
+                    shippingMethod
+                  )
+                }}
+              </div>
+            </div>
+          </div>
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color public-padding-bottom">
+                DELIVERY TIME:
+              </div>
+              <div>{{ printDetails.contract.deliveryTime }}</div>
+            </div>
+            <div style="width: 67%; padding-left: 4px">
+              <div class="public-color public-padding-bottom">
+                付款方式 TERMS OF PAYMENT:
+              </div>
+              <div>
+                {{ printDetails.contract.remark }}
+              </div>
+            </div>
+          </div>
+        </div>
+        <div style="height: 16px"></div>
+        <!--装箱和商业发票唛头信息  -->
+        <div style="border: 1px solid black" v-if="[1, 2].includes(openStatus)">
+          <div style="display: flex; width: 100%">
+            <div
+              style="
+                width: 33%;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color">唛头及箱号 MARK & NUMBERS</div>
+              <div
+                style="padding: 8px 0"
+                v-html="printDetails.documents.remark"
+              ></div>
+            </div>
+            <div
+              style="
+                width: 34%;
+                border-right: 1px solid black;
+                padding-left: 4px;
+              "
+            >
+              <div class="public-color">包装规格 PACKING & DESCRIPTION</div>
+              <div
+                v-if="
+                  printDetails.packDetailList &&
+                  printDetails.packDetailList.length > 0
+                "
+              >
+                <div
+                  style="padding: 8px 0"
+                  v-for="(item, index) in printDetails.packDetailList"
+                  :key="index"
+                >
+                  <span style="padding-right: 16px">{{ index + 1 }}</span>
+                  <span v-if="item.boxLong">{{ item.boxLong }}cm</span>
+                  <span>*</span>
+                  <span v-if="item.boxWide">{{ item.boxWide }}cm</span>
+                  <span>*</span>
+                  <span v-if="item.boxHigh">{{ item.boxHigh }}cm</span>
+                  <span>*</span>
+                  <span>{{ item.packQuantity }}TNS</span>
+                </div>
+              </div>
+            </div>
+            <div style="width: 33%; padding-left: 4px">
+              <div class="public-color">总毛重 TOTAL GROSS WEIGHT/KG</div>
+              <div>{{ printDetails.sumRoughWeight }}</div>
+              <div class="public-color">总净重 TOTAL NET WEIGHT/KG</div>
+              <div>{{ printDetails.sumNetWeight }}</div>
+              <div class="public-color">总体积 TOTAL DIMENSION/M3</div>
+              <div>{{ printDetails.sumBomVolume }}</div>
+            </div>
+          </div>
+        </div>
+        <div style="height: 16px"></div>
+        <!-- 产品部分 -->
+        <table
+          class="three"
+          cellspacing="0"
+          cellpadding="0"
+          border="0"
+          style="width: 100%; border-bottom: 0"
+        >
+          <tr>
+            <td style="width: 100px; text-align: center" class="public-color">
+              项目
+              <br />
+              ITEM NO.
+            </td>
+            <td class="public-color" style="text-align: center">
+              货物描述
+              <br />
+              DESCRIPTION OF GOODS
+            </td>
+            <template v-if="[3].includes(openStatus)">
+              <td style="width: 100px; text-align: center" class="public-color">
+                单位
+                <br />
+                UNIT
+              </td>
+            </template>
+            <td style="width: 100px; text-align: center" class="public-color">
+              数量
+              <br />
+              QUANTITY
+              <br />
+              (SET/PCS)
+            </td>
+            <template v-if="[1].includes(openStatus)">
+              <td style="width: 100px; text-align: center" class="public-color">
+                净重
+                <br />
+                N.W./ KG
+              </td>
+              <td style="width: 100px; text-align: center" class="public-color">
+                毛重
+                <br />
+                G.W./ KG
+              </td>
+              <td style="width: 100px; text-align: center" class="public-color">
+                总尺寸
+                <br />
+                DIMENSIONS(CM)
+              </td>
+              <td
+                style="width: 100px; border-right: 0; text-align: center"
+                class="public-color"
+              >
+                总体积
+                <br />
+                MEAS.(CBM)
+              </td>
+            </template>
+            <template v-if="[2, 3].includes(openStatus)">
+              <td style="width: 100px; text-align: center" class="public-color">
+                单价
+                <br />
+                UNIT PRICE
+                <br />
+                {{
+                  dictValueLabel(
+                    printDetails.contract.currency,
+                    accountCurrency
+                  )
+                }}
+              </td>
+              <td
+                style="width: 100px; border-right: 0; text-align: center"
+                class="public-color"
+              >
+                总价
+                <br />
+                TOTAL PRICE
+                <br />
+                {{
+                  dictValueLabel(
+                    printDetails.contract.currency,
+                    accountCurrency
+                  )
+                }}
+              </td>
+            </template>
+          </tr>
+          <tbody
+            v-if="
+              printDetails.documentsProducts &&
+              printDetails.documentsProducts.length > 0
+            "
+          >
+            <tr
+              v-for="(item, index) in printDetails.documentsProducts"
+              :key="index"
+            >
+              <td style="text-align: center">{{ index + 1 }}</td>
+              <td>
+                <div style="text-align: center">{{ item.describes }}</div>
+                <div style="text-align: center">{{ item.subDescribe }}</div>
+                <div style="text-align: center">
+                  HS CODE: {{ item.customsCode }}
+                </div>
+              </td>
+              <td style="text-align: center" v-if="[3].includes(openStatus)">
+                {{ dictValueLabel(item.productUnit, productUnit) }}
+              </td>
+              <td style="text-align: center">{{ item.quantity }}</td>
+              <td
+                :rowspan="printDetails.documentsProducts.length"
+                style="text-align: center"
+                v-if="index === 0 && [1].includes(openStatus)"
+              >
+                {{ printDetails.sumBomVolume }}
+              </td>
+              <td
+                :rowspan="printDetails.documentsProducts.length"
+                style="text-align: center"
+                v-if="index === 0 && [1].includes(openStatus)"
+              >
+                {{ printDetails.sumRoughWeight }}
+              </td>
+              <td
+                :rowspan="printDetails.documentsProducts.length"
+                style="text-align: center"
+                v-if="index === 0 && [1].includes(openStatus)"
+              >
+                总尺寸
+              </td>
+              <td
+                :rowspan="printDetails.documentsProducts.length"
+                style="text-align: center; border-right: 0"
+                v-if="index === 0 && [1].includes(openStatus)"
+              >
+                总体积
+              </td>
+              <td style="text-align: center" v-if="[2, 3].includes(openStatus)">
+                {{ printDetails.contract.currency }}{{ item.price }}
+              </td>
+              <td
+                style="text-align: center; border-right: 0"
+                v-if="[2, 3].includes(openStatus)"
+              >
+                {{ printDetails.contract.currency
+                }}{{
+                  parseFloat(
+                    Number(item.quantity) * Number(item.price)
+                  ).toFixed(2)
+                }}
+              </td>
+            </tr>
+          </tbody>
+          <template v-if="[2].includes(openStatus)">
+            <tr>
+              <td
+                :colspan="2"
+                style="text-align: left; padding-left: 4px"
+                class="public-color"
+              >
+                SUBTOTAL:
+              </td>
+              <td style="text-align: center" class="public-color">
+                {{ statistics("quantity", "", 0) }}
+              </td>
+              <td></td>
+              <td style="text-align: center" class="public-color">
+                {{ printDetails.contract.currency
+                }}{{ statistics("price", "quantity", 2) }}
+              </td>
+            </tr>
+            <template
+              v-if="
+                printDetails.contractProjectList &&
+                printDetails.contractProjectList.length > 0
+              "
+            >
+              <tr
+                v-for="(item, index) in printDetails.contractProjectList"
+                :key="index"
+              >
+                <td
+                  :colspan="4"
+                  style="text-align: left; padding-left: 4px"
+                  class="public-color"
+                >
+                  {{ item.payName }}:
+                </td>
+                <td style="text-align: center" class="public-color">
+                  {{ printDetails.contract.currency }}{{ item.amount }}
+                </td>
+              </tr>
+            </template>
+            <tr>
+              <td
+                :colspan="4"
+                style="text-align: left; padding-left: 4px"
+                class="public-color"
+              >
+                TOTAL
+                {{
+                  dictValueLabel(
+                    printDetails.contract.tradeMethods,
+                    tradeMethods
+                  )
+                }}
+                PRICE:
+              </td>
+              <td style="text-align: center" class="public-color">
+                {{ printDetails.contract.currency
+                }}{{ getAllMoney(statistics("price", "quantity", 2)) }}
+              </td>
+            </tr>
+          </template>
+          <template v-if="[3].includes(openStatus)">
+            <tr>
+              <td
+                :colspan="3"
+                style="text-align: left; padding-left: 4px"
+                class="public-color"
+              >
+                SUBTOTAL:
+              </td>
+              <td style="text-align: center" class="public-color">
+                {{ statistics("quantity", "", 0) }}
+              </td>
+              <td></td>
+              <td style="text-align: center" class="public-color">
+                {{ printDetails.contract.currency
+                }}{{ statistics("price", "quantity", 2) }}
+              </td>
+            </tr>
+            <template
+              v-if="
+                printDetails.contractProjectList &&
+                printDetails.contractProjectList.length > 0
+              "
+            >
+              <tr
+                v-for="(item, index) in printDetails.contractProjectList"
+                :key="index"
+              >
+                <td
+                  :colspan="5"
+                  style="text-align: left; padding-left: 4px"
+                  class="public-color"
+                >
+                  {{ item.payName }}:
+                </td>
+                <td style="text-align: center" class="public-color">
+                  {{ printDetails.contract.currency }}{{ item.amount }}
+                </td>
+              </tr>
+            </template>
+            <tr>
+              <td
+                :colspan="5"
+                style="text-align: left; padding-left: 4px"
+                class="public-color"
+              >
+                TOTAL
+                {{
+                  dictValueLabel(
+                    printDetails.contract.tradeMethods,
+                    tradeMethods
+                  )
+                }}
+                PRICE:
+              </td>
+              <td style="text-align: center" class="public-color">
+                {{ printDetails.contract.currency
+                }}{{ getAllMoney(statistics("price", "quantity", 2)) }}
+              </td>
+            </tr>
+          </template>
+        </table>
+        <div v-if="[1].includes(openStatus)">
+          <div style="font-weight: 700; padding: 4px 0">
+            THE PACK FOR ABOVE CARGO ARE AS BELOWING SHOWS:
+          </div>
+          <table
+            class="three"
+            cellspacing="0"
+            cellpadding="0"
+            border="0"
+            style="width: 100%; border-bottom: 0"
+            v-if="
+              printDetails.packDetailList &&
+              printDetails.packDetailList.length > 0
+            "
+          >
+            <tbody
+              v-for="(item, index) in printDetails.packDetailList"
+              :key="index"
+            >
+              <tr
+                v-for="(itemAAA, indexAAA) in item.packDetailGoodsList"
+                :key="indexAAA"
+              >
+                <td
+                  :rowspan="item.packDetailGoodsList.length"
+                  style="text-align: center; width: 100px"
+                  v-if="indexAAA === 0"
+                >
+                  CTN NO.{{ index + 1 }}
+                </td>
+                <td>
+                  <div style="text-align: center">{{ itemAAA.remark }}</div>
+                </td>
+                <td style="text-align: center; width: 100px">
+                  {{ itemAAA.unit }}
+                </td>
+                <td style="text-align: center; width: 100px">
+                  {{ itemAAA.quantity }}
+                </td>
+                <td
+                  :rowspan="item.packDetailGoodsList.length"
+                  style="text-align: center; width: 200px; border-right: 0"
+                  v-if="indexAAA === 0"
+                >
+                  <span v-if="item.boxLong">{{ item.boxLong }}cm</span>
+                  <span>*</span>
+                  <span v-if="item.boxLong">{{ item.boxWide }}cm</span>
+                  <span>*</span>
+                  <span v-if="item.boxLong">{{ item.boxHigh }}cm</span>
+                  <span> / {{ item.roughWeight }}KG</span>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+        <div v-if="[3].includes(openStatus)">
+          <div style="height: 16px"></div>
+          <div class="baseRow">
+            <div class="contentRow public-color" style="width: 100%">
+              ACCOUNT INFORMATION:
+            </div>
+          </div>
+          <div class="baseRow" style="border-bottom: 1px solid black">
+            <div class="contentRow" style="width: 100%">
+              <div
+                style="
+                  line-height: 24px;
+                  padding-left: 4px;
+                  word-break: break-all;
+                  word-wrap: break-word;
+                "
+              >
+                Beneficiary Name: {{ printDetails.contract.beneficiaryName }}
+              </div>
+              <div
+                style="
+                  line-height: 24px;
+                  padding-left: 4px;
+                  word-break: break-all;
+                  word-wrap: break-word;
+                "
+              >
+                Beneficiary Bank: {{ printDetails.contract.beneficiaryBank }}
+              </div>
+              <div
+                style="
+                  line-height: 24px;
+                  padding-left: 4px;
+                  word-break: break-all;
+                  word-wrap: break-word;
+                "
+              >
+                Beneficiary Bank Address:
+                {{ printDetails.contract.beneficiaryBankAddress }}
+              </div>
+              <div
+                style="
+                  line-height: 24px;
+                  padding-left: 4px;
+                  word-break: break-all;
+                  word-wrap: break-word;
+                "
+              >
+                Beneficiary Account Number:
+                {{ printDetails.contract.beneficiaryAccountNumber }}
+              </div>
+              <div
+                style="
+                  line-height: 24px;
+                  padding-left: 4px;
+                  word-break: break-all;
+                  word-wrap: break-word;
+                "
+              >
+                Swift Code: {{ printDetails.contract.swiftCode }}
+              </div>
+              <div
+                style="
+                  line-height: 24px;
+                  padding-left: 4px;
+                  word-break: break-all;
+                  word-wrap: break-word;
+                "
+              >
+                Beneficiary Address:
+                {{ printDetails.contract.beneficiaryAddress }}
+              </div>
+            </div>
+          </div>
+          <div style="height: 32px"></div>
+          <div style="display: flex">
+            <div style="width: 50%">
+              <div class="public-color public-padding-bottom">
+                CONFIRMED BY VENDOR:
+              </div>
+              <div>{{ printDetails.corporation.nameEn }}</div>
+            </div>
+            <div style="width: 50%">
+              <div class="public-color public-padding-bottom">
+                CONFIRMED BY BUYER:
+              </div>
+              <div>{{ printDetails.customer.name }}</div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <el-button @click="openPrint = false" size="large">取消</el-button>
+        <el-button type="primary" @click="clickDownload()" size="large"
+          >下载PDF</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      title="打印"
+      v-if="openCustomsDeclaration"
+      v-model="openCustomsDeclaration"
+      width="1460"
+    >
+      <div
+        id="pdfDom"
+        style="width: 1400px; padding: 16px; font-size: 12px !important"
+      >
+        <table cellspacing="0" cellpadding="0" border="0" class="one">
+          <tr>
+            <td colspan="8">
+              <span style="font-weight: 700"
+                >出口货物正式报关单草单/申报信息填制模板</span
+              >
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2" style="background-color: #dce6f1">
+              <div>发件公司清关负责人</div>
+              <div>联系电话/手机(必填):</div>
+            </td>
+            <td colspan="2" style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.contacts }}
+              </div>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.contactsMobile }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.contacts"
+                size="small"
+              />
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.contactsMobile"
+                size="small"
+              />
+            </td>
+            <td colspan="2" style="background-color: #dce6f1">
+              <span>联系人邮箱:</span>
+            </td>
+            <td colspan="2" style="background-color: #ebf1de; text-align: left">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.contactsEmail }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.contactsEmail"
+                size="small"
+              />
+            </td>
+          </tr>
+          <tr style="background-color: #dce6f1">
+            <td colspan="2">
+              <span>境内发货人名称(填写发货公司中文名称)</span>
+            </td>
+            <td colspan="2">
+              <span
+                >境内发货人代码(填写18位统一社会信用代码,没有信用证代码填报10位海关备案编码)</span
+              >
+            </td>
+            <td colspan="2">
+              <span>出境关别(不用填写)</span>
+            </td>
+            <td colspan="2">
+              <span>备案号(如是手册的请填写)</span>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.companyNameChinese }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.companyNameChinese"
+                size="small"
+              />
+            </td>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.organizationCode }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.organizationCode"
+                size="small"
+              />
+            </td>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.exitCustoms }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.exitCustoms"
+                size="small"
+              />
+            </td>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.recordNo }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.recordNo"
+                size="small"
+              />
+            </td>
+          </tr>
+          <tr style="background-color: #dce6f1">
+            <td colspan="2">
+              <span
+                >境外收货人(指合同买方或合同指定的收货人公司英文名称)</span
+              >
+            </td>
+            <td colspan="2">
+              <span
+                >境外收货人代码(AEO互认企业需填报AEO编码;不填默认非AEO互认)</span
+              >
+            </td>
+            <td colspan="2">
+              <span>运输方式(不用填写)</span>
+            </td>
+            <td>
+              <span>运输工具名称及航次号(不用填写)</span>
+            </td>
+            <td>
+              <span>提运单号(指12位快递运单号码)</span>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2" style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.customerCompanyName }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.customerCompanyName"
+                size="small"
+              />
+            </td>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.overseasConsigneeCode }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.overseasConsigneeCode"
+                size="small"
+              />
+            </td>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.typeOfShipping }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.typeOfShipping"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.meansOfTransport }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.meansOfTransport"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.waybillCode }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.waybillCode"
+                size="small"
+              />
+            </td>
+          </tr>
+          <tr style="background-color: #dce6f1">
+            <td colspan="2">
+              <span>生产销售单位(指生产该产品的公司名称)</span>
+            </td>
+            <td colspan="2">
+              <span
+                >生产销售单位代码(填写18位统一社会信用代码,没有信用证代码填写“NO”)</span
+              >
+            </td>
+            <td colspan="2">
+              <span>监管方式</span>
+            </td>
+            <td>
+              <span>征免性质(与监管方式对应填写)</span>
+            </td>
+            <td>
+              <span>许可证号(如需许可证的请填写)</span>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.productCompanyNameChinese }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="
+                  printCustomsDeclaration.content.productCompanyNameChinese
+                "
+                size="small"
+              />
+            </td>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.productOrganizationCode }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="
+                  printCustomsDeclaration.content.productOrganizationCode
+                "
+                size="small"
+              />
+            </td>
+            <td colspan="2">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.supervisionMode }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.supervisionMode"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.exemptionNature }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.exemptionNature"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.licenseKey }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.licenseKey"
+                size="small"
+              />
+            </td>
+          </tr>
+          <tr style="background-color: #dce6f1">
+            <td colspan="2">
+              <span>合同协议号(根据合同填写)</span>
+            </td>
+            <td colspan="2">
+              <span>贸易国(合同买方所在国)</span>
+            </td>
+            <td colspan="2">
+              <span>运抵国</span>
+            </td>
+            <td>
+              <span>指运港(不用填写)</span>
+            </td>
+            <td>
+              <span>离境口岸(不用填写)</span>
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2" style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.contractCode }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.contractCode"
+                size="small"
+              />
+            </td>
+            <td colspan="2" style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.tradingCountry }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.tradingCountry"
+                size="small"
+              />
+            </td>
+            <td colspan="2" style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.arrivalCountry }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.arrivalCountry"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.portOfDestination }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.portOfDestination"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.departurePort }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.departurePort"
+                size="small"
+              />
+            </td>
+          </tr>
+          <tr style="background-color: #dce6f1">
+            <td>
+              <span>包装种类</span>
+            </td>
+            <td>
+              <span>件数(运单和装箱单一致)</span>
+            </td>
+            <td>
+              <span>毛重(千克)</span>
+            </td>
+            <td>
+              <span>净重(千克)</span>
+            </td>
+            <td>
+              <span>成交方式</span>
+            </td>
+            <td>
+              <span>运费</span>
+            </td>
+            <td>
+              <span>保费</span>
+            </td>
+            <td>
+              <span>杂费(如有请填写)</span>
+            </td>
+          </tr>
+          <tr>
+            <td style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.packageType }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.packageType"
+                size="small"
+              />
+            </td>
+            <td style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.sumPackQuantity }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.sumPackQuantity"
+                size="small"
+              />
+            </td>
+            <td style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.sumRoughWeight }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.sumRoughWeight"
+                size="small"
+              />
+            </td>
+            <td style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.sumNetWeight }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.sumNetWeight"
+                size="small"
+              />
+            </td>
+            <td style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.tradeModeName }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.tradeModeName"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.freightPrice }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.freightPrice"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.premiumPrice }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.premiumPrice"
+                size="small"
+              />
+            </td>
+            <td>
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.incidentalPrice }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.incidentalPrice"
+                size="small"
+              />
+            </td>
+          </tr>
+          <tr>
+            <td colspan="3" style="background-color: #dce6f1">
+              <span>随附单证及编号(常见如通关单号、原进口报关单号):</span>
+            </td>
+            <td colspan="5">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.documentsAttached }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.documentsAttached"
+                size="small"
+              />
+            </td>
+          </tr>
+          <tr>
+            <td colspan="2" style="background-color: #dce6f1">
+              <span>标记唛码及备注:</span>
+            </td>
+            <td colspan="2" style="background-color: #ebf1de">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.shippingMark }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.shippingMark"
+                size="small"
+              />
+            </td>
+            <td style="background-color: #dce6f1">
+              <span>境内货源地:</span>
+            </td>
+            <td colspan="3" style="background-color: #ebf1de; text-align: left">
+              <div
+                style="word-wrap: break-word; padding: 0 4px"
+                v-if="textShow"
+              >
+                {{ printCustomsDeclaration.content.withinChinaSource }}
+              </div>
+              <el-input
+                autosize
+                type="textarea"
+                v-if="!textShow"
+                v-model="printCustomsDeclaration.content.withinChinaSource"
+                size="small"
+              />
+            </td>
+          </tr>
+        </table>
+        <table cellspacing="0" cellpadding="0" border="0" class="two">
+          <tr>
+            <th style="width: 20px">
+              <span>项号</span>
+            </th>
+            <th style="width: 140px">
+              <span>商品编号(13位)原10位海关编码+3位检验检疫附加编码</span>
+            </th>
+            <th style="width: 140px">
+              <span>商品名称</span>
+            </th>
+            <th>
+              <span>品牌</span>
+            </th>
+            <th>
+              <span>品牌类型</span>
+            </th>
+            <th style="width: 140px">
+              <span>出口享惠情况(不填写则默认不享受)</span>
+            </th>
+            <th>
+              <span>型号</span>
+            </th>
+            <th style="width: 140px">
+              <span>税号所需申报要素(如:用途、材质等)</span>
+            </th>
+            <th>
+              <span>各项净重</span>
+            </th>
+            <th>
+              <span>成交数量</span>
+            </th>
+            <th>
+              <span>成交单位</span>
+            </th>
+            <th>
+              <span>原产国(地区)</span>
+            </th>
+            <th>
+              <span>总价与币制</span>
+            </th>
+            <th>
+              <span>成交单价</span>
+            </th>
+            <th>
+              <span>EXW 单价</span>
+            </th>
+          </tr>
+          <template
+            v-if="
+              printCustomsDeclaration.content.products &&
+              printCustomsDeclaration.content.products.length > 0
+            "
+          >
+            <tr
+              v-for="(item, index) in printCustomsDeclaration.content.products"
+              :key="index"
+            >
+              <td>
+                <span>{{ index + 1 }}</span>
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.customsCode }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.customsCode"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.productName }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.productName"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.brand }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.brand"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.brandType }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.brandType"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.exportBenefits }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.exportBenefits"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.productModelChinese }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.productModelChinese"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.declareRemark }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.declareRemark"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.netWeight }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.netWeight"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.quantity }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.quantity"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.unit }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.unit"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.countryChinese }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.countryChinese"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.sumPrice }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.sumPrice"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.declaredPrice }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.declaredPrice"
+                  size="small"
+                />
+              </td>
+              <td>
+                <div
+                  style="word-wrap: break-word; padding: 0 4px"
+                  v-if="textShow"
+                >
+                  {{ item.exwPrice }}
+                </div>
+                <el-input
+                  autosize
+                  type="textarea"
+                  v-if="!textShow"
+                  v-model="item.exwPrice"
+                  size="small"
+                />
+              </td>
+            </tr>
+          </template>
+          <tr>
+            <td colspan="15" style="text-align: left; padding-left: 8px">
+              <span style="color: red">
+                我司保证以上所提供的信息及资料准确无误,如在海关申报、查验时有任何异议,所造成的损失及后果由我司承担。
+                确认签名/盖章:_________________________
+              </span>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <template #footer>
+        <el-button @click="openCustomsDeclaration = false" size="large"
+          >取消</el-button
+        >
+        <el-button type="primary" @click="clickDownload()" size="large"
+          >下载PDF</el-button
+        >
+        <el-button type="primary" @click="clickSave()" size="large"
+          >保存</el-button
+        >
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import { ElMessage, ElMessageBox } from "element-plus";
+import useUserStore from "@/store/modules/user";
+import { useRoute } from "vue-router";
+const route = useRoute();
+const { proxy } = getCurrentInstance();
+const shipmentList = ref([]);
+const countryData = ref([]);
+const fundsPaymentMethod = ref([]);
+const shippingMethod = ref([]);
+const tradeMethods = ref([]);
+const accountCurrency = ref([]);
+const productUnit = ref([]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    warehouseId: "",
+    toWarehouseId: "",
+  },
+});
+const loading = ref(false);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "归属公司",
+        prop: "sellCorporationName",
+        "min-width": 260,
+      },
+    },
+    {
+      attrs: {
+        label: "客户名称",
+        prop: "buyCorporationName",
+        "min-width": 200,
+      },
+    },
+    {
+      attrs: {
+        label: "主合同编号",
+        prop: "code",
+        width: 200,
+      },
+    },
+    {
+      attrs: {
+        label: "货运详情",
+        slot: "acceptCode",
+        width: 200,
+      },
+    },
+    {
+      attrs: {
+        label: "查看单证",
+        slot: "toView",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "创建时间",
+        prop: "createTime",
+        width: 160,
+      },
+    },
+  ];
+});
+const getDict = () => {
+  proxy.post("/customizeArea/list", { parentId: "0" }).then((res) => {
+    if (res && res.length > 0) {
+      countryData.value = res.map((item) => {
+        return {
+          label: item.name,
+          value: item.id,
+        };
+      });
+    }
+  });
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "funds_payment_method",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        fundsPaymentMethod.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+      }
+    });
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "shipping_method",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        shippingMethod.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+      }
+    });
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "trade_mode",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        tradeMethods.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+      }
+    });
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "account_currency",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        accountCurrency.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+      }
+    });
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "unit",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        productUnit.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+      }
+    });
+};
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/documents/page", sourceList.value.pagination).then((res) => {
+    sourceList.value.data = res.rows;
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+getDict();
+if (route.query.currentContractId) {
+  sourceList.value.pagination.contractId = route.query.currentContractId;
+}
+getList();
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formData = reactive({
+  data: {
+    documentsProductList: [],
+  },
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      prop: "contractId",
+      label: "出货主合同",
+      required: true,
+      data: shipmentList.value,
+      fn: (val) => {
+        changeContract(val);
+      },
+    },
+    {
+      type: "slot",
+      slotName: "details",
+      label: "产品信息",
+    },
+    {
+      label: "唛头信息",
+    },
+    {
+      type: "select",
+      prop: "countryId",
+      label: "目的国",
+      required: true,
+      filterable: true,
+      data: countryData.value,
+      itemWidth: 40,
+    },
+    {
+      type: "input",
+      prop: "portOfDestination",
+      label: "目的港",
+      itemWidth: 60,
+    },
+    {
+      type: "input",
+      prop: "remark",
+      label: "唛头明细",
+      itemType: "textarea",
+    },
+  ];
+});
+const rules = ref({
+  contractId: [
+    { required: true, message: "请选择出货主合同", trigger: "change" },
+  ],
+  countryId: [{ required: true, message: "请选择目的国", trigger: "change" }],
+  describes: [{ required: true, message: "请输入货物描述", trigger: "blur" }],
+  subDescribe: [{ required: true, message: "请输入副描述", trigger: "blur" }],
+  customsCode: [{ required: true, message: "请输入海关编码", trigger: "blur" }],
+  quantity: [{ required: true, message: "请输入数量", trigger: "blur" }],
+  price: [{ required: true, message: "请输入单价", trigger: "blur" }],
+});
+const openModal = () => {
+  proxy.post("/packShipment/list", {}).then((res) => {
+    if (res && res.length > 0) {
+      shipmentList.value = res.map((item) => {
+        return {
+          packShipmentId: item.id,
+          label: item.contractCode,
+          value: item.contractId,
+          packDetailIds: item.packDetailIds,
+        };
+      });
+    } else {
+      shipmentList.value = [];
+    }
+  });
+  formData.data = {
+    documentsProductList: [],
+  };
+  loadingDialog.value = false;
+  dialogVisible.value = true;
+};
+const changeContract = (val) => {
+  if (val) {
+    let data = shipmentList.value.filter((item) => item.value === val);
+    if (data && data.length > 0) {
+      formData.data.packShipmentId = data[0].packShipmentId;
+      proxy
+        .post("/packShipment/productDetailList", {
+          packDetailIds: data[0].packDetailIds,
+        })
+        .then((res) => {
+          if (res && res.length > 0) {
+            formData.data.documentsProductList = res.map((item) => {
+              return {
+                businessId: item.businessId,
+                productId: item.productId,
+                describes: item.remark,
+                subDescribe: item.subDescription,
+                customsCode: item.customsCode,
+                quantity: item.quantity,
+                price: item.price,
+                type: item.type,
+              };
+            });
+          } else {
+            formData.data.documentsProductList = [];
+          }
+        });
+    } else {
+      formData.data.documentsProductList = [];
+    }
+    proxy.post("/contract/detail", { id: val }).then((res) => {
+      formData.data.countryId = res.buyCountryId;
+    });
+  } else {
+    formData.data.documentsProductList = [];
+  }
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    proxy.post("/documents/add", formData.data).then(
+      () => {
+        ElMessage({
+          message: "提交成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        sourceList.value.pagination.pageNum = 1;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+  });
+};
+const openAddAcceptCode = ref(false);
+const loadingTwo = ref(false);
+const submitTwo = ref(null);
+const fileList = ref([]);
+const uploadData = ref({});
+const formDataTwo = reactive({
+  data: {
+    documentsId: "",
+  },
+});
+const formConfigTwo = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "acceptCarriage",
+      label: "承运方",
+      itemType: "text",
+      itemWidth: 40,
+    },
+    {
+      type: "input",
+      prop: "code",
+      label: "单号",
+      itemType: "text",
+      itemWidth: 60,
+    },
+    {
+      type: "slot",
+      prop: "departureTime",
+      slotName: "departureTime",
+      label: "起运时间",
+    },
+    {
+      type: "input",
+      prop: "remark",
+      label: "备注",
+      itemType: "textarea",
+    },
+    {
+      type: "slot",
+      prop: "file",
+      slotName: "file",
+      label: "上传附件",
+    },
+  ];
+});
+const rulesTwo = ref({
+  acceptCarriage: [
+    { required: true, message: "请输入承运方", trigger: "blur" },
+  ],
+  code: [{ required: true, message: "请输入承运单号", trigger: "blur" }],
+  departureTime: [
+    { required: true, message: "请选择起运时间", trigger: "change" },
+  ],
+});
+const clickAddAcceptCode = (item) => {
+  formDataTwo.data = {
+    documentsId: item.id,
+  };
+  fileList.value = [];
+  openAddAcceptCode.value = true;
+};
+const uploadFile = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  file.id = res.id;
+  file.fileName = res.fileName;
+  file.fileUrl = res.fileUrl;
+  return true;
+};
+const onPreviewFile = (file) => {
+  window.open(file.raw.fileUrl, "_blank");
+};
+const submitTwoForm = () => {
+  submitTwo.value.handleSubmit(() => {
+    if (fileList.value && fileList.value.length > 0) {
+      formDataTwo.data.fileList = fileList.value.map((item) => {
+        return {
+          id: item.raw.id,
+          fileName: item.raw.fileName,
+          fileUrl: item.raw.fileUrl,
+        };
+      });
+    } else {
+      formDataTwo.data.fileList = [];
+    }
+    loadingTwo.value = true;
+    proxy.post("/documentsTransport/add", formDataTwo.data).then(
+      () => {
+        ElMessage({
+          message: "提交成功",
+          type: "success",
+        });
+        openAddAcceptCode.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingTwo.value = false;
+      }
+    );
+  });
+};
+const rowData = ref({});
+const openSelectPrint = ref(false);
+const clickToView = (item) => {
+  rowData.value = item;
+  openSelectPrint.value = true;
+  printDetails.value = {
+    packDetailGoodsList: [],
+    documents: {},
+    contract: {},
+    corporation: {},
+    packDetailList: [],
+    documentsProducts: [],
+    customer: {},
+  };
+  proxy
+    .get("/documents/generateInvoiceAPackPdf", { id: rowData.value.id })
+    .then((res) => {
+      printDetails.value = res.data;
+    });
+};
+const openPrint = ref(false);
+const openStatus = ref("");
+const printDetails = ref({
+  packDetailGoodsList: [],
+  documents: {},
+  contract: {},
+  contractProjectList: [],
+  corporation: {},
+  packDetailList: [],
+  documentsProducts: [],
+  customer: {},
+});
+const openCustomsDeclaration = ref(false);
+const printCustomsDeclaration = ref({
+  content: {},
+});
+const textShow = ref(false);
+const clickPrint = (status) => {
+  // printDetails.value = {
+  //   packDetailGoodsList: [],
+  //   documents: {},
+  //   contract: {},
+  //   contractProjectList: [],
+  //   corporation: {},
+  //   packDetailList: [],
+  //   documentsProducts: [],
+  //   customer: {},
+  // };
+  if ([1, 2, 3].includes(status)) {
+    openStatus.value = status;
+    openPrint.value = true;
+  } else {
+    printCustomsDeclaration.value = {
+      content: {},
+    };
+    openStatus.value = status;
+    textShow.value = false;
+    openCustomsDeclaration.value = true;
+    proxy
+      .get("/documents/generateClearanceePdf", { id: rowData.value.id })
+      .then((res) => {
+        if (res.data.content) {
+          res.data.content = JSON.parse(res.data.content);
+        }
+        printCustomsDeclaration.value = res.data;
+      });
+  }
+  // proxy.get("/documents/generateInvoiceAPackPdf", { id: rowData.value.id }).then((res) => {
+  //   printDetails.value = res.data;
+  // });
+};
+const clickDownload = () => {
+  if (openStatus.value === 1) {
+    proxy.getPdf("装箱单PDF文件");
+  } else if (openStatus.value === 2) {
+    proxy.getPdf("商业发票PDF文件");
+  } else if (openStatus.value === 3) {
+    proxy.getPdf("销售确认书PDF文件");
+  } else if (openStatus.value === 4) {
+    textShow.value = true;
+    let data = proxy.deepClone(printCustomsDeclaration.value);
+    data.content = JSON.stringify(data.content);
+    proxy.post("/documentsPdf/add", data).then();
+    setTimeout(() => {
+      proxy.getPdfTransverseA4("报关单PDF文件");
+      nextTick(() => {
+        setTimeout(() => {
+          textShow.value = false;
+        }, 1000);
+      });
+    }, 1000);
+  }
+};
+const clickSave = () => {
+  if (openStatus.value === 1) {
+    proxy.getPdf("装箱单PDF文件");
+  } else if (openStatus.value === 2) {
+    proxy.getPdf("商业发票PDF文件");
+  } else if (openStatus.value === 3) {
+    proxy.getPdf("销售确认书PDF文件");
+  } else if (openStatus.value === 4) {
+    textShow.value = true;
+    let data = proxy.deepClone(printCustomsDeclaration.value);
+    data.content = JSON.stringify(data.content);
+    proxy.post("/documentsPdf/add", data).then((res) => {
+      ElMessage({
+        message: "保存成功",
+        type: "success",
+      });
+    });
+  }
+};
+const getStyle = (text) => {
+  if (text) {
+    return text.replace(/\n|\r\n/g, "<br>");
+  } else {
+    return "";
+  }
+};
+const statistics = (label, label2, index) => {
+  let num = 0;
+  if (
+    printDetails.value.documentsProducts &&
+    printDetails.value.documentsProducts.length > 0
+  ) {
+    printDetails.value.documentsProducts.map((item) => {
+      if (label2) {
+        if (item[label] && item[label2]) {
+          num = parseFloat(
+            Number(num) + Number(item[label]) * Number(item[label2])
+          ).toFixed(index);
+        }
+      } else {
+        if (item[label]) {
+          num = parseFloat(Number(num) + Number(item[label])).toFixed(index);
+        }
+      }
+    });
+  }
+  return num;
+};
+const getAllMoney = (num) => {
+  let money = num;
+  if (
+    printDetails.value.contractProjectList &&
+    printDetails.value.contractProjectList.length > 0
+  ) {
+    printDetails.value.contractProjectList.map((item) => {
+      if (item.amount) {
+        money = parseFloat(Number(money) + Number(item.amount)).toFixed(2);
+      }
+    });
+  }
+  return money;
+};
+</script>
+
+<style lang="scss" scoped>
+.public-title {
+  font-size: 16px;
+  text-align: center;
+  // font-weight: 700;
+  color: #0647eb;
+}
+.title-decoration {
+  font-size: 16px;
+  text-align: center;
+  text-decoration: underline;
+  // font-weight: 700;
+  color: #0647eb;
+}
+.public-color {
+  color: #0647eb;
+  font-weight: none;
+}
+.public-padding-bottom {
+  padding-bottom: 4px;
+}
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+.baseRow {
+  min-height: 20px;
+  border-top: 1px solid black;
+  border-left: 1px solid black;
+}
+.contentRow {
+  border-right: 1px solid black;
+  line-height: 20px;
+  padding-left: 4px;
+}
+.three {
+  width: 100%;
+  border: 1px solid black;
+}
+.three thead {
+  text-align: center;
+  line-height: 20px;
+  font-weight: 700;
+}
+.three th {
+  border-right: 1px solid black;
+  border-bottom: 1px solid black;
+}
+.three td {
+  line-height: 20px;
+  border-right: 1px solid black;
+  border-bottom: 1px solid black;
+}
+.one {
+  width: 100%;
+  text-align: center;
+  border-top: 1px solid black;
+  border-left: 1px solid black;
+  table-layout: fixed;
+}
+.one td {
+  border: 0;
+  line-height: 18px;
+  border-right: 1px solid black;
+  border-bottom: 1px solid black;
+}
+.two {
+  width: 100%;
+  text-align: center;
+  border-top: 1px solid black;
+  border-left: 1px solid black;
+  table-layout: fixed;
+}
+.two th {
+  border: 0;
+  line-height: 18px;
+  border-right: 1px solid black;
+  border-bottom: 1px solid black;
+  background-color: #dce6f1;
+}
+.two td {
+  border: 0;
+  line-height: 18px;
+  border-right: 1px solid black;
+  border-bottom: 1px solid black;
+}
+:deep(#pdfDom .el-textarea__inner) {
+  background: transparent !important;
+  overflow-y: hidden;
+  padding: 0 4px !important;
+  resize: none;
+}
+:deep(#pdfDom .el-textarea) {
+  --el-input-focus-border: transparent;
+  --el-input-transparent-border: 0 0 0 0px;
+  --el-input-border-color: transparent;
+  --el-input-hover-border: 0px !important;
+  --el-input-hover-border-color: transparent;
+  --el-input-focus-border-color: transparent;
+  --el-input-clear-hover-color: transparent;
+  box-shadow: 0 0 0 0px !important;
+  --el-input-border: 0px;
+}
+</style>

+ 1406 - 0
src/components/detailCom/exportTracking/index.vue

@@ -0,0 +1,1406 @@
+<template>
+  <div class="tenant">
+    <byTable
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      highlight-current-row
+      :action-list="[]"
+      :hidePagination="true"
+      :hideSearch="true"
+      @get-list="getList"
+    >
+      <template #code="{ item }">
+        <div style="width: 100%">
+          <span class="public-class" @click="openDetails(item)">{{
+            item.code
+          }}</span>
+        </div>
+      </template>
+
+      <template #customer="{ item }">
+        <div style="width: 100%">
+          <span class="public-class" @click="clickCorporationName(item)">{{
+            item.buyCorporationName
+          }}</span>
+        </div>
+      </template>
+
+      <template #contractProduct="{ item }">
+        <div style="width: 100%">
+          <div
+            v-for="(product, index) in item.contractProductList"
+            :key="index"
+          >
+            <el-tooltip
+              class="box-item"
+              effect="dark"
+              :content="product.productName"
+              placement="top-start"
+            >
+              <div class="hidden-text">
+                {{ product.productName }}
+              </div>
+            </el-tooltip>
+          </div>
+        </div>
+      </template>
+
+      <template #tags="{ item }">
+        <div style="width: 100%">
+          <div
+            v-for="(product, index) in item.contractProductList"
+            :key="index"
+          >
+            {{ dictValueLabel(product.tradeMethods, tradeMethods) }}
+          </div>
+        </div>
+      </template>
+
+      <template #supplyName="{ item }">
+        <div style="width: 100%">
+          <div v-if="item.purchaseList && item.purchaseList.length > 0">
+            <div v-for="(purchase, index) in item.purchaseList" :key="index">
+              <el-tooltip
+                class="box-item"
+                effect="dark"
+                :content="purchase.supplyName"
+                placement="top-start"
+              >
+                <div class="hidden-text">
+                  {{ purchase.supplyName }}
+                </div>
+              </el-tooltip>
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <template #purchaseCode="{ item }">
+        <div style="width: 100%">
+          <div v-if="item.purchaseList && item.purchaseList.length > 0">
+            <div
+              v-for="(purchase, index) in item.purchaseList"
+              :key="index"
+              class="public-class"
+              @click="hdanlePushPurchase(purchase.code)"
+            >
+              {{ purchase.code }}
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <template #purchaseCreateTime="{ item }">
+        <div style="width: 100%">
+          <div v-if="item.purchaseList && item.purchaseList.length > 0">
+            <div v-for="(purchase, index) in item.purchaseList" :key="index">
+              {{ purchase.createTime.slice(0, 11) }}
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <template #purchaseDeliveryTime="{ item }">
+        <div style="width: 100%">
+          <div v-if="item.purchaseList && item.purchaseList.length > 0">
+            <div v-for="(purchase, index) in item.purchaseList" :key="index">
+              {{ purchase.deliveryTime }}
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <template #remarks="{ item }">
+        <div style="width: 100%">
+          <el-button
+            type="primary"
+            text
+            @click="handleClickLookRemarksRecords(item)"
+            >查看</el-button
+          >
+        </div>
+      </template>
+
+      <template #receipt="{ item }">
+        <div style="width: 100%">
+          <el-button
+            type="primary"
+            text
+            @click="handleClickLookContractFile(item, true)"
+            >查看</el-button
+          >
+        </div>
+      </template>
+
+      <template #package="{ item }">
+        <div style="width: 100%">
+          <el-button
+            type="primary"
+            text
+            @click="handleClickLookContractFile(item, false)"
+            >查看</el-button
+          >
+        </div>
+      </template>
+
+      <template #balanceMoney="{ item }">
+        <div style="width: 100%">
+          {{ moneyFormat(item.finalPayment, 2) }}
+        </div>
+      </template>
+
+      <!-- 动态头部插槽 -->
+      <template
+        v-for="(documentary, index) in headerList"
+        v-slot:[documentary.value]="{ item }"
+        :key="documentary.value"
+      >
+        <div style="width: 100%; display: flex; align-items: center">
+          <span>{{ documentary.label }}</span>
+          <span
+            style="
+              color: #8400ff;
+              cursor: pointer;
+              display: flex;
+              align-items: center;
+            "
+            @click="handleClickHeader(documentary.value)"
+            ><span>({{ headerData[documentary.value] || 0 }})</span>
+            <span
+              v-if="documentary.value == currentHeader && clickNum == 1"
+              class="iconfont icon-iconm_shanchu"
+              style="color: #d81e06; font-size: 20px"
+            >
+            </span>
+            <span
+              v-if="documentary.value == currentHeader && clickNum == 2"
+              class="iconfont icon-iconm_quertj"
+              style="color: #16c4af; font-size: 20px"
+            >
+            </span>
+          </span>
+        </div>
+      </template>
+
+      <!-- 动态内容插槽 -->
+      <template
+        v-for="(documentary, index) in headerList"
+        v-slot:[documentary.slot]="{ item }"
+        :key="documentary.slot"
+      >
+        <div style="width: 100%">
+          <div v-if="documentary.value == '1'">
+            <div v-if="item.purchaseList && item.purchaseList.length > 0">
+              <div
+                v-for="(purchase, index) in item.purchaseList"
+                :key="purchase.id"
+              >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-if="judgeHaveData(purchase, documentary.value)"
+                  >已提交</el-button
+                >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  style="color: #f59a23"
+                  v-else
+                  >未提交</el-button
+                >
+              </div>
+            </div>
+          </div>
+          <div
+            v-else-if="
+              ['2', '3', '4', '5', '7', '9'].includes(documentary.value)
+            "
+          >
+            <div v-if="item.purchaseList && item.purchaseList.length > 0">
+              <div
+                v-for="(purchase, index) in item.purchaseList"
+                :key="purchase.id"
+              >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-if="judgeHaveData(purchase, documentary.value)"
+                  >查看</el-button
+                >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  style="color: #f59a23"
+                  v-else
+                  >添加</el-button
+                >
+              </div>
+            </div>
+          </div>
+
+          <div v-else-if="documentary.value == '6'">
+            <div v-if="item.purchaseList && item.purchaseList.length > 0">
+              <div
+                v-for="(purchase, index) in item.purchaseList"
+                :key="purchase.id"
+              >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-if="!judgeHaveData(purchase, documentary.value)"
+                  style="color: #f59a23"
+                  >待验货</el-button
+                >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-else-if="judgeHaveDataOne(purchase, documentary.value)"
+                  >通过</el-button
+                >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-else
+                  style="color: red"
+                  >未通过</el-button
+                >
+              </div>
+            </div>
+          </div>
+
+          <div v-else-if="documentary.value == '8'">
+            <div v-if="item.purchaseList && item.purchaseList.length > 0">
+              <div
+                v-for="(purchase, index) in item.purchaseList"
+                :key="purchase.id"
+              >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-if="!judgeHaveData(purchase, documentary.value)"
+                  style="color: #f59a23"
+                  >添加</el-button
+                >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-else-if="judgeHaveDataOne(purchase, documentary.value)"
+                  >已收到</el-button
+                >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  style="color: red"
+                  v-else
+                  >未收到</el-button
+                >
+              </div>
+            </div>
+          </div>
+          <div v-else-if="['10', '11', '12'].includes(documentary.value)">
+            <div v-if="item.purchaseList && item.purchaseList.length > 0">
+              <div
+                v-for="(purchase, index) in item.purchaseList"
+                :key="purchase.id"
+              >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  v-if="judgeHaveData(purchase, documentary.value)"
+                  >{{
+                    judgeHaveDataOne(purchase, documentary.value)
+                  }}</el-button
+                >
+                <el-button
+                  type="primary"
+                  text
+                  @click="handleClickLook(item, purchase, documentary)"
+                  style="color: #f59a23"
+                  v-else
+                  >添加</el-button
+                >
+              </div>
+            </div>
+          </div>
+          <div v-else>暂无</div>
+        </div>
+      </template>
+
+      <!-- <template #slot1="{ item }">
+        <div style="width: 100%">
+          <div v-if="item.purchaseList && item.purchaseList.length > 0">
+            <div v-for="(purchase, index) in item.purchaseList" :key="index">
+              <el-button
+                type="primary"
+                text
+                @click="handleClickLook(item, purchase, '1')"
+                >查看</el-button
+              >
+            </div>
+          </div>
+        </div>
+      </template> -->
+    </byTable>
+    <!-- 备注弹窗 -->
+    <el-dialog
+      title="备注"
+      v-if="openRemarks"
+      v-model="openRemarks"
+      width="600"
+    >
+      <byForm
+        :formConfig="remarksFormConfig"
+        :formOption="formOption"
+        v-model="formData.remarksFormData"
+        :rules="remarksRules"
+        ref="remarksForm"
+        v-loading="formLoading"
+      >
+        <template #file>
+          <div style="width: 100%">
+            <el-upload
+              v-model:fileList="formData.remarksFormData.fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-success="handleSuccess"
+              :on-preview="onPreviewFile"
+            >
+              <el-button type="primary" plain>选择</el-button>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openRemarks = false" size="large">关 闭</el-button>
+        <el-button type="primary" @click="submitRemarks()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <!-- 记录弹窗 -->
+    <el-dialog
+      :title="`备注记录`"
+      v-if="openRemarkRecords"
+      v-model="openRemarkRecords"
+      width="600"
+    >
+      <div style="padding-left: 50px; margin-bottom: 20px">
+        <el-button type="primary" @click="handleClickLookRemarks()"
+          >添加备注</el-button
+        >
+      </div>
+      <el-timeline>
+        <el-timeline-item
+          v-for="(activity, index) in remarkRecordsData"
+          :key="index"
+        >
+          <div
+            style="
+              width: 100%;
+              display: flex;
+              justify-content: space-between;
+              color: #bfb9b9;
+            "
+          >
+            <div>{{ activity.createTime }}</div>
+            <div>{{ activity.userName }}</div>
+          </div>
+          <div style="width: 100%; margin-top: 8px">
+            {{ activity.documentaryRemark }}
+          </div>
+          <div
+            style="width: 100%; margin-top: 8px"
+            v-if="activity.fileList && activity.fileList.length > 0"
+          >
+            <div v-for="(item, index) in activity.fileList" :key="index">
+              <div
+                style="cursor: pointer; color: #409eff"
+                @click="openFile(item)"
+              >
+                {{ item.fileName }}
+              </div>
+            </div>
+          </div>
+        </el-timeline-item>
+      </el-timeline>
+
+      <template #footer>
+        <el-button @click="openRemarkRecords = false" size="large"
+          >关 闭</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <!-- 交接单、包装指示弹窗 -->
+    <el-dialog
+      :title="fileTitle"
+      v-if="openFiles"
+      v-model="openFiles"
+      width="600"
+    >
+      <byForm
+        :formConfig="filesFormConfig"
+        :formOption="formOption"
+        v-model="formData.filesFormData"
+      >
+        <template #file>
+          <div style="width: 100%">
+            <el-upload
+              v-model:fileList="formData.filesFormData.fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-success="handleSuccess"
+              :on-preview="onPreviewFile"
+            >
+              <el-button type="primary" plain disabled>选择</el-button>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openFiles = false" size="large">关 闭</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 记录弹窗 -->
+    <el-dialog
+      :title="`(${selectNode.label})详情记录`"
+      v-if="openRecords"
+      v-model="openRecords"
+      width="600"
+    >
+      <div style="padding-left: 50px; margin-bottom: 20px">
+        <el-button type="primary" @click="handleClickAddRecord()"
+          >添加记录</el-button
+        >
+      </div>
+      <el-timeline>
+        <el-timeline-item v-for="(activity, index) in recordsData" :key="index">
+          <div
+            style="
+              width: 100%;
+              display: flex;
+              justify-content: space-between;
+              color: #bfb9b9;
+            "
+          >
+            <div>{{ activity.documentaryTime }}</div>
+            <div>{{ activity.userName }}</div>
+          </div>
+          <div style="width: 100%; margin-top: 8px">
+            {{ activity.documentaryRemark }}
+          </div>
+          <div
+            style="width: 100%; margin-top: 8px"
+            v-if="activity.fileList && activity.fileList.length > 0"
+          >
+            <div v-for="(item, index) in activity.fileList" :key="index">
+              <div
+                style="cursor: pointer; color: #409eff"
+                @click="openFile(item)"
+              >
+                {{ item.fileName }}
+              </div>
+            </div>
+          </div>
+        </el-timeline-item>
+      </el-timeline>
+
+      <template #footer>
+        <el-button @click="openRecords = false" size="large">关 闭</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 添加记录弹窗 -->
+    <el-dialog
+      :title="`添加记录(${selectNode.label})`"
+      v-if="openAddRecords"
+      v-model="openAddRecords"
+      width="600"
+    >
+      <byForm
+        :formConfig="recordsFormConfig"
+        :formOption="formOption"
+        v-model="formData.recordsFormData"
+        :rules="recordsRules"
+        ref="recordsForm"
+        v-loading="formLoading"
+      >
+        <template #typeSlot>
+          <div style="width: 100%">
+            <el-select
+              v-model="formData.recordsFormData.content"
+              class="m-2"
+              placeholder="请选择"
+              v-if="selectNode.value == '6'"
+            >
+              <el-option label="通过" value="1" />
+              <el-option label="未通过" value="0" />
+            </el-select>
+            <el-select
+              v-model="formData.recordsFormData.content"
+              class="m-2"
+              placeholder="请选择"
+              v-if="selectNode.value == '8'"
+            >
+              <el-option label="收到" value="1" />
+              <el-option label="未收到" value="0" />
+            </el-select>
+            <el-date-picker
+              v-if="['10', '11', '12'].includes(selectNode.value)"
+              v-model="formData.recordsFormData.content"
+              type="date"
+              placeholder="请选择"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+            />
+          </div>
+        </template>
+        <template #file>
+          <div style="width: 100%">
+            <el-upload
+              v-model:fileList="formData.recordsFormData.fileList"
+              action="https://winfaster.obs.cn-south-1.myhuaweicloud.com"
+              :data="uploadData"
+              multiple
+              :before-upload="uploadFile"
+              :on-success="handleSuccess"
+              :on-preview="onPreviewFile"
+            >
+              <el-button type="primary" plain>选择</el-button>
+            </el-upload>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openAddRecords = false" size="large"
+          >关 闭</el-button
+        >
+        <el-button type="primary" @click="submitRecords()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { computed } from "vue";
+import useUserStore from "@/store/modules/user";
+import { useRoute } from "vue-router";
+const route = useRoute();
+const props = defineProps({
+  contractId: String,
+});
+const userInfo = useUserStore();
+// const tableHeight = ref(0);
+// const getTableHeight = () => {
+//   tableHeight.value = window.innerHeight - 270;
+// };
+// getTableHeight();
+window.addEventListener("resize", () => {
+  getTableHeight();
+});
+const { proxy } = getCurrentInstance();
+const uploadData = ref({});
+const tradeMethods = ref([]);
+const contractDocumentary = ref([]);
+const status = ref([
+  {
+    label: "待采购待收款",
+    value: 10,
+  },
+  {
+    label: "待采购已收款",
+    value: 20,
+  },
+  {
+    label: "已采购待收款",
+    value: 30,
+  },
+  {
+    label: "已完成",
+    value: 40,
+  },
+]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    orderStatus: "",
+    documentaryType: "",
+    documentarySearch: "0",
+    id: "",
+  },
+});
+const loading = ref(false);
+const selectConfig = computed(() => {
+  return [
+    {
+      label: "订单状态",
+      prop: "orderStatus",
+      data: status.value,
+    },
+  ];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "订单号",
+        slot: "code",
+        width: 150,
+        fixed: "left",
+      },
+    },
+    {
+      attrs: {
+        label: "订单状态",
+        prop: "orderStatus",
+        width: 120,
+        fixed: "left",
+      },
+      render(type) {
+        return proxy.dictValueLabel(type, status.value);
+      },
+    },
+    {
+      attrs: {
+        label: "备注",
+        slot: "remarks",
+        width: 60,
+        fixed: "left",
+        align: "center",
+      },
+    },
+    isShowSalesmanArrange.value
+      ? {
+          attrs: {
+            label: "客户",
+            slot: "customer",
+            "min-width": 140,
+            fixed: "left",
+          },
+        }
+      : {},
+    {
+      attrs: {
+        label: "产品",
+        slot: "contractProduct",
+        width: 140,
+      },
+    },
+    isShowSalesFinancemanArrange.value
+      ? {
+          attrs: {
+            label: "条款",
+            slot: "tags",
+            width: 80,
+          },
+        }
+      : {},
+    isShowSalesFinancemanArrange.value
+      ? {
+          attrs: {
+            label: "定金",
+            prop: "earnest",
+            width: 100,
+          },
+          render(money) {
+            return proxy.moneyFormat(money, 2);
+          },
+        }
+      : {},
+    isShowSalesFinancemanArrange.value
+      ? {
+          attrs: {
+            label: "定金到账时间",
+            prop: "claimTime",
+            width: 110,
+          },
+          render(time) {
+            if (time) {
+              return time.slice(0, 11);
+            }
+          },
+        }
+      : {},
+    {
+      attrs: {
+        label: "交接单",
+        slot: "receipt",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "包装指示",
+        slot: "package",
+        width: 90,
+      },
+    },
+    {
+      attrs: {
+        label: "采购订单号",
+        slot: "purchaseCode",
+        width: 160,
+      },
+    },
+    {
+      attrs: {
+        label: "供应商",
+        slot: "supplyName",
+        "min-width": 140,
+      },
+    },
+    {
+      attrs: {
+        label: "下单时间",
+        slot: "purchaseCreateTime",
+        width: 110,
+      },
+    },
+    {
+      attrs: {
+        label: "交期",
+        slot: "purchaseDeliveryTime",
+        width: 100,
+      },
+    },
+  ];
+});
+const getDict = () => {
+  proxy.getDictOne(["trade_mode", "contract_documentary"]).then((res) => {
+    tradeMethods.value = res["trade_mode"].map((x) => ({
+      label: x.dictValue,
+      value: x.dictKey,
+    }));
+  });
+};
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  getHeaderData();
+  proxy
+    .post("/contract/exportCopy/page", sourceList.value.pagination)
+    .then((res) => {
+      for (let i = 0; i < res.rows.length; i++) {
+        if (
+          res.rows[i].contractProductList &&
+          res.rows[i].contractProductList.length > 0
+        ) {
+          for (let j = 0; j < res.rows[i].contractProductList.length; j++) {
+            let element = res.rows[i].contractProductList[j];
+            if (element.ehsdJson) {
+              let jsonObj = JSON.parse(element.ehsdJson);
+              element.tradeMethods = jsonObj.tradeMethods;
+            }
+          }
+        }
+      }
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+const headerList = ref([
+  {
+    label: "签样",
+    value: "1",
+    slot: "slot1",
+  },
+  {
+    label: "LOGO",
+    value: "2",
+    slot: "slot2",
+  },
+  {
+    label: "包材稿件",
+    value: "3",
+    slot: "slot3",
+  },
+  {
+    label: "箱唛",
+    value: "4",
+    slot: "slot4",
+  },
+  {
+    label: "标签(内盒标/FBA 标)",
+    value: "5",
+    slot: "slot5",
+  },
+  {
+    label: "验货",
+    value: "6",
+    slot: "slot6",
+  },
+  {
+    label: "出货通知",
+    value: "7",
+    slot: "slot7",
+  },
+  {
+    label: "大货样",
+    value: "8",
+    slot: "slot8",
+  },
+  {
+    label: "订舱(BL info 给 ADA)",
+    value: "9",
+    slot: "slot9",
+  },
+  {
+    label: "发货/装柜日期",
+    value: "10",
+    slot: "slot10",
+  },
+  {
+    label: "ETD",
+    value: "11",
+    slot: "slot11",
+  },
+  {
+    label: "ETA",
+    value: "12",
+    slot: "slot12",
+  },
+]);
+const isShowSalesmanArrange = ref(true);
+const isShowSalesFinancemanArrange = ref(true);
+const isPurchasingManager = ref(false);
+const checkShow = () => {
+  // 当前账号角色如果不是业务总监、总经理、业务员,则不能查看
+  if (
+    !(
+      userInfo.roles.includes("salesDirector") ||
+      userInfo.roles.includes("ceo") ||
+      userInfo.roles.includes("salesman")
+    )
+  ) {
+    isShowSalesmanArrange.value = false;
+  }
+  // 当前账号角色如果不是业务总监、总经理、业务员、财务,则不能查看
+  if (
+    !(
+      userInfo.roles.includes("salesDirector") ||
+      userInfo.roles.includes("ceo") ||
+      userInfo.roles.includes("salesman") ||
+      userInfo.roles.includes("financeOfficer")
+    )
+  ) {
+    isShowSalesFinancemanArrange.value = false;
+  }
+  // 当前角色是否是采购主管
+  if (userInfo.roles.includes("purchasingOfficer")) {
+    isPurchasingManager.value = true;
+  }
+};
+checkShow();
+const arrangeInit = () => {
+  for (let i = 0; i < headerList.value.length; i++) {
+    const element = headerList.value[i];
+    if (
+      ["9", "11", "12"].includes(element.value) &&
+      !isShowSalesmanArrange.value
+    ) {
+      continue;
+    }
+    let width = 150;
+    if (element.label.length > 5) {
+      width = 250;
+    }
+    let attrs = {
+      label: element.label,
+      slot: element.slot,
+      isNeedHeaderSlot: true,
+      headerSlot: element.value,
+      "min-width": width,
+    };
+    config.value.push({
+      attrs,
+    });
+  }
+  let attrs = {
+    label: "尾款金额",
+    slot: "balanceMoney",
+    isNeedHeaderSlot: false,
+    width: 120,
+  };
+  if (isShowSalesmanArrange.value) {
+    config.value.push({
+      attrs,
+    });
+  }
+};
+arrangeInit();
+const headerData = ref({});
+const getHeaderData = () => {
+  proxy
+    .post("/contractDocumentary/getSumCount", sourceList.value.pagination)
+    .then((res) => {
+      headerData.value = res;
+    });
+};
+getDict();
+
+if (route.query.currentContractId) {
+  sourceList.value.pagination.id = route.query.currentContractId;
+}
+getList();
+
+const formData = reactive({
+  remarksFormData: {},
+  recordsFormData: {},
+  filesFormData: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const remarksFormConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      prop: "documentaryRemark",
+      label: "备注内容",
+      itemType: "textarea",
+      disabled: false,
+    },
+    {
+      type: "slot",
+      slotName: "file",
+      label: "上传附件",
+    },
+  ];
+});
+const remarksRules = ref({
+  documentaryRemark: [
+    { required: true, message: "请输入备注内容", trigger: "blur" },
+  ],
+});
+const formLoading = ref(false);
+const openRemarks = ref(false);
+const remarksForm = ref(null);
+const handleClickLookRemarks = () => {
+  formData.remarksFormData = {
+    businessId: contractData.value.id,
+    content: "",
+    businessType: "0",
+    documentaryRemark: "",
+    documentaryType: "0",
+    fileList: [],
+  };
+  openRemarks.value = true;
+};
+const submitRemarks = () => {
+  remarksForm.value.handleSubmit(() => {
+    formLoading.value = true;
+    formData.remarksFormData.fileList = formData.remarksFormData.fileList.map(
+      (item) => {
+        return {
+          id: item.raw.id,
+          fileName: item.raw.fileName,
+          fileUrl: item.raw.fileUrl,
+          uploadState: item.raw.uploadState,
+        };
+      }
+    );
+    proxy
+      .post("/contractDocumentary/add", formData.remarksFormData)
+      .then((res) => {
+        ElMessage({
+          message: "操作成功",
+          type: "success",
+        });
+        getRemarkRecordsData();
+        formLoading.value = false;
+        openRemarks.value = false;
+      });
+  });
+};
+const openRemarkRecords = ref(false);
+const remarkRecordsData = ref([]);
+const getRemarkRecordsData = () => {
+  proxy
+    .post("/contractDocumentary/page", {
+      businessId: contractData.value.id,
+      documentaryType: "0",
+    })
+    .then((res) => {
+      remarkRecordsData.value = res.rows;
+      const idList = remarkRecordsData.value.map((x) => x.id);
+      // 请求文件数据并回显
+      if (idList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: idList,
+          })
+          .then((fileObj) => {
+            if (fileObj) {
+              for (let i = 0; i < remarkRecordsData.value.length; i++) {
+                const e = remarkRecordsData.value[i];
+                for (const key in fileObj) {
+                  if (e.id === key) {
+                    e.fileList = fileObj[key];
+                  }
+                }
+              }
+            }
+          });
+      }
+    });
+};
+const handleClickLookRemarksRecords = (row) => {
+  contractData.value = row;
+  openRemarkRecords.value = true;
+  getRemarkRecordsData();
+};
+// 上传文件
+const uploadFile = async (file) => {
+  const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
+  uploadData.value = res.uploadBody;
+  file.id = res.id;
+  file.fileName = res.fileName;
+  file.fileUrl = res.fileUrl;
+  file.uploadState = true;
+  return true;
+};
+const handleSuccess = (any, UploadFile) => {
+  UploadFile.raw.uploadState = false;
+};
+const onPreviewFile = (file) => {
+  window.open(file.raw.fileUrl, "_blank");
+};
+// 记录
+const selectNode = ref({});
+const contractData = ref({});
+const purchaseData = ref({});
+const openRecords = ref(false);
+const openAddRecords = ref(false);
+const recordsLoading = ref(false);
+const recordsData = ref([]);
+const recordsForm = ref(null);
+const recordsFormConfig = ref([]);
+const recordsRules = ref({
+  documentaryTime: [
+    { required: true, message: "请选择跟单时间", trigger: "change" },
+  ],
+  documentaryRemark: [
+    { required: true, message: "请输入跟单记录", trigger: "blur" },
+  ],
+  content: [{ required: true, message: "请选择", trigger: "change" }],
+});
+const getRecordsData = () => {
+  proxy
+    .post("/contractDocumentary/page", {
+      businessId: purchaseData.value.id,
+      documentaryType: selectNode.value.value,
+    })
+    .then((res) => {
+      recordsData.value = res.rows;
+      const idList = recordsData.value.map((x) => x.id);
+      // 请求文件数据并回显
+      if (idList.length > 0) {
+        proxy
+          .post("/fileInfo/getList", {
+            businessIdList: idList,
+          })
+          .then((fileObj) => {
+            if (fileObj) {
+              for (let i = 0; i < recordsData.value.length; i++) {
+                const e = recordsData.value[i];
+                for (const key in fileObj) {
+                  if (e.id === key) {
+                    e.fileList = fileObj[key];
+                  }
+                }
+              }
+            }
+          });
+      }
+    });
+};
+const openFile = (item) => {
+  window.open(item.fileUrl, "_blank");
+};
+const handleClickLook = (row, purchase, node) => {
+  contractData.value = row;
+  purchaseData.value = purchase;
+  selectNode.value = node;
+  openRecords.value = true;
+  getRecordsData();
+};
+const handleClickAddRecord = () => {
+  recordsRules.value.documentaryRemark = [
+    { required: true, message: "请输入跟单记录", trigger: "blur" },
+  ];
+  let type = selectNode.value.value;
+  let label = "";
+  if (type == "6") {
+    label = "验货结论";
+    delete recordsRules.value.documentaryRemark;
+  } else if (type == "8") {
+    label = "是否收到";
+  } else if (type == "10") {
+    label = "发货/装柜日期";
+  } else if (type == "11") {
+    label = "ETD日期";
+  } else if (type == "12") {
+    label = "ETA日期";
+  }
+  recordsFormConfig.value = [
+    {
+      type: "date",
+      itemType: "datetime",
+      prop: "documentaryTime",
+      label: "跟单时间",
+      disabled: false,
+    },
+    ["6", "8", "10", "11", "12"].includes(type)
+      ? {
+          type: "slot",
+          slotName: "typeSlot",
+          prop: "content",
+          label: label,
+        }
+      : {},
+    {
+      type: "input",
+      prop: "documentaryRemark",
+      label: "跟单记录",
+      itemType: "textarea",
+      disabled: false,
+    },
+    {
+      type: "slot",
+      slotName: "file",
+      label: "上传附件",
+      required: type == "6" ? true : false,
+    },
+  ];
+  formData.recordsFormData = {
+    businessId: purchaseData.value.id,
+    businessType: "1",
+    documentaryType: selectNode.value.value,
+    documentaryTime: proxy.parseTime(new Date()),
+    documentaryRemark: "",
+    content: "",
+    fileList: [],
+  };
+  openAddRecords.value = true;
+};
+
+const submitRecords = () => {
+  recordsForm.value.handleSubmit(() => {
+    if (selectNode.value.value == "6") {
+      if (!formData.recordsFormData.fileList.length > 0) {
+        return ElMessage({
+          message: "请上传附件",
+          type: "info",
+        });
+      }
+    }
+    formLoading.value = true;
+    formData.recordsFormData.fileList = formData.recordsFormData.fileList.map(
+      (item) => {
+        return {
+          id: item.raw.id,
+          fileName: item.raw.fileName,
+          fileUrl: item.raw.fileUrl,
+          uploadState: item.raw.uploadState,
+        };
+      }
+    );
+    proxy
+      .post("/contractDocumentary/add", formData.recordsFormData)
+      .then((res) => {
+        ElMessage({
+          message: "操作成功",
+          type: "success",
+        });
+        getRecordsData();
+        getList();
+
+        formLoading.value = false;
+        openAddRecords.value = false;
+      });
+  });
+};
+// 交接单
+const openFiles = ref(false);
+const fileTitle = ref("");
+const filesFormConfig = computed(() => {
+  return [
+    {
+      type: "slot",
+      slotName: "file",
+      label: "附件",
+    },
+  ];
+});
+const handleClickLookContractFile = (row, flag) => {
+  let id = row.id;
+  fileTitle.value = flag ? "交接单" : "包装指示";
+  openFiles.value = true;
+  formData.filesFormData = {
+    fileList: [],
+  };
+  proxy
+    .post("/fileInfo/getList", {
+      businessIdList: [id],
+    })
+    .then((fileObj) => {
+      if (fileObj[id] && fileObj[id].length > 0) {
+        if (flag) {
+          formData.filesFormData.fileList = fileObj[id]
+            .filter((x) => x.businessType === "1")
+            .map((x) => ({ raw: x, name: x.fileName, url: x.fileUrl }));
+        } else {
+          formData.filesFormData.fileList = fileObj[id]
+            .filter((x) => x.businessType === "2")
+            .map((x) => ({ raw: x, name: x.fileName, url: x.fileUrl }));
+        }
+      }
+    });
+};
+
+const openDetails = (row) => {
+  // currentContractId.value = row.id;
+  // openDetailsDialog.value = true;
+  // 新页面打开方式
+  // const page = proxy.$router.resolve({
+  //   name: "contractDetails",
+  //   query: {
+  //     currentContractId: row.id,
+  //   },
+  // });
+  // window.open(page.href, "_blank");
+  if (!isPurchasingManager.value) {
+    proxy.$router.push({
+      name: "contractDetails",
+      query: {
+        currentContractId: row.id,
+      },
+    });
+  }
+};
+
+const clickCorporationName = (row) => {
+  proxy.$router.push({
+    name: "Portrait",
+    query: {
+      id: row.buyCorporationId,
+    },
+  });
+};
+
+const judgeHaveData = (purchase, documentaryType) => {
+  if (purchase.purchaseDocumentary && purchase.purchaseDocumentary.length > 0) {
+    const list = purchase.purchaseDocumentary.filter(
+      (x) => x.documentaryType == documentaryType
+    );
+    return list.length ? true : false;
+  } else {
+    return false;
+  }
+};
+
+const judgeHaveDataOne = (purchase, documentaryType) => {
+  if (purchase.purchaseDocumentary && purchase.purchaseDocumentary.length > 0) {
+    const list = purchase.purchaseDocumentary.filter(
+      (x) => x.documentaryType == documentaryType
+    );
+    if (list && list.length > 0) {
+      list.sort((a, b) => {
+        return (
+          new Date(b.documentaryTime).getTime() -
+          new Date(a.documentaryTime).getTime()
+        );
+      });
+      if (["6", "8"].includes(documentaryType)) {
+        return Number(list[0].content);
+      } else {
+        return list[0].content;
+      }
+    }
+  }
+};
+
+const currentHeader = ref("");
+const clickNum = ref(0);
+const handleClickHeader = (type) => {
+  if (currentHeader.value && currentHeader.value != type) {
+    clickNum.value = 0;
+    clickNum.value++;
+  } else {
+    clickNum.value++;
+    if (clickNum.value > 2) {
+      clickNum.value = 0;
+    }
+  }
+  currentHeader.value = type;
+  sourceList.value.pagination.documentaryType = type;
+  sourceList.value.pagination.documentarySearch = clickNum.value;
+  getList();
+};
+
+const hdanlePushPurchase = (code) => {
+  proxy.$router.push({
+    name: "Purchased",
+    query: {
+      code: code,
+    },
+  });
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+.public-class {
+  color: #409eff;
+  cursor: pointer;
+  word-break: break-all;
+}
+.headerSlot {
+  margin-left: 10px;
+  font-size: 14px;
+  color: #409eff;
+  cursor: pointer;
+}
+.hidden-text {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  cursor: pointer;
+}
+</style>

+ 926 - 0
src/components/detailCom/profitBudgetEHSD/index.vue

@@ -0,0 +1,926 @@
+<template>
+  <div class="tenant">
+    <byTable
+      :hideTable="true"
+      :hidePagination="true"
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      highlight-current-row
+      :action-list="[]"
+      :hideSearch="true"
+      @get-list="getList"
+    >
+    </byTable>
+    <div
+      style="padding: 0 20px 20px 20px; background-color: white"
+      v-if="rateStatus"
+    >
+      <el-table :data="sourceList.data">
+        <el-table-column label="合同编号" prop="code" width="160" fixed />
+        <el-table-column
+          label="客户名称"
+          prop="customerName"
+          min-width="200"
+          fixed
+        />
+        <el-table-column label="业务员" prop="userName" width="140" fixed />
+        <el-table-column label="合同金额" width="140">
+          <template #default="{ row }">
+            <div>{{ row.currency }} {{ row.amount }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="应付货款" width="140">
+          <template #default="{ row }">
+            <div>
+              <span v-if="row.otherSumAmount">{{ row.otherSumAmount }}</span>
+              <span v-else>{{ row.ehsdSumAmount }}</span>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="税率" width="140">
+          <template #default="{ row }">
+            <div>13%</div>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="应退税金额"
+          prop="refundableAmount"
+          width="140"
+        />
+        <el-table-column label="包材金额" width="140">
+          <template #default="{ row }">
+            <div>{{ row.peritectoidAmount }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="配件金额" width="140">
+          <template #default="{ row }">
+            <div>{{ row.accessoriesAmount }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="拖车费" width="140">
+          <template #default="{ row }">
+            <div>{{ row.trailerFee }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="报关费" width="140">
+          <template #default="{ row }">
+            <div>{{ row.customsFee }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="代理费" width="140">
+          <template #default="{ row }">
+            <div>{{ row.agencyFee }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="港杂费" width="140">
+          <template #default="{ row }">
+            <div>{{ row.portMixedFee }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="验货红包" width="140">
+          <template #default="{ row }">
+            <div>
+              {{ row.inspectionRedPack }}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="佣金" width="140">
+          <template #default="{ row }">
+            <div>{{ row.commission }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="其他" width="140">
+          <template #default="{ row }">
+            <div>{{ row.other }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="收入总计" prop="incomeAmount" width="140" />
+        <el-table-column
+          label="支出总计"
+          prop="expenditureAmount"
+          width="140"
+        />
+        <el-table-column label="毛利率" width="140">
+          <template #default="{ row }">
+            <div>{{ parseFloat(row.grossRate).toFixed(2) }}%</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="毛利" prop="gross" width="140" />
+      </el-table>
+      <!-- <el-row style="padding: 20px" justify="end" type="flex">
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :current-page="sourceList.pagination.pageNum"
+          :page-size="sourceList.pagination.pageSize"
+          :total="sourceList.pagination.total"
+          @size-change="handleSizeChange"
+          @current-change="handlePageChange"
+        />
+      </el-row> -->
+    </div>
+
+    <el-dialog
+      title="默认汇率"
+      v-if="dialogVisible"
+      v-model="dialogVisible"
+      width="600"
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="submit"
+      >
+        <template #currencyList>
+          <el-table
+            :data="formData.data.list"
+            style="width: 100%"
+            v-loading="loadingDialog"
+          >
+            <el-table-column label="币种">
+              <template #default="{ row }">
+                <div>{{ dictValueLabel(row.type, accountCurrency) }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column label="兑 CHY 汇率">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'list.' + $index + '.rate'"
+                  :rules="rules.rate"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    onmousewheel="return false;"
+                    v-model="row.rate"
+                    placeholder="请输入兑 CHY 汇率"
+                    style="width: 100%"
+                    :precision="6"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      title="调整汇率"
+      v-if="openChange"
+      v-model="openChange"
+      width="600"
+    >
+      <byForm
+        :formConfig="formChangeConfig"
+        :formOption="formOption"
+        v-model="formChangeData.data"
+        :rules="rules"
+        ref="change"
+      >
+        <template #currencyList>
+          <el-table
+            :data="formChangeData.data.list"
+            style="width: 100%"
+            v-loading="loadingDialog"
+          >
+            <el-table-column label="币种">
+              <template #default="{ row }">
+                <div>{{ dictValueLabel(row.type, accountCurrency) }}</div>
+              </template>
+            </el-table-column>
+            <el-table-column label="兑 CHY 汇率">
+              <template #default="{ row, $index }">
+                <el-form-item
+                  :prop="'list.' + $index + '.rate'"
+                  :rules="rules.rate"
+                  :inline-message="true"
+                >
+                  <el-input-number
+                    onmousewheel="return false;"
+                    v-model="row.rate"
+                    placeholder="请输入兑 CHY 汇率"
+                    style="width: 100%"
+                    :precision="6"
+                    :controls="false"
+                    :min="0"
+                  />
+                </el-form-item>
+              </template>
+            </el-table-column>
+          </el-table>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openChange = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitChangeForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog title="预算" v-if="openBudget" v-model="openBudget" width="400">
+      <byForm
+        :formConfig="formBudgetConfig"
+        :formOption="formOption"
+        v-model="formBudgetData.data"
+        ref="budget"
+      >
+        <template #budgetMoney>
+          <div style="width: 100%">
+            <el-form-item label="拖车费" prop="trailerFee">
+              <el-input
+                v-model="formBudgetData.data.trailerFee"
+                placeholder="请输入拖车费"
+                class="input-with-select"
+              >
+                <template #prepend>
+                  <el-select
+                    v-model="formBudgetData.data.trailerFeeCurrency"
+                    placeholder="请选择货币"
+                    style="width: 115px"
+                    disabled
+                  >
+                    <el-option
+                      v-for="(item, index) in accountCurrency"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+            <el-form-item
+              label="报关费"
+              prop="customsFee"
+              style="margin-top: 20px"
+            >
+              <el-input
+                v-model="formBudgetData.data.customsFee"
+                placeholder="请输入报关费"
+                class="input-with-select"
+              >
+                <template #prepend>
+                  <el-select
+                    v-model="formBudgetData.data.customsFeeCurrency"
+                    placeholder="请选择货币"
+                    style="width: 115px"
+                    disabled
+                  >
+                    <el-option
+                      v-for="(item, index) in accountCurrency"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+            <el-form-item
+              label="代理费"
+              prop="agencyFee"
+              style="margin-top: 20px"
+            >
+              <el-input
+                v-model="formBudgetData.data.agencyFee"
+                placeholder="请输入代理费"
+                class="input-with-select"
+              >
+                <template #prepend>
+                  <el-select
+                    v-model="formBudgetData.data.agencyFeeCurrency"
+                    placeholder="请选择货币"
+                    style="width: 115px"
+                    disabled
+                  >
+                    <el-option
+                      v-for="(item, index) in accountCurrency"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+            <el-form-item
+              label="港杂费"
+              prop="portMixedFee"
+              style="margin-top: 20px"
+            >
+              <el-input
+                v-model="formBudgetData.data.portMixedFee"
+                placeholder="请输入港杂费"
+                class="input-with-select"
+              >
+                <template #prepend>
+                  <el-select
+                    v-model="formBudgetData.data.portMixedFeeCurrency"
+                    placeholder="请选择货币"
+                    style="width: 115px"
+                    disabled
+                  >
+                    <el-option
+                      v-for="(item, index) in accountCurrency"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+            <el-form-item
+              label="验货红包"
+              prop="inspectionRedPack"
+              style="margin-top: 20px"
+            >
+              <el-input
+                v-model="formBudgetData.data.inspectionRedPack"
+                placeholder="请输入验货红包"
+                class="input-with-select"
+              >
+                <template #prepend>
+                  <el-select
+                    v-model="formBudgetData.data.inspectionRedPackCurrency"
+                    placeholder="请选择货币"
+                    style="width: 115px"
+                    disabled
+                  >
+                    <el-option
+                      v-for="(item, index) in accountCurrency"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+            <el-form-item
+              label="佣金"
+              prop="commission"
+              style="margin-top: 20px"
+            >
+              <el-input
+                v-model="formBudgetData.data.commission"
+                placeholder="请输入佣金"
+                class="input-with-select"
+              >
+                <template #prepend>
+                  <el-select
+                    v-model="formBudgetData.data.commissionCurrency"
+                    placeholder="请选择货币"
+                    style="width: 115px"
+                    disabled
+                  >
+                    <el-option
+                      v-for="(item, index) in accountCurrency"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+            <el-form-item label="其他" prop="other" style="margin-top: 20px">
+              <el-input
+                v-model="formBudgetData.data.other"
+                placeholder="请输入其他"
+                class="input-with-select"
+              >
+                <template #prepend>
+                  <el-select
+                    v-model="formBudgetData.data.otherCurrency"
+                    placeholder="请选择货币"
+                    style="width: 115px"
+                    disabled
+                  >
+                    <el-option
+                      v-for="(item, index) in accountCurrency"
+                      :key="index"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </template>
+              </el-input>
+            </el-form-item>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openBudget = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitBudgetForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      :title="'高级检索'"
+      v-model="moreSearchDialog"
+      width="500px"
+      destroy-on-close
+    >
+      <byForm
+        :formConfig="formSearchConfig"
+        :formOption="formOption"
+        v-model="sourceList.pagination"
+      >
+      </byForm>
+      <template #footer>
+        <el-button @click="moreSearchReset" size="large">重置</el-button>
+        <el-button @click="moreSearchQuery" type="primary" size="large"
+          >搜索</el-button
+        >
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import useUserStore from "@/store/modules/user";
+import { ElMessage } from "element-plus";
+import { useRoute } from "vue-router";
+const route = useRoute();
+const { proxy } = getCurrentInstance();
+const accountCurrency = ref([]);
+const userList = ref([]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    userId: "",
+    userName: "",
+    contractCode: "",
+    customerName: "",
+    beginTime: "",
+    endTime: "",
+    id: "",
+  },
+});
+const props = defineProps({
+  contractId: String,
+});
+const loading = ref(false);
+
+const config = computed(() => {
+  return [];
+});
+const headerData = ref({});
+
+const getDict = () => {
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "account_currency",
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        accountCurrency.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+        judgeRate();
+      } else {
+        ElMessage("请先添加货币");
+      }
+    });
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+};
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/contract/getProfitBudgetPage", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+  proxy
+    .post("/contract/getProfitBudgetHeadStatistic", sourceList.value.pagination)
+    .then((res) => {
+      headerData.value = res;
+    });
+};
+const rateStatus = ref(false);
+const judgeRate = () => {
+  proxy.post("/currencyRate/list", {}).then(
+    (res) => {
+      if (res && res.length > 0) {
+        for (let i = 0; i < accountCurrency.value.length; i++) {
+          let currencyStatus = true;
+          for (let j = 0; j < res.length; j++) {
+            if (accountCurrency.value[i].value === res[j].type) {
+              currencyStatus = false;
+              break;
+            }
+          }
+          if (currencyStatus) {
+            return ElMessage("请先完成默认汇率的配置");
+          }
+        }
+        rateStatus.value = true;
+        if (route.query.currentContractId) {
+          sourceList.value.pagination.id = route.query.currentContractId;
+        }
+        getList();
+      } else {
+        ElMessage("请先完成默认汇率的配置");
+      }
+    },
+    (err) => {
+      console.log(err);
+      ElMessage("请先完成默认汇率的配置");
+    }
+  );
+};
+getDict();
+const handleSizeChange = (val) => {
+  sourceList.value.pagination.pageNum = 1;
+  sourceList.value.pagination.pageSize = val;
+  getList();
+};
+const handlePageChange = (val) => {
+  sourceList.value.pagination.pageNum = val;
+  getList();
+};
+const dialogVisible = ref(false);
+const loadingDialog = ref(false);
+const submit = ref(null);
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formData = reactive({
+  data: {
+    list: [],
+  },
+});
+const formConfig = computed(() => {
+  return [
+    {
+      type: "slot",
+      prop: "currencyList",
+      slotName: "currencyList",
+      label: "",
+    },
+  ];
+});
+const rules = ref({
+  rate: [{ required: true, message: "请输入兑 CHY 汇率", trigger: "blur" }],
+});
+const openModal = () => {
+  if (accountCurrency.value && accountCurrency.value.length > 0) {
+    formData.data = {
+      list: accountCurrency.value.map((item) => {
+        return {
+          id: "",
+          type: item.value,
+          rate: 1,
+        };
+      }),
+    };
+  } else {
+    formData.data = {
+      list: [],
+    };
+  }
+  loadingDialog.value = true;
+  dialogVisible.value = true;
+  proxy.post("/currencyRate/list", {}).then(
+    (res) => {
+      if (res && res.length > 0 && formData.data.list.length > 0) {
+        formData.data.list = formData.data.list.map((item) => {
+          for (let i = 0; i < res.length; i++) {
+            if (item.type === res[i].type) {
+              item.id = res[i].id;
+              item.rate = res[i].rate;
+              break;
+            }
+          }
+          return {
+            ...item,
+          };
+        });
+      }
+      loadingDialog.value = false;
+    },
+    (err) => {
+      console.log(err);
+      loadingDialog.value = false;
+    }
+  );
+};
+const submitForm = () => {
+  submit.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    proxy.post("/currencyRate/edit", formData.data.list).then(
+      () => {
+        ElMessage({
+          message: "保存成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        rateStatus.value = true;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+  });
+};
+const openChange = ref(false);
+const change = ref(null);
+const formChangeData = reactive({
+  data: {
+    list: [],
+  },
+});
+const formChangeConfig = computed(() => {
+  return [
+    {
+      type: "slot",
+      prop: "currencyList",
+      slotName: "currencyList",
+      label: "",
+    },
+  ];
+});
+const changeExchangeRate = (row) => {
+  formChangeData.data = {
+    id: row.contractId,
+    list: [],
+  };
+  if (accountCurrency.value && accountCurrency.value.length > 0) {
+    formChangeData.data.list = accountCurrency.value.map((item) => {
+      return {
+        type: item.value,
+        rate: 1,
+      };
+    });
+  }
+  loadingDialog.value = true;
+  openChange.value = true;
+  if (row.currencyRateJson) {
+    let currencyRateJson = JSON.parse(row.currencyRateJson);
+    formChangeData.data.list = formChangeData.data.list.map((item) => {
+      for (let i = 0; i < currencyRateJson.length; i++) {
+        if (item.type === currencyRateJson[i].type) {
+          item.rate = currencyRateJson[i].rate;
+          break;
+        }
+      }
+      return {
+        ...item,
+      };
+    });
+    loadingDialog.value = false;
+  } else {
+    proxy.post("/currencyRate/list", {}).then(
+      (res) => {
+        if (res && res.length > 0 && formChangeData.data.list.length > 0) {
+          formChangeData.data.list = formChangeData.data.list.map((item) => {
+            for (let i = 0; i < res.length; i++) {
+              if (item.type === res[i].type) {
+                item.rate = res[i].rate;
+                break;
+              }
+            }
+            return {
+              ...item,
+            };
+          });
+        }
+        loadingDialog.value = false;
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+  }
+};
+const submitChangeForm = () => {
+  change.value.handleSubmit(() => {
+    loadingDialog.value = true;
+    let data = {};
+    data.id = formChangeData.data.id;
+    data.currencyRateJson = JSON.stringify(formChangeData.data.list);
+    proxy.post("/contract/edit", data).then(
+      () => {
+        ElMessage({
+          message: "保存成功",
+          type: "success",
+        });
+        openChange.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        loadingDialog.value = false;
+      }
+    );
+  });
+};
+const openBudget = ref(false);
+const budget = ref(null);
+const formBudgetData = reactive({
+  data: {},
+});
+const formBudgetConfig = computed(() => {
+  return [
+    {
+      type: "title",
+      title: "合同信息",
+      label: "",
+    },
+    {
+      type: "input",
+      prop: "code",
+      label: "合同编号",
+      itemType: "text",
+      disabled: true,
+    },
+    {
+      type: "input",
+      prop: "customerName",
+      label: "客户名称",
+      itemType: "text",
+      disabled: true,
+    },
+    {
+      type: "input",
+      prop: "userName",
+      label: "业务员",
+      itemType: "text",
+      disabled: true,
+    },
+    {
+      type: "title",
+      title: "预算金额",
+      label: "",
+    },
+    {
+      type: "slot",
+      slotName: "budgetMoney",
+      label: "",
+    },
+  ];
+});
+const changeBudget = (row) => {
+  let currency = "CNY";
+  if (accountCurrency.value && accountCurrency.value.length > 0) {
+    currency = accountCurrency.value[0].value;
+  }
+  formBudgetData.data = {
+    contractId: row.contractId,
+    code: row.code,
+    customerName: row.customerName,
+    userName: row.userName,
+    trailerFeeCurrency: currency,
+    trailerFee: row.trailerFee,
+    customsFeeCurrency: currency,
+    customsFee: row.customsFee,
+    agencyFeeCurrency: currency,
+    agencyFee: row.agencyFee,
+    portMixedFeeCurrency: currency,
+    portMixedFee: row.portMixedFee,
+    inspectionRedPackCurrency: currency,
+    inspectionRedPack: row.inspectionRedPack,
+    commissionCurrency: currency,
+    commission: row.commission,
+    otherCurrency: currency,
+    other: row.other,
+  };
+  openBudget.value = true;
+};
+const submitBudgetForm = () => {
+  proxy.post("/contractBudget/budget", formBudgetData.data).then(() => {
+    ElMessage({
+      message: "保存成功",
+      type: "success",
+    });
+    openBudget.value = false;
+    getList();
+  });
+};
+
+const formSearchConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      label: "业务员",
+      prop: "userName",
+      itemWidth: 100,
+    },
+    {
+      type: "input",
+      label: "合同编号",
+      prop: "contractCode",
+      itemWidth: 100,
+    },
+    {
+      type: "input",
+      label: "客户名称",
+      prop: "customerName",
+      itemWidth: 100,
+    },
+    {
+      type: "date",
+      itemType: "datetime",
+      label: "合同时间",
+      prop: "beginTime",
+      placeholder: "合同开始时间",
+      itemWidth: 50,
+      clearable: true,
+    },
+    {
+      type: "date",
+      itemType: "datetime",
+      label: " ",
+      prop: "endTime",
+      placeholder: "合同结束时间",
+      itemWidth: 50,
+      clearable: true,
+    },
+  ];
+});
+const moreSearchDialog = ref(false);
+const clickMoreSearch = () => {
+  moreSearchDialog.value = true;
+};
+const moreSearchQuery = () => {
+  moreSearchDialog.value = false;
+  getList();
+};
+const moreSearchReset = () => {
+  sourceList.value.pagination = {
+    total: 0,
+    pageNum: sourceList.value.pagination.pageNum,
+    pageSize: sourceList.value.pagination.pageSize,
+    keyword: "",
+    userId: "",
+    userName: "",
+    contractCode: "",
+    customerName: "",
+    beginTime: "",
+    endTime: "",
+  };
+  moreSearchQuery();
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 401 - 0
src/components/detailCom/profitSettlementEHSD/index.vue

@@ -0,0 +1,401 @@
+<template>
+  <div class="tenant">
+    <byTable
+      :hideTable="true"
+      :hidePagination="true"
+      :source="sourceList.data"
+      :pagination="sourceList.pagination"
+      :config="config"
+      :loading="loading"
+      :hideSearch="true"
+      highlight-current-row
+      @get-list="getList"
+    >
+    </byTable>
+    <div style="padding: 0 20px 20px 20px; background-color: white">
+      <el-table v-loading="loading" :data="sourceList.data">
+        <el-table-column label="合同编号" prop="code" width="160" fixed />
+        <el-table-column
+          label="客户名称"
+          prop="customerName"
+          min-width="200"
+          fixed
+        />
+        <el-table-column label="业务员" prop="userName" width="140" fixed />
+        <el-table-column label="合同金额" width="140">
+          <template #default="{ row }">
+            <div>{{ row.amount }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="收入">
+          <el-table-column label="到账金额" prop="sumClaimMoney" width="140" />
+          <el-table-column
+            label="退税金额"
+            prop="refundableAmount"
+            width="140"
+          />
+          <el-table-column
+            label="其他收入"
+            prop="otherIncomeAmount"
+            width="140"
+          />
+        </el-table-column>
+        <el-table-column
+          label="采购合同金额"
+          prop="sumPurchaseContractMoney"
+          width="140"
+        />
+        <el-table-column label="支出">
+          <el-table-column label="已付货款" prop="accountPaid" width="140" />
+          <el-table-column label="代理费" prop="agencyFee" width="140" />
+          <el-table-column label="拖车费" prop="trailerFee" width="140" />
+          <el-table-column label="报关费" prop="customsFee" width="140" />
+          <el-table-column label="港杂费" prop="portMixedFee" width="140" />
+          <el-table-column
+            label="验货红包"
+            prop="inspectionRedPack"
+            width="140"
+          />
+          <el-table-column label="佣金" prop="commission" width="140" />
+          <el-table-column label="检测费" prop="checkout" width="140" />
+          <el-table-column label="验货费" prop="inspectionCharge" width="140" />
+          <el-table-column label="运费" prop="freight" width="140" />
+          <el-table-column
+            label="产地证费"
+            prop="certificateOfOrigin"
+            width="140"
+          />
+          <el-table-column label="其他" prop="other" width="140" />
+        </el-table-column>
+        <el-table-column label="备注" prop="remark" width="200" />
+        <el-table-column label="统计">
+          <el-table-column label="收入合计" prop="incomeAmount" width="140" />
+          <el-table-column
+            label="支出合计"
+            prop="expenditureAmount"
+            width="140"
+          />
+          <el-table-column label="毛利" prop="gross" width="140" />
+          <el-table-column label="毛利率" width="140">
+            <template #default="{ row }">
+              <div>{{ row.grossRate }}%</div>
+            </template>
+          </el-table-column>
+        </el-table-column>
+      </el-table>
+      <!-- <el-row style="padding: 20px" justify="end" type="flex">
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :current-page="sourceList.pagination.pageNum"
+          :page-size="sourceList.pagination.pageSize"
+          :total="sourceList.pagination.total"
+          @size-change="handleSizeChange"
+          @current-change="handlePageChange"
+        />
+      </el-row> -->
+    </div>
+
+    <el-dialog
+      title="代理费"
+      v-if="openAgencyFee"
+      v-model="openAgencyFee"
+      width="400"
+    >
+      <byForm
+        :formConfig="formAgencyFeeConfig"
+        :formOption="formOption"
+        v-model="formAgencyFeeData.data"
+        ref="agencyFee"
+      >
+        <template #agencyFee>
+          <div style="width: 100%">
+            <el-form-item label="代理费" prop="agencyFee">
+              <el-input-number
+                onmousewheel="return false;"
+                v-model="formAgencyFeeData.data.agencyFee"
+                :precision="2"
+                :controls="false"
+                :min="0"
+              />
+            </el-form-item>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openAgencyFee = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitAgencyFeeForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog title="备注" v-if="openRemark" v-model="openRemark" width="400">
+      <byForm
+        :formConfig="formRemarkConfig"
+        :formOption="formOption"
+        v-model="formRemarkData.data"
+        ref="remark"
+      >
+        <template #remark>
+          <div style="width: 100%">
+            <el-form-item label="备注" prop="remark">
+              <el-input
+                v-model="formRemarkData.data.remark"
+                :rows="4"
+                type="textarea"
+              />
+            </el-form-item>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="openRemark = false" size="large">取 消</el-button>
+        <el-button type="primary" @click="submitRemarkForm()" size="large"
+          >确 定</el-button
+        >
+      </template>
+    </el-dialog>
+
+    <el-dialog
+      :title="'高级检索'"
+      v-model="moreSearchDialog"
+      width="500px"
+      destroy-on-close
+    >
+      <byForm
+        :formConfig="formSearchConfig"
+        :formOption="formOption"
+        v-model="sourceList.pagination"
+      >
+      </byForm>
+      <template #footer>
+        <el-button @click="moreSearchReset" size="large">重置</el-button>
+        <el-button @click="moreSearchQuery" type="primary" size="large"
+          >搜索</el-button
+        >
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import useUserStore from "@/store/modules/user";
+import { ElMessage } from "element-plus";
+import { useRoute } from "vue-router";
+const route = useRoute();
+const { proxy } = getCurrentInstance();
+const accountCurrency = ref([]);
+const props = defineProps({
+  contractId: String,
+});
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    userId: "",
+    userName: "",
+    contractCode: "",
+    customerName: "",
+    beginTime: "",
+    endTime: "",
+    id: "",
+  },
+});
+const loading = ref(false);
+const config = computed(() => {
+  return [];
+});
+const getDict = () => {
+  proxy
+    .post("/dictTenantData/page", {
+      pageNum: 1,
+      pageSize: 999,
+      dictCode: "account_currency",
+      tenantId: useUserStore().user.tenantId,
+      total: "1",
+    })
+    .then((res) => {
+      if (res.rows && res.rows.length > 0) {
+        accountCurrency.value = res.rows.map((item) => {
+          return {
+            label: item.dictValue,
+            value: item.dictKey,
+          };
+        });
+      }
+    });
+};
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/contract/getProfitClearingPage", sourceList.value.pagination)
+    .then((res) => {
+      sourceList.value.data = res.rows;
+      sourceList.value.pagination.total = res.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+getDict();
+if (route.query.currentContractId) {
+  sourceList.value.pagination.id = route.query.currentContractId;
+}
+getList();
+const handleSizeChange = (val) => {
+  sourceList.value.pagination.pageNum = 1;
+  sourceList.value.pagination.pageSize = val;
+  getList();
+};
+const handlePageChange = (val) => {
+  sourceList.value.pagination.pageNum = val;
+  getList();
+};
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const openAgencyFee = ref(false);
+const agencyFee = ref(null);
+const formAgencyFeeData = reactive({
+  data: {},
+});
+const formAgencyFeeConfig = computed(() => {
+  return [
+    {
+      type: "slot",
+      slotName: "agencyFee",
+    },
+  ];
+});
+const changeAgencyFee = (row) => {
+  formAgencyFeeData.data = {
+    id: row.id,
+    agencyFee: row.agencyFee,
+  };
+  openAgencyFee.value = true;
+};
+const submitAgencyFeeForm = () => {
+  proxy.post("/contract/edit", formAgencyFeeData.data).then(() => {
+    ElMessage({
+      message: "保存成功",
+      type: "success",
+    });
+    openAgencyFee.value = false;
+    getList();
+  });
+};
+const openRemark = ref(false);
+const remark = ref(null);
+const formRemarkData = reactive({
+  data: {},
+});
+const formRemarkConfig = computed(() => {
+  return [
+    {
+      type: "slot",
+      slotName: "remark",
+    },
+  ];
+});
+const changeRemark = (row) => {
+  formRemarkData.data = {
+    id: row.id,
+    remark: row.remark,
+  };
+  openRemark.value = true;
+};
+const submitRemarkForm = () => {
+  proxy.post("/contract/edit", formRemarkData.data).then(() => {
+    ElMessage({
+      message: "保存成功",
+      type: "success",
+    });
+    openRemark.value = false;
+    getList();
+  });
+};
+
+const formSearchConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      label: "业务员",
+      prop: "userName",
+      itemWidth: 100,
+    },
+    {
+      type: "input",
+      label: "合同编号",
+      prop: "contractCode",
+      itemWidth: 100,
+    },
+    {
+      type: "input",
+      label: "客户名称",
+      prop: "customerName",
+      itemWidth: 100,
+    },
+    {
+      type: "date",
+      itemType: "datetime",
+      label: "合同时间",
+      prop: "beginTime",
+      placeholder: "合同开始时间",
+      itemWidth: 50,
+      clearable: true,
+    },
+    {
+      type: "date",
+      itemType: "datetime",
+      label: " ",
+      prop: "endTime",
+      placeholder: "合同结束时间",
+      itemWidth: 50,
+      clearable: true,
+    },
+  ];
+});
+const moreSearchDialog = ref(false);
+const clickMoreSearch = () => {
+  moreSearchDialog.value = true;
+};
+const moreSearchQuery = () => {
+  moreSearchDialog.value = false;
+  getList();
+};
+const moreSearchReset = () => {
+  sourceList.value.pagination = {
+    total: 0,
+    pageNum: sourceList.value.pagination.pageNum,
+    pageSize: sourceList.value.pagination.pageSize,
+    keyword: "",
+    userId: "",
+    userName: "",
+    contractCode: "",
+    customerName: "",
+    beginTime: "",
+    endTime: "",
+  };
+  moreSearchQuery();
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 3 - 0
src/views/process/processApproval/index.vue

@@ -215,6 +215,9 @@
       width="400"
       v-model="dialogVisible"
       v-if="dialogVisible"
+      :show-close="false"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
     >
       <el-form :model="flowForm">
         <el-form-item prop="remark" label="处理人">

+ 5 - 3
src/views/salesMange/shipmentMange/packing/index.vue

@@ -932,21 +932,23 @@
                   v-if="indexTwo === 0"
                   :rowspan="item.packDetailProductLists.length"
                 >
-                  {{ item.netWeight }}
+                  {{ item.netWeight * item.packQuantity }}
                 </td>
                 <td
                   style="text-align: center; width: 10%"
                   v-if="indexTwo === 0"
                   :rowspan="item.packDetailProductLists.length"
                 >
-                  {{ item.roughWeight }}
+                  {{ item.roughWeight * item.packQuantity }}
                 </td>
                 <td
                   style="text-align: center; width: 10%"
                   v-if="indexTwo === 0"
                   :rowspan="item.packDetailProductLists.length"
                 >
-                  {{ (item.bomVolume / 1000000).toFixed(4) }}
+                  {{
+                    (item.bomVolume / 1000000).toFixed(4) * item.packQuantity
+                  }}
                 </td>
               </tr>
             </template>