You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

554 lines
19 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <client-only>
  3. <div
  4. class="tw-px-[15px] tw-mb-[60px] xl:tw-px-[60px] xl:tw-max-w-screen-xl xl:tw-mx-auto xl:tw-grid xl:tw-grid-cols-[822px_auto] xl:tw-gap-[30px]"
  5. >
  6. <section
  7. class="section section-one tw-my-[40px] md:tw-my-[50px] xl:tw-col-span-2"
  8. >
  9. <StepInfo :step_active="step"></StepInfo>
  10. </section>
  11. <section class="section section-two">
  12. <h2
  13. class="t18 title-icon-left tw-text-black tw-mb-[15px] xl:tw-mb-[10px] xl:tw-text-[24px]"
  14. >
  15. {{ $t("Booking Info") }}
  16. </h2>
  17. <div
  18. class="notice tw-body-3 tw-text-black tw-mb-[20px] tw-hidden xl:tw-block"
  19. >
  20. {{
  21. $t(
  22. "Please enter your info carefully. Once submitted it cannot be changed."
  23. )
  24. }}
  25. </div>
  26. <BookingInfoItem
  27. v-for="(item, index) in order"
  28. :key="index"
  29. :info="item"
  30. :content="content"
  31. :questions="content.booking_questions"
  32. :contact.sync="userContactList"
  33. :active="activeLabel"
  34. @changeActiveLabel="activeLabel = $event"
  35. @contact="contactData = $event"
  36. @answer="answerData = $event"
  37. @bookingDetail_validation="getBookingDetail_validation"
  38. >
  39. </BookingInfoItem>
  40. <h2
  41. class="t18 title-icon-left tw-text-black tw-mb-[15px] lg:tw-mb-[8px] xl:tw-text-[24px] xl:tw-mt-[60px]"
  42. >
  43. {{ $t("Complete Payment") }}
  44. </h2>
  45. <div
  46. class="notice tw-body-3 tw-text-black tw-mb-[20px] tw-hidden xl:tw-block"
  47. >
  48. {{
  49. $t(
  50. "Please enter your info carefully. Once submitted it cannot be changed."
  51. )
  52. }}
  53. </div>
  54. <PurchaserInfo
  55. :class="[bookingDetail_Validation ? 'noFilter' : 'haveFilter']"
  56. ref="purchaserInfo"
  57. :userCompanyList="userCompanyList"
  58. :countryOptions="countryOptions"
  59. :infoType="type"
  60. :bookingDetail_Validation="bookingDetail_Validation"
  61. @type="type = $event"
  62. @active="companyActiveLabel = $event"
  63. @individual="individualData = $event"
  64. @company="companyData = $event"
  65. @purchaserInfo_validation="getPurchaserInfo_validation"
  66. ></PurchaserInfo>
  67. <ChooseMethod
  68. :class="[purchaserInfo_Validation ? 'noFilter' : 'haveFilter']"
  69. :orderNo="orderNo"
  70. :purchaserInfo_Validation="purchaserInfo_Validation"
  71. @paymentType="paymentData.payment_type = $event"
  72. @update="updateToken($event)"
  73. >
  74. </ChooseMethod>
  75. <!-- <Invoice v-if="language == 'zh-tw'"></Invoice> -->
  76. <PcTotalPrice
  77. :subTotal="subTotal"
  78. :currency="currency"
  79. v-on:payNowClick="payNow()"
  80. ></PcTotalPrice>
  81. </section>
  82. <section class="section section-three">
  83. <PriceInfo
  84. v-for="(item, index) in order"
  85. :key="index"
  86. :info="item"
  87. :currency="currency"
  88. ></PriceInfo>
  89. <TotalPrice
  90. :subTotal="subTotal"
  91. :currency="currency"
  92. v-on:payNowClick="payNow()"
  93. ></TotalPrice>
  94. </section>
  95. <!-- <AddContactModal @update="updateContactList"></AddContactModal> -->
  96. <!-- <EditContactModal
  97. ref="EditContactModal"
  98. :contact.sync="userContactList[this.activeLabel - 1]"
  99. @update="getContactList"
  100. ></EditContactModal>
  101. <AddCompanyModal
  102. :selectList.sync="countryOptions"
  103. @update="updateCompanyList()"
  104. >
  105. </AddCompanyModal>
  106. <EditCompanyModal
  107. :selectList.sync="countryOptions"
  108. :company.sync="userCompanyList[companyActiveLabel - 1]"
  109. @update="getCompanyList()"
  110. ></EditCompanyModal> -->
  111. </div></client-only>
  112. </template>
  113. <script>
  114. import StepInfo from "@/components/service/StepInfo";
  115. import BookingInfoItem from "@/components/service/BookingInfoItem";
  116. import PurchaserInfo from "@/components/service/PurchaserInfo";
  117. import ChooseMethod from "@/components/service/ChooseMethod";
  118. import PriceInfo from "@/components/service/PriceInfo";
  119. import TotalPrice from "@/components/service/TotalPrice";
  120. import PcTotalPrice from "@/components/service/PcTotalPrice";
  121. import elementInput from "@/components/newComponent/form/ElementInput";
  122. // import AddContactModal from "@/components/newComponent/modal/AddContactModal";
  123. // import EditContactModal from "@/components/newComponent/modal/EditContactModal";
  124. // import AddCompanyModal from "@/components/newComponent/modal/AddCompanyModal";
  125. // import EditCompanyModal from "@/components/newComponent/modal/EditCompanyModal";
  126. import Invoice from "@/components/service/Invoice.vue";
  127. import ElementInputNew from "@/components/newComponent/form/ElementInputNew";
  128. export default {
  129. name: "service",
  130. layout: "service",
  131. auth: true,
  132. components: {
  133. StepInfo,
  134. BookingInfoItem,
  135. PurchaserInfo,
  136. ChooseMethod,
  137. PriceInfo,
  138. TotalPrice,
  139. PcTotalPrice,
  140. elementInput,
  141. Invoice,
  142. // AddContactModal,
  143. // EditContactModal,
  144. // AddCompanyModal,
  145. // EditCompanyModal,
  146. ElementInputNew,
  147. },
  148. data() {
  149. return {
  150. apiUrl: process.env.SERVICE_CONSOLE,
  151. devECPayUrl: "https://dev-lambda.showeasy.com",
  152. language: this.$i18n.locale,
  153. step: "2",
  154. orderNo: this.$route.params.id,
  155. order: [{
  156. title: '展館服務(堆高機、拆裝箱、空箱儲存⋯⋯等)',
  157. detail: '<div class="element tw-flex tw-justify-between tw-items-center tw-flex-nowrap tw-my-[12px]" > <div class="label tw-body-4">選擇展覽</div><div class="content tw-body-4">2022 台灣國際咖啡展 </div></div>',
  158. preview_image: require('/assets/img/service_banner.png'),
  159. date: '2023-02-13',
  160. quantity: '1111',
  161. total: 23132,
  162. service_name: '展館服務(堆高機、拆裝箱、空箱儲存⋯⋯等)',
  163. package_name: '123',
  164. package_name: '123',
  165. customer_plan_name: '123',
  166. service_date: '20023-02-13',
  167. service_time: '12:00:00',
  168. selectExhibition: '2022 台灣國際咖啡展',
  169. order_as: [],
  170. order_item: [{
  171. package_name:'裸機, 100*100*100cm, 100kg',
  172. customer_plan_name: '堆高機服務',
  173. specification_name: '拆箱',
  174. quantity: '2'
  175. },{
  176. package_name:'裸機, 100*100*100cm, 100kg',
  177. customer_plan_name: '堆高機服務',
  178. specification_name: '拆箱',
  179. quantity: '2'
  180. },{
  181. package_name:'裸機, 100*100*100cm, 100kg',
  182. customer_plan_name: '堆高機服務',
  183. specification_name: '拆箱',
  184. quantity: '2'
  185. }]
  186. }],
  187. serviceId: "",
  188. currency: "TWD",
  189. type: "Individual",
  190. individualData: {},
  191. companyData: {},
  192. contactData: {},
  193. paymentData: {},
  194. answerData: [],
  195. content: {
  196. preview_image: "",
  197. country: null,
  198. city: null,
  199. name: "",
  200. highlights: "",
  201. details: "",
  202. cancellation_policy: "",
  203. saved: false,
  204. confirmation_time: 24,
  205. supplier: null,
  206. available_sections: null,
  207. timeStatus: "",
  208. dateStatus: "",
  209. times: [],
  210. start: "",
  211. end: "",
  212. faq: null,
  213. packages: [],
  214. additionalServices: [],
  215. booking_questions: [],
  216. },
  217. subTotal: 0,
  218. activeLabel: 0,
  219. companyActiveLabel: 0,
  220. userContactList: [],
  221. userCompanyList: [],
  222. countryOptions: [],
  223. contact: [],
  224. method: "",
  225. payToken: "",
  226. three_d_url: "",
  227. validation: {
  228. bookingInfo: false,
  229. purchaserInfo: false,
  230. chooseMethod: false,
  231. },
  232. bookingDetail_Validation: false,
  233. purchaserInfo_Validation: false,
  234. };
  235. },
  236. async created() {
  237. if (this.$auth.loggedIn) {
  238. // await this.getContactList();
  239. // await this.getActiveLength();
  240. // await this.getOrder();
  241. await this.getServiceData();
  242. // await this.getPackages();
  243. // await this.getCountries();
  244. // await this.getCompanyList();
  245. }
  246. },
  247. mounted() {},
  248. methods: {
  249. // async getContactList() {
  250. // await this.$axios
  251. // .get(`/trending/api/Members/Contacts`)
  252. // .then((response) => {
  253. // if(response && response.data && response.data.DATA && response.data.DATA.rel){
  254. // let data = response.data.DATA.rel
  255. // if(data.length>0){
  256. // this.userContactList = data.map((item) => {
  257. // return {
  258. // first_name: item.FirstName,
  259. // last_name: item.LastName,
  260. // email: item.Email,
  261. // phone_number: item.PhoneCountryCode +"-"+ item.PhoneNo
  262. // };
  263. // });
  264. // }
  265. // }
  266. // })
  267. // .catch((err) => {
  268. // console.log(err);
  269. // });
  270. // },
  271. // async updateContactList() {
  272. // const patchData = {};
  273. // await this.$axios
  274. // .post(`/trending/api/Members/Contacts`,patchData)
  275. // .then((result) => {
  276. // // this.userContactList = result.data.contacts;
  277. // // this.activeLabel = this.userContactList.length;
  278. // // return result.data;
  279. // })
  280. // .catch((err) => {
  281. // console.log(err);
  282. // });
  283. // },
  284. async getOrder() {
  285. // await this.$axios
  286. // .get(
  287. // `/order/${this.$route.params.id}?jwt=${
  288. // this.$auth.$storage.getUniversal("jwt").token
  289. // }`
  290. // )
  291. // .then((res) => {
  292. // this.order = res.data;
  293. // for (let index in this.order[0].order_item) {
  294. // this.subTotal += this.order[0].order_item[index].item_amount;
  295. // }
  296. // for (let index in this.order[0].order_as) {
  297. // this.subTotal += this.order[0].order_as[index].as_amount;
  298. // }
  299. // this.serviceId = this.order[0].service_id;
  300. // this.currency = this.order[0].currency;
  301. // })
  302. // .catch((err) => {
  303. // console.log(err);
  304. // });
  305. },
  306. async getServiceData() {
  307. await this.$axios
  308. .get(`/trending/api/Onsite/Info?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  309. .then((response) => {
  310. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  311. let data = response.data.DATA.rel
  312. if(data){
  313. // this.content.service_name = data.ServiceName;
  314. // this.content.package_name = data.Features;
  315. // this.content.package_name = data.Details;
  316. // this.content.customer_plan_name = data.CancelPolicy;
  317. // this.content.specification_name = data.FQAs;
  318. // this.content.quantity = data.ConfirmDays;
  319. // this.content.service_date = "2023-02-13";
  320. // this.content.service_time = "02:00:12";
  321. // this.content.booking_questions = data.FQAs;
  322. // this.content.preview_image = res.data.preview_image;
  323. // this.content.name = res.data.name;
  324. // this.content.country = res.data.country;
  325. // this.content.city = res.data.city;
  326. // this.content.highlights = res.data.highlights;
  327. // this.content.details = res.data.details;
  328. // this.content.cancellation_policy = res.data.cancellation_policy;
  329. // this.content.supplier = res.data.supplier;
  330. // this.content.available_sections = res.data.available_sections;
  331. // this.content.times = res.data.available_sections.times;
  332. // this.content.timeStatus = res.data.available_sections.time_status;
  333. // this.content.dateStatus = res.data.available_sections.date_status;
  334. // this.content.start = res.data.available_sections.start;
  335. // this.content.end = res.data.available_sections.end;
  336. // this.content.payment_currency = 0;
  337. }
  338. }
  339. })
  340. .catch((error) => console.log(error));
  341. },
  342. async getPackages() {
  343. let orderPackageId = this.order[0].order_item[0].package_id
  344. ? this.order[0].order_item[0].package_id
  345. : "";
  346. await this.$axios
  347. .get( `/trending/api/Onsite/PackingTypes?Lang=${this.$i18n.localeProperties["langQuery"]}&currency=${this.currency}`)
  348. .then((response) => {
  349. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  350. let data = response.data.DATA.rel
  351. if(data.length>0){
  352. this.content.packages = data.map((item) => {
  353. return {
  354. package_id: item.ArgumentID,
  355. name: item.ArgumentValue,
  356. };
  357. });
  358. let packageObject = this.content.packages[
  359. this.content.packages.findIndex(
  360. (item) => item.ArgumentID === orderPackageId
  361. )
  362. ];
  363. for (let i in packageObject.questions) {
  364. packageObject.questions[i].required = packageObject.questions[i].required_ans;
  365. this.content.booking_questions.push(packageObject.questions[i]);
  366. }
  367. }
  368. }
  369. })
  370. .catch((error) => console.log(error));
  371. },
  372. async payNow() {
  373. let vm = this;
  374. if (this.paymentData.payment_type == "Credit Card") {
  375. try {
  376. // ECPay.getPayToken(function (paymentInfo, errMsg) {
  377. // //console.log("response => getPayToken(paymentInfo, errMsg):", paymentInfo, errMsg);
  378. // if (errMsg != null) {
  379. // vm.ErrHandle(errMsg);
  380. // return;
  381. // }
  382. // vm.payToken = paymentInfo.PayToken;
  383. // vm.updateOrder(Object);
  384. // return true;
  385. // });
  386. } catch (err) {
  387. this.ErrHandle(err);
  388. }
  389. } else {
  390. vm.updateOrder(Object);
  391. }
  392. },
  393. // async getCountries() {
  394. // await this.$axios
  395. // .get(`/users/countries?lang=${this.$i18n.locale.replace("-", "")}`)
  396. // .then((result) => {
  397. // this.countryOptions = result.data.result;
  398. // })
  399. // .catch((err) => {
  400. // console.log(err);
  401. // });
  402. // },
  403. async getCompanyList() {
  404. await this.$axios
  405. .get(
  406. `/trending/api/Members/Companies?Lang=${this.$i18n.localeProperties["langQuery"]}`
  407. )
  408. .then((response) => {
  409. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  410. let data = response.data.DATA.rel
  411. if(data.length){
  412. this.userCompanyList = data.map((item) => {
  413. return {
  414. company_name: item.CompanyName,
  415. company_tax_no: item.TaxNumber,
  416. company_address1: item.Street1,
  417. company_address2: item.Street2,
  418. company_city: item.CityName,
  419. company_state: item.StateName,
  420. company_country_name: item.Country.Country,
  421. company_zipcode: item.ZipCode,
  422. company_country: item.Country.CountryID,
  423. };
  424. });
  425. // this.userCompanyList = result.data.data;
  426. // Array.from(this.userCompanyList).forEach((item) => {
  427. // let id = item.company_country;
  428. // let countryName = this.countryOptions.filter(
  429. // (item) => item.id === id || null
  430. // );
  431. // item.company_country_name = countryName[0].name ?? 0;
  432. // });
  433. // return result.data;
  434. }
  435. }
  436. })
  437. .catch((err) => {
  438. console.log(err);
  439. });
  440. },
  441. updateCompanyList() {
  442. const patchData = {};
  443. this.$axios
  444. .post(
  445. `/trending/api/Members/Company`,patchData
  446. )
  447. .then((result) => {
  448. // this.userCompanyList = result.data.data;
  449. // this.companyActiveLabel = this.userCompanyList.length;
  450. // this.Company.company_name =
  451. // result.data.data[this.activeLabel].company_name;
  452. // this.Company.company_tax_no =
  453. // result.data.data[this.activeLabel].company_tax_no;
  454. // this.Company.company_address1 =
  455. // result.data.data[this.activeLabel].company_address1;
  456. // this.Company.company_address2 =
  457. // result.data.data[this.activeLabel].company_address2;
  458. // this.Company.company_city =
  459. // result.data.data[this.activeLabel].company_city;
  460. // this.Company.company_state =
  461. // result.data.data[this.activeLabel].company_state;
  462. // this.Company.company_country =
  463. // result.data.data[this.activeLabel].company_country_name;
  464. // this.Company.company_zipcode =
  465. // result.data.data[this.activeLabel].company_zipcode;
  466. // return result.data;
  467. })
  468. .catch((err) => {
  469. console.log(err);
  470. });
  471. },
  472. updateOrder() {
  473. let Object = {
  474. order_id: this.order[0].order_id,
  475. total: this.subTotal,
  476. amount: this.subTotal,
  477. discount: 0,
  478. contact: [this.contactData],
  479. answer: this.answerData,
  480. };
  481. if (this.type == "Individual") {
  482. Object.purchase_personal = this.individualData;
  483. } else {
  484. Object.purchase_company = this.companyData;
  485. }
  486. Object.payment = [this.paymentData];
  487. Object.payment[0].payment_index = 0;
  488. Object.payment[0].amount = this.subTotal;
  489. // this.$axios
  490. // .put(
  491. // `/order/${this.$route.params.id}?jwt=${
  492. // this.$auth.$storage.getUniversal("jwt").token || ""
  493. // }`,
  494. // Object
  495. // )
  496. // .then((res) => {
  497. // if (res.status == "200") {
  498. // if (this.paymentData.payment_type == "Credit Card") {
  499. // this.createPayment();
  500. // } else {
  501. // this.$router.push(
  502. // this.localePath("/service/done/" + this.$route.params.id)
  503. // );
  504. // }
  505. // }
  506. // })
  507. // .catch((error) => {
  508. // console.log(error);
  509. // });
  510. },
  511. getActiveLength() {
  512. this.activeLabel = this.userContactList.length > 0 ? 1 : 0;
  513. },
  514. updateToken(token) {
  515. this.payToken = token;
  516. },
  517. // createPayment() {
  518. // this.$axios
  519. // .post(`${this.devECPayUrl}/payment/ecpay/create-payment`, {
  520. // pay_token: this.payToken,
  521. // payment_flow: "ecpay",
  522. // product_order_no: this.orderNo,
  523. // })
  524. // .then((response) => {
  525. // if (response.data.status_code === 200) {
  526. // window.location.assign(response.data.three_d_url);
  527. // }
  528. // })
  529. // .catch((error) => console.log(error));
  530. // },
  531. getBookingDetail_validation(data) {
  532. this.bookingDetail_Validation = data;
  533. },
  534. getPurchaserInfo_validation(data) {
  535. this.purchaserInfo_Validation = data;
  536. },
  537. },
  538. };
  539. </script>
  540. <style lang="scss" scoped>
  541. .noFilter {
  542. pointer-events: auto;
  543. cursor: auto;
  544. }
  545. .haveFilter {
  546. cursor: not-allowed;
  547. pointer-events: none;
  548. filter: opacity(50%);
  549. }
  550. </style>