contractPDFOne.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. <template>
  2. <div>
  3. <div
  4. id="pdfDom"
  5. ref="pdfDom"
  6. style="padding: 30px 60px"
  7. v-loading="loading"
  8. >
  9. <table border="1" style="width: 100%" class="table">
  10. <tr>
  11. <td style="width: 120px">
  12. <img
  13. :src="pdfData.companyPic"
  14. alt=""
  15. fit="scale-down"
  16. style="height: 60px; width: 60px"
  17. />
  18. </td>
  19. <td style="padding: 10px">
  20. <div style="font-size: 18px" class="color-class">
  21. {{ pdfData.sellCorporationNameEn }}
  22. </div>
  23. <div style="font-size: 18px" class="color-class">
  24. {{ pdfData.sellCorporationName }}
  25. </div>
  26. <div style="font-size: 14px; color: #000">
  27. Address: {{ pdfData.sellDetailedAddressEn }}
  28. </div>
  29. <div style="font-size: 14px; color: #000; margin-top: 5px">
  30. {{ pdfData.sellCityNameEn }} , {{ pdfData.sellProvinceNameEn }} ,
  31. {{ pdfData.sellCountryNameEn }}
  32. </div>
  33. <div style="font-size: 14px; color: #000; margin-top: 10px">
  34. 地址: {{ pdfData.sellCountryName }} ,
  35. {{ pdfData.sellProvinceName }} , {{ pdfData.sellCityName }}
  36. </div>
  37. <div style="font-size: 14px; color: #000; margin-top: 5px">
  38. {{ pdfData.sellDetailedAddress }}
  39. </div>
  40. <div style="margin: 8px 0; color: black">
  41. Tel: <span>{{ pdfData.sellContactNumber }}</span>
  42. <!-- Fax:
  43. <span>{{ pdfData.fax }}</span>
  44. Website:
  45. <span>{{ pdfData.Website }}</span> -->
  46. </div>
  47. </td>
  48. </tr>
  49. <tr>
  50. <td colspan="2">
  51. <div
  52. class="color-class"
  53. style="text-align: center; font-size: 18px"
  54. >
  55. Proforma Invoice
  56. </div>
  57. </td>
  58. </tr>
  59. </table>
  60. <div style="height: 15px; background: #7f197f"></div>
  61. <table border="1" style="width: 100%" class="table">
  62. <tr>
  63. <td style="width: 50%; text-align: left">
  64. Buyer: {{ pdfData.buyCorporationName }}
  65. </td>
  66. <td style="width: 50%; text-align: left">
  67. Seller: {{ pdfData.sellCorporationNameEn }}
  68. </td>
  69. </tr>
  70. </table>
  71. <table border="1" style="width: 100%; border-top: none" class="table">
  72. <tr>
  73. <td style="width: 15%">PI No.</td>
  74. <td style="width: 35%">{{ pdfData.contractCode }}</td>
  75. <td style="width: 15%">Date:</td>
  76. <td style="width: 35%">{{ pdfData.createTimeEn }}</td>
  77. </tr>
  78. <tr>
  79. <!-- 客户合同号 -->
  80. <td style="width: 15%">PO No.</td>
  81. <td style="width: 35%"></td>
  82. <td style="width: 15%">Loading Port:</td>
  83. <td style="width: 35%">{{ pdfData.transportRemark }}</td>
  84. </tr>
  85. </table>
  86. <div style="height: 15px; background: #7f197f"></div>
  87. <table border="1" style="width: 100%" class="table">
  88. <tr>
  89. <td style="width: 15%">Image</td>
  90. <td style="width: 20%">Description</td>
  91. <td style="width: 15%">Size</td>
  92. <td style="width: 12%">Packaging</td>
  93. <td style="width: 12%">
  94. Order <br />
  95. Quantity
  96. </td>
  97. <td style="width: 13%">Unit <br />Price</td>
  98. <td style="width: 13%">Total <br />Amount</td>
  99. </tr>
  100. <tr
  101. v-if="pdfData.productInfoList && pdfData.productInfoList.length > 0"
  102. v-for="(item, index) in pdfData.productInfoList"
  103. :key="item.productId"
  104. >
  105. <td style="width: 15%">
  106. <img
  107. :src="item.fileList[0].fileUrl"
  108. alt=""
  109. fit="scale-down"
  110. style="height: 60px; width: 60px"
  111. v-if="item.fileList && item.fileList.length > 0"
  112. />
  113. </td>
  114. <td style="width: 20%">{{ item.productName }}</td>
  115. <td style="width: 15%">
  116. <span v-if="item.productModel">{{ item.productModel }} cm</span>
  117. </td>
  118. <td style="width: 12%">{{ item.packMethod }}</td>
  119. <td style="width: 12%">
  120. {{ item.productQuantity }}
  121. </td>
  122. <td style="width: 13%">
  123. {{ pdfData.currency }} {{ moneyFormat(item.productPrice, 2) }}
  124. </td>
  125. <td style="width: 13%">
  126. {{ pdfData.currency }} {{ moneyFormat(item.amount, 2) }}
  127. </td>
  128. </tr>
  129. <template
  130. v-if="
  131. pdfData.contractProjectList &&
  132. pdfData.contractProjectList.length > 0
  133. "
  134. >
  135. <tr>
  136. <td colspan="6" style="text-align: right">
  137. <div
  138. v-for="(item, index) in pdfData.contractProjectList"
  139. :key="item.id"
  140. >
  141. {{ item.payName }}:
  142. </div>
  143. </td>
  144. <td>
  145. <div
  146. v-for="(item, index) in pdfData.contractProjectList"
  147. :key="item.id"
  148. >
  149. {{ pdfData.currency }}
  150. {{ moneyFormat(item.amount, 2) }}
  151. </div>
  152. </td>
  153. </tr>
  154. </template>
  155. <tr>
  156. <td colspan="6" style="text-align: right">Total Amount:</td>
  157. <td>
  158. {{ pdfData.currency }}
  159. {{ moneyFormat(pdfData.totalAmount, 2) }}
  160. </td>
  161. </tr>
  162. <tr>
  163. <td colspan="6" style="text-align: right">
  164. Deposit( {{ pdfData.advanceRatio }} %):
  165. </td>
  166. <td>{{ pdfData.currency }} {{ getBalance(pdfData.advanceRatio) }}</td>
  167. </tr>
  168. <tr>
  169. <td colspan="6" style="text-align: right">
  170. Balance( {{ pdfData.advanceRatioOne }} %):
  171. </td>
  172. <td>
  173. {{ pdfData.currency }} {{ getBalance(pdfData.advanceRatioOne) }}
  174. </td>
  175. </tr>
  176. </table>
  177. <div style="height: 15px; background: #7f197f"></div>
  178. <table border="1" style="width: 100%" class="table">
  179. <tr>
  180. <td class="width-one" style="text-align: left">1.Lead Time:</td>
  181. <td style="text-align: left">{{ pdfData.deliveryTime }}</td>
  182. </tr>
  183. <tr>
  184. <td class="width-one" style="text-align: left">2.Payment Term:</td>
  185. <td style="text-align: left">
  186. <div v-html="pdfData.remark"></div>
  187. </td>
  188. </tr>
  189. <tr>
  190. <td class="width-one" style="text-align: left">3.Shipping Mode</td>
  191. <td style="text-align: left">
  192. {{ dictValueLabel(pdfData.transportMethod, shippingMethod) }}
  193. </td>
  194. </tr>
  195. <tr>
  196. <td class="width-one" style="text-align: left">4.Insurance</td>
  197. <td style="text-align: left">By Buyer</td>
  198. </tr>
  199. <tr>
  200. <td class="width-one" style="text-align: left">5.Banking Info</td>
  201. <td style="text-align: left">
  202. <div>Beneficiary Name: {{ pdfData.beneficiaryName }}</div>
  203. <div>Beneficiary Bank: {{ pdfData.beneficiaryBank }}</div>
  204. <div>
  205. Beneficiary Bank Address:
  206. {{ pdfData.beneficiaryBankAddress }}
  207. </div>
  208. <div>
  209. Beneficiary Account Number:
  210. {{ pdfData.beneficiaryAccountNumber }}
  211. </div>
  212. <div>Swift Code: {{ pdfData.swiftCode }}</div>
  213. <div>Beneficiary Address: {{ pdfData.beneficiaryAddress }}</div>
  214. </td>
  215. </tr>
  216. <tr>
  217. <td class="width-one" style="text-align: left">
  218. 6.Important Clauses:
  219. </td>
  220. <td style="text-align: left">
  221. A:Making payment will be considered as confirmation and
  222. countersignature of this order. Order can not be canceled after
  223. confirmation and countersignature except acceptance by the seller.
  224. The Buyer has obligation to make full payment of order including
  225. canceled orders.
  226. <br />
  227. B:The seller should not be responsible for the delay cause by the
  228. buyer and force majeure.
  229. <br />
  230. C:Modification of products will not be allowed after the deposit has
  231. been arranged unless acceptance by the seller. All costs and
  232. <br />consequences arising from modifying the product or other
  233. things will be borne by the buyer.
  234. <br />
  235. D:Packging details including shipping marks, barcodes, artworks,etc
  236. .should be provided 30 days before cargo readty agreed by both
  237. <br />parties.The delay caused by the buyer's failure to submit the
  238. packaging materials on time will be borne the buyer.
  239. <br />
  240. E: Shipping information including consignee and notify party,
  241. discharge port, loading port ects should be provided 20 before
  242. cargo<br />
  243. ready date. The delay caused by the buyer's failure to provide
  244. shipping information on time will be borne by the buyer.
  245. <br />
  246. F:Please notify the seller of the special requirements of shipping
  247. documents and certificates when placing an order.
  248. </td>
  249. </tr>
  250. </table>
  251. <table border="1" style="width: 100%; border-top: none" class="table">
  252. <tr>
  253. <td style="width: 50%; text-align: left">
  254. The Buyer's Signature
  255. <div style="width: 200px; height: 200px"></div>
  256. </td>
  257. <td style="width: 50%; text-align: left">
  258. The Seller's Signature
  259. <div style="width: 200px; height: 200px">
  260. <img
  261. v-if="pdfData.companySeal"
  262. :src="pdfData.companySeal"
  263. alt=""
  264. fit="scale-down"
  265. style="height: 200px; width: 200px"
  266. />
  267. </div>
  268. </td>
  269. </tr>
  270. </table>
  271. </div>
  272. </div>
  273. </template>
  274. <script setup>
  275. import { NumberToChinese } from "@/utils/util.js";
  276. import { async } from "@antv/x6/lib/registry/marker/main";
  277. import { watch } from "vue";
  278. const { proxy } = getCurrentInstance();
  279. const pdfData = ref({});
  280. const props = defineProps({
  281. rowData: Object,
  282. });
  283. const loading = ref(false);
  284. const getPdfData = (query) => {
  285. loading.value = true;
  286. proxy.post("/contract/getContractPdfInfo", query).then((res) => {
  287. pdfData.value = res;
  288. if (pdfData.value.advanceRatio) {
  289. pdfData.value.advanceRatio = parseFloat(
  290. pdfData.value.advanceRatio
  291. ).toFixed(2);
  292. pdfData.value.advanceRatioOne = (
  293. 100 - Number(pdfData.value.advanceRatio)
  294. ).toFixed(2);
  295. }
  296. if (pdfData.value.sellCorporationId) {
  297. proxy
  298. .post("/fileInfo/getList", {
  299. businessIdList: [pdfData.value.sellCorporationId],
  300. fileType: 1,
  301. })
  302. .then((fileObj) => {
  303. proxy
  304. .getImgBase64(fileObj[pdfData.value.sellCorporationId][0].fileUrl)
  305. .then((res) => {
  306. pdfData.value.companyPic = res;
  307. });
  308. });
  309. proxy
  310. .post("/fileInfo/getList", {
  311. businessIdList: [pdfData.value.sellCorporationId],
  312. fileType: 4,
  313. })
  314. .then((fileObj) => {
  315. proxy
  316. .getImgBase64(fileObj[pdfData.value.sellCorporationId][0].fileUrl)
  317. .then((res) => {
  318. pdfData.value.companySeal = res;
  319. });
  320. });
  321. }
  322. loading.value = false;
  323. // 拿取产品图
  324. if (
  325. pdfData.value.productInfoList &&
  326. pdfData.value.productInfoList.length > 0
  327. ) {
  328. let arr = pdfData.value.productInfoList.map((x) => x.productId);
  329. proxy
  330. .post("/fileInfo/getList", {
  331. businessIdList: arr,
  332. })
  333. .then(async (fileObj) => {
  334. for (let i = 0; i < pdfData.value.productInfoList.length; i++) {
  335. const e = pdfData.value.productInfoList[i];
  336. for (const key in fileObj) {
  337. if (e.productId === key) {
  338. if (fileObj[key] && fileObj[key].length > 0) {
  339. const res = await proxy.getImgBase64(fileObj[key][0].fileUrl);
  340. fileObj[key][0].fileUrl = res;
  341. e.fileList = fileObj[key];
  342. }
  343. }
  344. }
  345. }
  346. });
  347. }
  348. });
  349. };
  350. const productUnit = ref([]);
  351. const tradeMethods = ref([]);
  352. const shippingMethod = ref([]);
  353. const getDict = () => {
  354. proxy.getDictOne(["trade_mode", "shipping_method", "unit"]).then((res) => {
  355. tradeMethods.value = res["trade_mode"].map((x) => ({
  356. label: x.dictValue,
  357. value: x.dictKey,
  358. }));
  359. shippingMethod.value = res["shipping_method"].map((x) => ({
  360. label: x.dictValue,
  361. value: x.dictKey,
  362. }));
  363. productUnit.value = res["unit"].map((x) => ({
  364. label: x.dictValue,
  365. value: x.dictKey,
  366. }));
  367. });
  368. };
  369. getDict();
  370. const getBalance = (val) => {
  371. if (val) {
  372. return proxy.moneyFormat(
  373. parseFloat(pdfData.value.totalAmount * (val / 100)).toFixed(2),
  374. 2
  375. );
  376. }
  377. };
  378. watch(
  379. () => props.rowData,
  380. (val) => {
  381. if (props.rowData.id) {
  382. getPdfData({ id: props.rowData.id });
  383. } else if (props.rowData.code) {
  384. getPdfData({ code: props.rowData.code });
  385. }
  386. },
  387. {
  388. immediate: true,
  389. deep: true,
  390. }
  391. );
  392. </script>
  393. <style lang="scss" scoped>
  394. .color-class {
  395. color: #7f197f;
  396. }
  397. .bck {
  398. background: #7f197f;
  399. }
  400. .width-one {
  401. width: 140px;
  402. }
  403. .table {
  404. border-collapse: collapse;
  405. border-spacing: 0;
  406. td {
  407. text-align: center;
  408. padding: 2px 4px;
  409. // padding: 5px 10px;
  410. }
  411. }
  412. </style>