contractPDFOne.vue 13 KB

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