1367 lines
51 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
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
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
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. <div
  3. class="service-content tw-mb-[60px] tw-grid tw-grid-cols-1 tw-gap-[30px] md:tw-mb-[100px] xl:tw-px-[60px] xl:tw-max-w-screen-xl xl:tw-mx-auto xl:tw-grid-cols-[auto_364px]">
  4. <mobileFixTopBar ref="stickySwiper" :fixBar="fixBar" :currStep="currStep" :list="fixBarList"></mobileFixTopBar>
  5. <section class="step sercion-1 tw-w-full md:tw-px-[30px] xl:tw-px-0 xl:tw-col-span-2">
  6. <div class="tw-mt-[20px] md:tw-mb-[11px] md:tw-mt-[40px]">
  7. <Breadcrumbs></Breadcrumbs>
  8. </div>
  9. <div v-if="content.banners.length" class="tw-w-full">
  10. <slideshow :banners="content.banners"></slideshow>
  11. </div>
  12. </section>
  13. <section class="sercion-2 tw-px-[30px] md:tw-px-[30px] xl:tw-px-0 xl:tw-col-start-1 xl:tw-row-start-2">
  14. <h1 class="t16 tw-mb-[18px] md:t24">{{ content.name }}</h1>
  15. <div v-if="content.supplier"
  16. class="supplier tw-flex tw-items-center tw-mb-[20px] tw-text-base-primary t14 md:tw-mb-[30px] md:t16 md:tw-font-normal">
  17. <img :src="content.supplier.logo" class="tw-max-w-[40px] md:tw-max-w-[80px]" />
  18. <div class="t14 tw-font-normal tw-ml-[10px] md:t18 md:tw-font-normal">
  19. {{ content.supplier.brand }}
  20. </div>
  21. </div>
  22. <div class="editor-styleguide tw-text-base-primary" v-html="content.highlights"></div>
  23. </section>
  24. <section
  25. class="sercion-3 tw-grid tw-grid-cols-1 tw-gap-[30px] md:tw-gap-[40px] md:tw-px-[30px] xl:tw-px-0 xl:tw-col-start-1 xl:tw-row-start-3">
  26. <div ref="packageOptions" id="packageOptions" class="step">
  27. <div class="tw-px-[30px] md:tw-px-0">
  28. <h2 class="title-icon-left t16 tw-mb-[20px] md:t24">
  29. {{ $t("Package Options") }}
  30. </h2>
  31. <p class="text-slate-600 t12 md:t16">{{ $t("Select the exhibition you want to attend, and add the storage and delivery service of exhibits or truck pickup service") }}</p>
  32. </div>
  33. <div class="tw-w-full tw-bg-neutrals-100 tw-px-[20px] tw-py-[30px] md:tw-p-[30px] tw-rounded-[20px]">
  34. <div class="">
  35. <div class="group tw-mb-[40px] tw-px-[20px] tw-py-[30px] tw-rounded-[20px] tw-bg-white">
  36. <h3 class="t14 tw-font-bold tw-mb-[30px] md:t16 tw-block">
  37. 輸入攤位數量
  38. </h3>
  39. <selectExhibitionBooth @booth-select="getBoothSelect"></selectExhibitionBooth>
  40. </div>
  41. <div class="group tw-mb-[40px] tw-px-[20px] tw-py-[30px] tw-rounded-[20px] tw-bg-white">
  42. <h3 class="t14 tw-font-bold tw-mb-[30px] md:t16 tw-block">
  43. {{ $t("Select Exhibition") }}
  44. </h3>
  45. <selectExhibition ref="ref_selectExhibition" :selectYearList="selectYearList" :selectMonthList="selectMonthList" :selectExhibitionList="selectExhibitionList"></selectExhibition>
  46. </div>
  47. <div class="group tw-mb-[20px] tw-p-[20px] tw-rounded-[20px] tw-bg-white">
  48. <h3 class="t14 tw-font-bold tw-mb-[20px] md:t16 tw-block">
  49. {{ $t("Select exhibition hall service") }}
  50. </h3>
  51. <div class="tw-mb-[10px]">
  52. <p class="tw-text-neutrals-500 tw-font-normal md:t16">{{ $t("Storage service of exhibits in the exhibition hall, and assistance in transportation to the designated booth") }}</p>
  53. </div>
  54. <selectExhibitionService v-for="(item,index) in selectExhibitionServiceList"
  55. :key="item.id" :ref="'ref_selectExhibitionitem'+item.id" @ChangeCosts="ChangeCosts($event)"
  56. :selectQuantityList="selectQuantityList"
  57. :selectPackageList="selectPackageList"
  58. :typeGroupList="typeGroupList"
  59. :sort="index+1"
  60. :show = "item.id == showServiceItem"
  61. @delExhibitionService="delExhibitionService(item.id)">
  62. </selectExhibitionService>
  63. <v-btn outlined class="tw-rounded-[16px] remove-upper tw-border-primary-2 tw-text-primary-1 tw-flex tw-items-center"
  64. style="padding: 24px 10px" width="100%" @click="addExhibitionService">
  65. <v-img max-width="20" class="tw-mr-[8px]" :src="require(`@/assets/svg/new.svg`)"></v-img>
  66. <span class="t18 tw-font-normal">{{ $t("New exhibit specifications") }}</span>
  67. </v-btn>
  68. </div>
  69. <div v-show="showCardItem" class="group tw-mb-[20px] tw-p-[20px] tw-rounded-[20px] tw-bg-white">
  70. <div class="tw-flex tw-justify-between tw-items-center">
  71. <h3 class="t14 tw-font-bold tw-mb-[20px] md:t16">
  72. {{ $t("Select truck pickup service") }}
  73. </h3>
  74. <v-img v-show="pickupServiceShow" max-width="18" max-height="19" class="tw-mr-[8px] tw-cursor-pointer" :src="require(`@/assets/svg/delete_default.svg`)" @click="deletePickupSerivce()"></v-img>
  75. </div>
  76. <div class="tw-mb-[20px]">
  77. <p class="tw-text-neutrals-500 tw-font-normal md:t16">{{ $t("Pick up the goods at the designated place and transport them to the exhibition hall") }}</p>
  78. </div>
  79. <div v-show="pickupServiceShow">
  80. <div>
  81. <quantitySelectGroup ref="ref_quantitySelectGroup" :label="'Select quantity'" :quantitySelectList="quantitySelectList" @ChangeCosts="ChangeCosts($event)">
  82. </quantitySelectGroup>
  83. </div>
  84. <h3 class="t14 tw-font-bold tw-mb-[20px] md:t16 tw-block">
  85. {{ $t("Fill in the picking information") }}<span class="required t12 md:t14">*</span>
  86. </h3>
  87. <pickupInformation :selectAddressList="selectAddressList" ref="ref_pickupService" @ChangeCosts="ChangeCosts($event)"></pickupInformation>
  88. </div>
  89. <v-btn v-show="pickupServiceShow==false" outlined class="tw-rounded-[16px] remove-upper tw-border-primary-2 tw-text-primary-1 t18"
  90. style="padding: 24px 10px" width="100%" @click="pickupServiceShow = true">
  91. <v-img max-width="20" class="tw-mr-[8px]" :src="require(`@/assets/svg/new.svg`)"></v-img>
  92. <span class="t18 tw-font-normal">{{ $t("New pickup service") }}</span>
  93. </v-btn>
  94. </div>
  95. <div class="md:tw-flex md:tw-justify-between md:tw-items-center">
  96. <div class="tw-flex tw-justify-between tw-items-start md:tw-w-full md:tw-basis-10/12">
  97. <div class="tw-flex tw-flex-col tw-justify-center">
  98. <div class="tw-flex tw-items-center tw-mb-[8px] md:tw-mb-0">
  99. <div class="tw-body-4 tw-text-neutrals-900 tw-mr-[10px] md:t24">
  100. ${{ finalPrice }} {{ currencyName }}
  101. </div>
  102. </div>
  103. <!-- <div class="tw-hidden tw-body-4 tw-text-neutrals-600 md:tw-hidden">
  104. Deposit fee: $5 {{ currency }} (10%)
  105. </div> -->
  106. </div>
  107. <like></like>
  108. </div>
  109. <button
  110. class="tw-transition tw-btn-md tw-text-white tw-border tw-border-solid tw-border-primary-default tw-bg-primary-default tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl md:tw-mt-0 md:tw-ml-[36px] md:tw-w-auto md:tw-basis-2/12 disabled:tw-bg-neutral-100 disabled:tw-text-base-disable disabled:tw-border-neutral-200"
  111. @click="bookNow" :disabled="btnDisabled">
  112. {{ $t("Book Now") }}
  113. </button>
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. <div id="serviceDetails" class="serviceDetails step">
  119. <div class="tw-px-[30px] md:tw-px-0">
  120. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  121. {{ $t("Service Details") }}
  122. </h2>
  123. <div v-if="content.details.length < 800">
  124. <div ref="details" class="editor-styleguide tw-text-base-primary t14 md:t16 md:tw-font-normal"
  125. v-html="content.details"></div>
  126. </div>
  127. <div v-else>
  128. <div :class="[
  129. button.details ? 'seeMore-hide' : 'seeMore-show',
  130. 'editor-styleguide tw-text-base-primary tw-transition t14 md:t16 md:tw-font-normal',
  131. ]" ref="details" v-html="content.details"></div>
  132. <button v-show="seeMore.details" :class="[
  133. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  134. button.details ? '' : 'open',
  135. ]" @click="opendetail()">
  136. {{ $t(seeMoreDetailsText) }}
  137. </button>
  138. </div>
  139. </div>
  140. </div>
  141. <div id="serviceDescription" class="serviceDescription step">
  142. <div class="tw-px-[30px] md:tw-px-0">
  143. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  144. {{ $t("Service Description") }}
  145. </h2>
  146. <div v-for="(item,index) in expenseRules" :key="index" style="border: 1px solid red;">
  147. <h3 class="t16 tw-mb-[20px] md:18 xl:t18 xl:tw-font-bold tw-pl-[10px]">
  148. {{ index+1 }}.&nbsp;{{ item.ItemName }}
  149. </h3>
  150. <table class="tablecss" width="100%" v-if="item.ItemType=='01'">
  151. <thead class="tw-bg-[#343434]">
  152. <tr>
  153. <th class="tw-text-[#fefefe]">{{$t('Weight')}}</th>
  154. <th class="tw-text-[#fefefe]">{{$t('Price (NT $, tax included)')}}</th>
  155. </tr>
  156. </thead>
  157. <tbody>
  158. <template v-if="item.StackerCostRules && item.StackerCostRules.length>0">
  159. <tr v-for="item2 in item.StackerCostRules" :key="item2.Guid">
  160. <td width="50%">{{item2.Weight_Min}}{{$t('More than tons to')}}{{item2.Weight_Max}}{{$t('Less than tons')}}</td>
  161. <td width="50%">{{item2.Price}}<span v-if="item2.PricingMode=='N'">{{$t('NTD/piece')}}</span><span v-else>{{$t('NTD/ton')}}</span></td>
  162. </tr>
  163. </template>
  164. </tbody>
  165. </table>
  166. <div ref="details" v-if="item.ItemType!='01' && item.ItemType!='02'" class="editor-styleguide tw-text-base-primary t14 md:t16 md:tw-font-normal tw-mt-[20px]"
  167. v-html="item.CostRuleText"></div>
  168. <div ref="details" class="editor-styleguide tw-text-base-primary t14 md:t16 md:tw-font-normal tw-mt-[20px]"
  169. v-html="item.ExpensesMemo"></div>
  170. </div>
  171. <!-- <div v-if="content.details.length < 800">
  172. <div ref="details" class="editor-styleguide tw-text-base-primary t14 md:t16 md:tw-font-normal"
  173. v-html="content.details"></div>
  174. </div>
  175. <div v-else>
  176. <div :class="[
  177. button.details ? 'seeMore-hide' : 'seeMore-show',
  178. 'editor-styleguide tw-text-base-primary tw-transition t14 md:t16 md:tw-font-normal',
  179. ]" ref="details" v-html="content.details"></div>
  180. <button v-show="seeMore.details" :class="[
  181. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  182. button.details ? '' : 'open',
  183. ]" @click="opendetail()">
  184. {{ $t(seeMoreDetailsText) }}
  185. </button>
  186. </div> -->
  187. </div>
  188. </div>
  189. <div id="cancellationPolicy" class="cancellationPolicy step tw-px-[30px] md:tw-px-0">
  190. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  191. {{ $t("Cancellation Policy") }}
  192. </h2>
  193. <div v-if="content.cancellation_policy.length < 800">
  194. <div ref="cancellation_policy" class="editor-styleguide tw-text-base-primary t14 md:t16 md:tw-font-normal"
  195. v-html="content.cancellation_policy">
  196. </div>
  197. </div>
  198. <div v-else>
  199. <div :class="[
  200. button.cancellation_policy ? 'seeMore-hide' : 'seeMore-show',
  201. 'editor-styleguide tw-text-base-primary tw-transition t14 md:t16 md:tw-font-normal',
  202. ]" ref="cancellation_policy" v-html="content.cancellation_policy"></div>
  203. <button v-show="seeMore.cancellation_policy" :class="[
  204. 'seeMore tw-transition tw-btn-md tw-text-primary-1 tw-border tw-border-solid tw-border-primary-1 tw-px-[30px] tw-py-[8.5px] tw-mt-[20px] tw-w-full tw-rounded-xl hover:tw-bg-primary-3 xl:hover:tw-bg-transparent xl:tw-border-none',
  205. button.cancellation_policy ? '' : 'open',
  206. ]" @click="openCancellationPolicy()">
  207. {{ $t(seeMoreCancellationPolicyText) }}
  208. </button>
  209. </div>
  210. </div>
  211. <div v-show="content.faq && content.faq.length>0" id="faq" ref="faq" class="step tw-px-[30px] md:tw-px-0">
  212. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  213. {{ $t("FAQ") }}
  214. </h2>
  215. <faq :faq="content.faq" class="tw-z-[8]"></faq>
  216. </div>
  217. <div id="contactUs" class="step tw-px-[30px] md:tw-px-0">
  218. <h2 class="title-icon-left t16 tw-mb-[20px] md:t20 xl:tw-font-bold">
  219. {{ $t("Contact Us") }}
  220. </h2>
  221. <div class="tw-body-3 tw-text-base-primary tw-mb-[20px]">
  222. 886-2-2725-5000
  223. </div>
  224. <div class="tw-body-3 tw-text-base-primary">info@showeasy.com</div>
  225. </div>
  226. <div :class="[
  227. 'tw-bg-white tw-flex tw-flex-cols tw-justify-between tw-items-center tw-px-[30px] tw-py-[16px] tw-w-full',
  228. fixBar
  229. ? 'tw-fixed tw-left-[0px] tw-bottom-[0px] tw-z-[8] tw-shadow-[1px_0px_2px_rgba(0,0,0,0.25)]'
  230. : 'tw-hidden',
  231. ]">
  232. <div :class="[
  233. 'tw-flex tw-flex-col tw-justify-between tw-items-start tw-grow md:tw-w-full md:tw-flex-row md:tw-items-center',
  234. ]">
  235. <div class="tw-flex tw-items-center tw-mb-[12px] md:tw-mb-0">
  236. <div class="t16 tw-text-neutrals-900 tw-mr-[10px] md:t20 md:tw-mr-0">
  237. ${{ finalPrice }} {{ currencyName }}
  238. </div>
  239. </div>
  240. <div class="tw-flex tw-justify-center tw-items-center tw-w-full md:tw-w-fit">
  241. <like></like>
  242. <button
  243. class="tw-transition tw-whitespace-nowrap tw-body-4 tw-text-white tw-border tw-border-solid tw-border-primary-default tw-bg-primary-default tw-ml-[22px] tw-px-[24px] tw-py-[8.5px] tw-rounded-xl tw-w-full md:tw-body-2 md:tw-min-w-[130px] md:tw-max-w-[130px] md:tw-mt-0 disabled:tw-bg-neutral-100 disabled:tw-text-base-disable disabled:tw-border-neutral-200"
  244. @click="bookNow" :disabled="btnDisabled">
  245. {{ $t("Book Now") }}
  246. </button>
  247. </div>
  248. </div>
  249. </div>
  250. </section>
  251. <section
  252. class="sercion-4 tw-px-[30px] tw-grid tw-grid-cols-1 tw-gap-[40px] tw-z-[8] md:tw-px-[30px] xl:tw-px-0 xl:tw-col-start-1 xl:tw-row-start-4">
  253. <detailsModal :detail="content.details"></detailsModal>
  254. <cancellationPolicyModal :cancellationPolicy="content.cancellation_policy"></cancellationPolicyModal>
  255. </section>
  256. <section class="sercion-5 tw-hidden md:tw-px-[30px] xl:tw-px-0 xl:tw-block xl:tw-row-start-2 xl:tw-row-end-5">
  257. <div class="tw-mb-[40px]">
  258. <sidebarSelectOption :totalPrice="finalPrice" :currency="currencyName" :confirmationTime="content.confirmationTime">
  259. </sidebarSelectOption>
  260. </div>
  261. <sideBarMenu :fixBarList="fixBarList" :currStep="currStep"></sideBarMenu>
  262. </section>
  263. <v-dialog v-model="dialog" :width="423"
  264. @click:outside="colseDialog()">
  265. <v-card class="tw-p-[30px]">
  266. <v-spacer class="d-flex tw-justify-between align-center tw-mb-[30px]">
  267. <div class="tw-text-[20px] tw-text-black tw-font-bold">
  268. {{ $t("Remind") }}
  269. </div>
  270. <v-btn @click="colseDialog()" icon>
  271. <v-icon> mdi-close </v-icon>
  272. </v-btn>
  273. </v-spacer>
  274. <v-spacer class="tw-mb-[40px]">
  275. <div class="tw-text-[16px] tw-text-neutrals-800">
  276. {{$t("Your goods are of special size. Please contact ShowEasy service personnel (02) 2725-5000")}}
  277. </div>
  278. </v-spacer>
  279. <div class="tw-text-[18px] tw-rounded-[16px] tw-text-center">
  280. <span class="tw-text-primary-1 t18">{{countdown}}</span>s{{ $t("userProfile.unLinkOK") }}
  281. </div>
  282. </v-card>
  283. </v-dialog>
  284. <loading :isLoading="isLoading"></loading>
  285. </div>
  286. </template>
  287. <script>
  288. import Breadcrumbs from "@/components/Breadcrumbs";
  289. import slideshow from "@/components/swiper/serviceContent.vue";
  290. import detailsModal from "@/components/service/contentModal/DetailsModal.vue";
  291. import cancellationPolicyModal from "@/components/service/contentModal/cancellationPolicyModal.vue";
  292. import selectExhibition from "@/components/service/content/selectExhibition.vue";
  293. import selectExhibitionBooth from "@/components/service/content/selectExhibitionBooth.vue";
  294. import selectExhibitionService from "@/components/service/content/selectExhibitionService.vue";
  295. import quantitySelectGroup from "@/components/service/content/quantitySelectGroup.vue";
  296. import pickupInformation from "@/components/service/content/pickupInformation.vue";
  297. import faq from "@/components/service/content/faq.vue";
  298. import sidebarSelectOption from "@/components/service/content/sidebarSelectOption.vue";
  299. import sideBarMenu from "@/components/service/content/sideBarMenu.vue";
  300. import Swiper from "swiper/bundle";
  301. import { scrollama } from "scrollama";
  302. import mobileFixTopBar from "@/components/swiper/mobileFixTopBar.vue";
  303. import like from "@/components/newComponent/like/like.vue";
  304. import { filterData,dateIsInWeekend } from "~/utils/common";
  305. import loading from "@/components/newComponent/loading/loading.vue";
  306. export default {
  307. name: 'ServiceContent',
  308. layout: "login",
  309. auth: false,
  310. components: {
  311. Swiper,
  312. scrollama,
  313. Breadcrumbs,
  314. slideshow,
  315. detailsModal,
  316. cancellationPolicyModal,
  317. selectExhibition,
  318. selectExhibitionBooth,
  319. selectExhibitionService,
  320. quantitySelectGroup,
  321. pickupInformation,
  322. faq,
  323. sidebarSelectOption,
  324. sideBarMenu,
  325. mobileFixTopBar,
  326. like,
  327. loading,
  328. },
  329. data() {
  330. return {
  331. dialog: false,
  332. isLoading: false,
  333. showCardItem: false,
  334. pickupServiceShow: false,
  335. apiUrl: process.env.SERVICE_CONSOLE,
  336. btnDisabled: process.env.ENV == 'production',
  337. currStep: null,
  338. stickySwiper: null,
  339. content: {
  340. banners: [],
  341. country: null,
  342. city: null,
  343. name: "",
  344. highlights: '',
  345. details: '',
  346. cancellation_policy: "",
  347. saved: false,
  348. confirmation_time: 24,
  349. supplier: {
  350. logo: require('/assets/img/Footer.png'),
  351. brand: 'ShowEasy'
  352. },
  353. available_sections: null,
  354. timeStatus: 'active',
  355. dateStatus: 'active',
  356. times: [{
  357. start_time: '2023-02-06',
  358. end_time: '2023-03-06',
  359. },{
  360. start_time: '2023-02-06',
  361. end_time: '2023-03-06',
  362. },{
  363. start_time: '2023-02-06',
  364. end_time: '2023-03-06',
  365. }],
  366. start: '2023-02-06',
  367. end: '2023-06-06',
  368. faq: [],
  369. confirmationTime: '',
  370. additionalServices: [
  371. {
  372. name: '司機英文服務'
  373. },{
  374. name: '兒童安全座椅'
  375. },{
  376. name: '增加一個停靠點'
  377. },{
  378. name: '協助飯店入住(每個人,限接機)'
  379. }
  380. ],
  381. },
  382. list: [],
  383. choicesIndex: 0,
  384. countrycode: [],
  385. regionName: [],
  386. elementHeight: {
  387. details: null,
  388. cancellation_policy: null,
  389. faq: null,
  390. },
  391. seeMore: {
  392. details: true,
  393. cancellation_policy: true,
  394. },
  395. button: {
  396. details: true,
  397. cancellation_policy: true,
  398. },
  399. offset: {
  400. packageOptions: 0,
  401. faq: 0,
  402. },
  403. contentId: "",
  404. packageId: "",
  405. packageName: "",
  406. window: {
  407. width: 0,
  408. },
  409. fixBar: false,
  410. fixBarList: [
  411. { id: "packageOptions", title: "Package Options", show: true },
  412. { id: "serviceDetails", title: "Service Details", show: true },
  413. { id: "serviceDescription", title: "Service Description", show: true },
  414. { id: "cancellationPolicy", title: "Cancellation Policy", show: true },
  415. { id: "faq", title: "FAQ", show: false },
  416. { id: "contactUs", title: "Contact Us", show: true },
  417. ],
  418. activePackage: 0,
  419. totalPrice: 0,
  420. additionTotalPrice: [],
  421. customPlanPrice: [],
  422. selectDates: '',
  423. typeGroupList: [],
  424. selectQuantityList: [],
  425. selectYearList: [],
  426. selectMonthList: [],
  427. selectExhibitionList: [],
  428. selectAddressList: [],
  429. selectExhibitionServiceList: [{id: 0,show: true}],
  430. selectPackageList: [],
  431. quantitySelectList: [],
  432. deliveryType: '',
  433. expenseRules: [],
  434. finalPrice: "0",
  435. showServiceItem: 0,
  436. currencyName: '',
  437. currencyID: '',
  438. previewFile: '',
  439. countdown: 15,
  440. rulesShow: false,
  441. boothSelect: 0,
  442. };
  443. },
  444. async created() {
  445. this.isLoading = true;
  446. let arr = [];
  447. for(let i=1;i<11;i++){
  448. let target = {
  449. id: i+"",
  450. name: i+"",
  451. };
  452. arr.push(target);
  453. }
  454. this.selectQuantityList = arr;
  455. await this.getBanners();
  456. await this.getServiceData();
  457. await this.getExtensionYear();
  458. await this.getExtensionMonth();
  459. await this.getExhibitions();
  460. await this.getQuantitySelects();
  461. await this.getServiceItems();
  462. await this.getReceivingCitys();
  463. // await this.getFaq();
  464. await this.getPackages();
  465. await this.getInfoItem();
  466. // await this.addViewCount();
  467. // await this.getYouMightLikeData();
  468. // await this.getRegionName();
  469. // await this.getCountryCode();
  470. if (process.browser) {
  471. window.addEventListener("resize", this.handleResize);
  472. }
  473. this.handleResize();
  474. this.$nextTick(()=>{
  475. this.isLoading = false;
  476. });
  477. },
  478. mounted() {
  479. let vm = this;
  480. vm.contentId = vm.$route.params.id;
  481. vm.offset.packageOptions = vm.$refs.packageOptions.offsetTop;
  482. vm.offset.faq = vm.$refs.faq.offsetTop;
  483. vm.$nextTick(function () {
  484. // instantiate the scrollama
  485. const scrollama = require("scrollama");
  486. const scroller = scrollama();
  487. // setup the instance, pass callback functions
  488. scroller
  489. .setup({
  490. step: ".service-content .step",
  491. offset: 0.6,
  492. })
  493. .onStepEnter((response) => {
  494. // { element, index, direction }
  495. vm.currStep = response.element.id;
  496. let fb_messenger = document.querySelector(".fb_dialog_content");
  497. if (response.index > 3) {
  498. vm.$refs.stickySwiper.slideTo(4);
  499. } else {
  500. vm.$refs.stickySwiper.slideTo(0);
  501. }
  502. if (response.index >= 1 && response.index < 6) {
  503. vm.fixBar = true;
  504. if (fb_messenger) {
  505. fb_messenger.classList.add("hasBar");
  506. }
  507. } else {
  508. vm.fixBar = false;
  509. if (fb_messenger) {
  510. fb_messenger.classList.remove("hasBar");
  511. }
  512. }
  513. })
  514. .onStepExit((response) => {
  515. // { element, index, direction }
  516. vm.currStep = response.element.id;
  517. let fb_messenger = document.querySelector(".fb_dialog_content");
  518. if (response.index >= 1 && response.index < 6) {
  519. vm.fixBar = true;
  520. if (fb_messenger) {
  521. fb_messenger.classList.add("hasBar");
  522. }
  523. } else {
  524. vm.fixBar = false;
  525. if (fb_messenger) {
  526. fb_messenger.classList.remove("hasBar");
  527. }
  528. }
  529. });
  530. })
  531. },
  532. computed: {
  533. currency() {
  534. return this.$store.getters.getCurrency;
  535. },
  536. seeMoreDetailsText() {
  537. if (this.button.details == false) {
  538. return "See less";
  539. } else {
  540. return "See more";
  541. }
  542. },
  543. seeMoreCancellationPolicyText() {
  544. if (this.button.cancellation_policy == false) {
  545. return "See less";
  546. } else {
  547. return "See more";
  548. }
  549. },
  550. // finalPrice() {
  551. // let option = 0;
  552. // let custom = 0;
  553. // let addition = 0;
  554. // if (this.additionTotalPrice) {
  555. // this.additionTotalPrice.forEach((item) => {
  556. // addition += Number(item.total);
  557. // });
  558. // }
  559. // if (this.customPlanPrice) {
  560. // this.customPlanPrice.forEach((item) => {
  561. // custom += Number(item.total);
  562. // });
  563. // }
  564. // if (this.totalPrice) {
  565. // this.totalPrice.forEach((item) => {
  566. // option += Number(item.total);
  567. // });
  568. // }
  569. // if (this.currency == 'USD') {
  570. // return Number(addition + custom + option).toFixed(2).toLocaleString();
  571. // } else {
  572. // return Number(addition + custom + option).toLocaleString();
  573. // }
  574. // },
  575. },
  576. watch: {
  577. currency: {
  578. handler: function () {
  579. this.getServiceData();
  580. // this.getPackages();
  581. },
  582. },
  583. // activePackage: {
  584. // handler: function (newVal, oldVal) {
  585. // if (newVal !== oldVal) {
  586. // this.customPlanPrice = [];
  587. // this.totalPrice = [];
  588. // }
  589. // },
  590. // },
  591. // choicesIndex: {
  592. // handler: function (newVal, oldVal) {
  593. // if (newVal !== oldVal) {
  594. // this.customPlanPrice = [];
  595. // this.totalPrice = [];
  596. // }
  597. // },
  598. // }
  599. },
  600. destroyed() {
  601. if (process.browser) {
  602. window.removeEventListener("resize", this.handleResize);
  603. }
  604. },
  605. methods: {
  606. async getBanners() {
  607. await this.$axios.get(`/trending/api/Onsite/BannerFiles?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  608. .then((response) => {
  609. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  610. let data = response.data.DATA.rel
  611. if(data.length>0){
  612. this.content.banners = data.map((item) => {
  613. return {
  614. banner_id: item.FileID,
  615. image: item.FilePath,
  616. };
  617. });
  618. }
  619. }
  620. })
  621. .catch((error) => console.log(error));
  622. },
  623. async getExtensionYear() {
  624. await this.$axios.get(`/trending/api/Onsite/ExtensionYear?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  625. .then((response) => {
  626. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  627. let data = response.data.DATA.rel
  628. if(data.length>0){
  629. this.selectYearList = data.map((item) => {
  630. return {
  631. id: item.ArgumentID,
  632. name: item.ArgumentValue,
  633. };
  634. });
  635. }
  636. }
  637. })
  638. .catch((error) => console.log(error));
  639. },
  640. async getExtensionMonth() {
  641. await this.$axios.get(`/trending/api/Onsite/ExtensionMonth?Lang=${this.$i18n.localeProperties["langQuery"]}`)
  642. .then((response) => {
  643. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  644. let data = response.data.DATA.rel
  645. if(data.length>0){
  646. this.selectMonthList = data.map((item) => {
  647. return {
  648. id: item.ArgumentID,
  649. name: item.ArgumentValue,
  650. };
  651. });
  652. }
  653. }
  654. })
  655. .catch((error) => console.log(error));
  656. },
  657. async getExhibitions(){
  658. let select_year = "";
  659. let select_month = "";
  660. await this.$axios.get(`/trending/api/Onsite/Exhibitions?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}&Year=${select_year}&Month=${select_month}`)
  661. .then((response) => {
  662. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  663. let data = response.data.DATA.rel
  664. if(data.length>0){
  665. this.selectExhibitionList = data.map((item) => {
  666. return {
  667. id: item.ArgumentID,
  668. name: item.ArgumentValue,
  669. };
  670. });
  671. }
  672. }
  673. })
  674. .catch((error) => console.log(error));
  675. },
  676. async getServiceItems() {
  677. this.showCardItem = false;
  678. await this.$axios
  679. .get(`trending/api/Onsite/ServiceItems?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  680. .then((response) => {
  681. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  682. let data = response.data.DATA.rel
  683. if(data.length>0){
  684. this.typeGroupList = data.map((item) => {
  685. if(item.ItemType=="02"){
  686. this.showCardItem = true;
  687. }
  688. return {
  689. package_id: item.ArgumentID,
  690. name: item.ArgumentValue,
  691. itemType: item.ItemType
  692. };
  693. });
  694. }
  695. }
  696. })
  697. .catch((error) => console.log(error));
  698. },
  699. // async getFaq() {
  700. // await this.$axios
  701. // .get(
  702. // `${this.apiUrl}/user-services/faqs?service_id=${this.$route.params.id}&lang_code=${this.$i18n.localeProperties["langQuery"]}`
  703. // )
  704. // .then((res) => {
  705. // this.content.faq = res.data;
  706. // })
  707. // .catch((error) => console.log(error));
  708. // },
  709. async getPackages() {
  710. await this.$axios
  711. .get(`trending/api/Onsite/PackingTypes?Lang=${this.$i18n.localeProperties["langQuery"]}`)
  712. .then((response) => {
  713. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  714. let data = response.data.DATA.rel
  715. if(data.length>0){
  716. this.selectPackageList = data.map((item) => {
  717. return {
  718. id: item.ArgumentID,
  719. name: item.ArgumentValue,
  720. };
  721. });
  722. }
  723. }
  724. })
  725. .catch((error) => console.log(error));
  726. },
  727. async getQuantitySelects() {
  728. await this.$axios
  729. .get(`trending/api/Onsite/TruckTypes?Lang=${this.$i18n.localeProperties["langQuery"]}`)
  730. .then((response) => {
  731. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  732. let data = response.data.DATA.rel
  733. if(data.length>0){
  734. this.quantitySelectList = data;
  735. }
  736. }
  737. })
  738. .catch((error) => console.log(error));
  739. },
  740. async getReceivingCitys() {
  741. await this.$axios
  742. .get(`trending/api/Onsite/ReceivingCitys?Lang=${this.$i18n.localeProperties["langQuery"]}`)
  743. .then((response) => {
  744. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  745. let data = response.data.DATA.rel
  746. if(data.length>0){
  747. this.selectAddressList = data.map((item) => {
  748. return {
  749. id: item.ArgumentID,
  750. name: item.ArgumentValue,
  751. };
  752. });
  753. }
  754. }
  755. })
  756. .catch((error) => console.log(error));
  757. },
  758. async getServiceData() {
  759. await this.$axios
  760. .get(`/trending/api/Onsite/Info?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  761. .then((response) => {
  762. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  763. let data = response.data.DATA.rel
  764. console.log(data)
  765. if(data){
  766. this.content.name = data.ServiceName;
  767. this.content.highlights = data.Features;
  768. this.content.details = data.Details;
  769. this.content.cancellation_policy = data.CancelPolicy;
  770. this.content.faq = data.FQAs;
  771. this.currencyName = data.CurrencyName;
  772. this.currencyID = data.CurrencyID;
  773. this.previewFile = data.PreviewFile;
  774. this.finalPrice = data.MinPrice == null ? "0" : data.MinPrice +"";
  775. this.content.supplier.brand = data.SupplierName;
  776. this.content.supplier.logo = data.SupplierLogo;
  777. for(let i=0;i<this.fixBarList.length;i++){
  778. if(this.fixBarList[i].id=="faq"){
  779. if(data.FQAs && data.FQAs.length>0){
  780. this.fixBarList.show = true;
  781. }else{
  782. this.fixBarList.show = false;
  783. }
  784. break;
  785. }
  786. }
  787. this.content.confirmationTime = data.ConfirmDays;
  788. }
  789. }
  790. // this.content.country = res.data.country;
  791. // this.content.city = res.data.city;
  792. // this.content.highlights = res.data.highlights;
  793. // this.content.details = res.data.details;
  794. // this.content.cancellation_policy = res.data.cancellation_policy;
  795. // this.content.supplier = res.data.supplier;
  796. // this.content.available_sections = res.data.available_sections;
  797. // this.content.times = res.data.available_sections.times;
  798. // this.content.timeStatus = res.data.available_sections.time_status;
  799. // this.content.dateStatus = res.data.available_sections.date_status;
  800. // this.content.start = res.data.available_sections.start;
  801. // this.content.end = res.data.available_sections.end;
  802. // this.content.payment_currency = res.data.payment_currency;
  803. // this.content.confirmationTime = res.data.confirmation_time.toString();
  804. })
  805. .catch((error) => console.log(error));
  806. },
  807. //攤位數量
  808. getBoothSelect(value){
  809. this.boothSelect = value;
  810. console.log("攤位數:" + this.boothSelect);
  811. },
  812. //抓卡車相關數據
  813. async getInfoItem() {
  814. await this.$axios
  815. .get(`/trending/api/Onsite/InfoItem?Lang=${this.$i18n.localeProperties["langQuery"]}&ServiceID=${this.$route.params.id}`)
  816. .then((response) => {
  817. if(response && response.data && response.data.DATA && response.data.DATA.rel){
  818. let data = response.data.DATA.rel
  819. console.log(data);
  820. if(data.length>0){
  821. this.expenseRules = data;
  822. }
  823. }
  824. })
  825. .catch((error) => console.log(error));
  826. },
  827. async addViewCount() {
  828. let Obj = {
  829. service_id: `${this.$route.params.id}`,
  830. lang_code: `${this.$i18n.localeProperties["langQuery"]}`,
  831. add_number: 1,
  832. };
  833. await this.$axios
  834. .put(`${this.apiUrl}/user-services/view-counts`, Obj)
  835. .then((res) => { })
  836. .catch((error) => console.log(error));
  837. },
  838. opendetail() {
  839. if (this.window.width >= 1366) {
  840. this.button.details = !this.button.details;
  841. } else {
  842. this.$modal.show("Details");
  843. }
  844. },
  845. openCancellationPolicy() {
  846. if (this.window.width >= 1366) {
  847. this.button.cancellation_policy = !this.button.cancellation_policy;
  848. } else {
  849. this.$modal.show("cancellationPolicy");
  850. }
  851. },
  852. handleResize() {
  853. if (process.browser) {
  854. this.window.width = window.innerWidth;
  855. }
  856. },
  857. bookNow() {
  858. let validators = this.$refs.ref_selectExhibition.validators();
  859. console.log("this.$refs.ref_selectExhibition:" + this.$refs.ref_selectExhibition);
  860. if(validators==false){
  861. return false;
  862. }
  863. if(this.selectExhibitionServiceList.length>0){
  864. for(let i=0;i<this.selectExhibitionServiceList.length;i++){
  865. let ref = eval("this.$refs.ref_selectExhibitionitem"+this.selectExhibitionServiceList[i].id)[0];
  866. if(ref !=undefined){
  867. validators = ref.validators();
  868. if(validators==false){
  869. ref.show = true;
  870. return false;
  871. }
  872. }
  873. }
  874. }
  875. let selectExhibitionData = this.$refs.ref_selectExhibition.formData;
  876. let selectExhibitionServiceData = [];
  877. if(this.selectExhibitionServiceList.length>0){
  878. for(let i=0;i<this.selectExhibitionServiceList.length;i++){
  879. let ref = eval("this.$refs.ref_selectExhibitionitem"+this.selectExhibitionServiceList[i].id)[0];
  880. if(ref !=undefined){
  881. let target = ref.formData;
  882. selectExhibitionServiceData.push(target);
  883. }
  884. }
  885. }
  886. let quantityData = this.$refs.ref_quantitySelectGroup.formData;
  887. if(quantityData.selectList.length>0){
  888. if(this.showCardItem){
  889. validators = this.$refs.ref_quantitySelectGroup.validators();
  890. if(validators==false){
  891. this.pickupServiceShow = true;
  892. return false;
  893. }
  894. validators = this.$refs.ref_pickupService.validators();
  895. if(validators==false){
  896. this.pickupServiceShow = true;
  897. return false;
  898. }
  899. }
  900. }
  901. // let pickupServiceData = this.$refs.ref_pickupService.formData;
  902. if(this.rulesShow){
  903. this.ChangeCosts(null);
  904. return false;
  905. }
  906. this.$router.push(
  907. {
  908. path: this.localePath("/service/checkout/" + this.$route.params.id),
  909. //携带需要传递的参数
  910. query: {
  911. selectExhibitionData: encodeURIComponent(JSON.stringify(selectExhibitionData)),
  912. selectExhibitionServiceData: encodeURIComponent(JSON.stringify(selectExhibitionServiceData)),
  913. quantityData: encodeURIComponent(JSON.stringify(quantityData)),
  914. // pickupServiceData: encodeURIComponent(JSON.stringify(pickupServiceData)),
  915. totalPrice: this.totalPrice,
  916. currencyName: encodeURIComponent(this.currencyName),
  917. previewFile: encodeURIComponent(this.previewFile),
  918. title: encodeURIComponent(this.content.name)
  919. }
  920. });
  921. },
  922. // choicesIdx(data) {
  923. // let vm = this;
  924. // vm.choicesIndex = data;
  925. // },
  926. addExhibitionService(){
  927. const arr = this.selectExhibitionServiceList.map(({id})=> id);
  928. let max = arr.length>0 ? Math.max.apply(null, arr) : 0;
  929. this.selectExhibitionServiceList.push({id: max+1,show:true});
  930. this.showServiceItem = max+1;
  931. },
  932. delExhibitionService(value){
  933. if(this.selectExhibitionServiceList.length>0){
  934. for(let i=0;i<this.selectExhibitionServiceList.length;i++){
  935. if(value == this.selectExhibitionServiceList[i].id){
  936. // let index = this.selectExhibitionServiceList.indexOf(this.selectExhibitionServiceList[i]);
  937. this.selectExhibitionServiceList.splice(i, 1);
  938. break;
  939. }
  940. }
  941. }
  942. this.ChangeCosts(null);
  943. },
  944. deletePickupSerivce(){
  945. this.pickupServiceShow = false;
  946. if(this.$refs.ref_quantitySelectGroup){
  947. this.$refs.ref_quantitySelectGroup.clearAll();
  948. }
  949. },
  950. //展館服務(包裝、尺寸、數量、服務類型)
  951. ChangeCosts(data){
  952. console.log("展館服務數量:" + data.value.quantity);
  953. console.log(data)
  954. let totalPrice = 0;
  955. this.totalPrice = 0;
  956. this.rulesShow = false;
  957. // let selectExhibitionData = this.$refs.ref_selectExhibition.formData;
  958. let selectExhibitionServiceData = [];
  959. if(this.selectExhibitionServiceList.length>0){
  960. for(let i=0;i<this.selectExhibitionServiceList.length;i++){
  961. let ref = eval("this.$refs.ref_selectExhibitionitem"+this.selectExhibitionServiceList[i].id)[0];
  962. if(ref !=undefined){
  963. let target = ref.formData;
  964. selectExhibitionServiceData.push(target);
  965. }
  966. }
  967. }
  968. if(selectExhibitionServiceData.length>0){
  969. for(let i=0;i<selectExhibitionServiceData.length;i++){
  970. let arr = selectExhibitionServiceData[i].selectServiceItems;
  971. if(arr.length>0){
  972. for(let j=0;j<arr.length;j++){
  973. if(arr[j].itemType == "01"){
  974. totalPrice += this.stackerCostRules(selectExhibitionServiceData[i],arr[j]);
  975. if(totalPrice==-1){
  976. this.totalPrice = 0;
  977. this.finalPrice = "0";
  978. this.rulesShow = true;
  979. return false;
  980. }
  981. }else if(arr[j].itemType == "02"){
  982. }else if(arr[j].itemType == "03" || arr[j].itemType == "04" || arr[j].itemType == "05" || arr[j].itemType == "06"){
  983. totalPrice += this.OtherCostRules(selectExhibitionServiceData[i],arr[j]);
  984. if(totalPrice==-1){
  985. this.totalPrice = 0;
  986. this.finalPrice = "0";
  987. this.rulesShow = true;
  988. return false;
  989. }
  990. }
  991. }
  992. }
  993. }
  994. }
  995. let quantityData = this.$refs.ref_quantitySelectGroup.formData;
  996. if(quantityData.selectList.length>0){
  997. totalPrice += this.TruckCostRules();
  998. }
  999. this.totalPrice = Math.ceil(totalPrice);
  1000. this.finalPrice = Math.ceil(Number(totalPrice)).toLocaleString();
  1001. },
  1002. // 堆高機
  1003. stackerCostRules(data1,data2){
  1004. //這邊這邊是這個
  1005. console.log('expenseRules', this.expenseRules);
  1006. console.log('data1', data1);
  1007. console.log('data2', data2);
  1008. // if(this.expenseRules.ItemType == "01"){
  1009. // }
  1010. let price = 0;
  1011. let tmpWeight = 0;//Number(data1.weight)/1000;
  1012. // 材積重 長x寬x高/6000 得到噸
  1013. if((data1.length =="" && data1.width=="" && data1.height=="") && data1.weight!=""){
  1014. tmpWeight = Number(data1.weight)/1000; // Number() => 將字串轉為數值!!
  1015. } //長(沒值),寬(沒值),高(沒值) 但重量(有值) => 總噸數 = 重量(公斤)/1000!!
  1016. else if((data1.length !="" && data1.width!="" && data1.height!="") && data1.weight==""){
  1017. tmpWeight = Number(data1.length)*Number(data1.width)*Number(data1.height)/6000/1000;
  1018. } //長(有值),寬(有值),高(有值) 但重量(沒值) => 總噸數 = 長*寬*高/6000/1000!!
  1019. //長(有值),寬(有值),高(有值) 但重量(有值) => 總噸數 = 長*寬*高/6000/1000!!
  1020. else if(data1.length !="" && data1.width!="" && data1.height!="" && data1.weight!=""){
  1021. let volumeWeight = Number(data1.length)*Number(data1.width)*Number(data1.height)/6000/1000;
  1022. // 比較誰大 (材積重與客戶給出的公斤重比較)!!
  1023. if(volumeWeight>Number(data1.weight)/1000){
  1024. tmpWeight = volumeWeight; //若材積重 > 客戶給的公斤重 => 總噸數 = 材積重!!
  1025. }else{
  1026. tmpWeight = Number(data1.weight)/1000; //若材積重 < 客戶給的公斤重 => 總噸數 = 客戶給的公斤重!!
  1027. }
  1028. }
  1029. //判斷 => 若長 > 1000 或 寬 > 1000 或 高 > 330,則顯示提醒dialog!!
  1030. if(Number(data1.length) > 1000 || Number(data1.width) > 1000 || Number(data1.height)>330){
  1031. this.dialog = true;
  1032. this.openTimer();
  1033. return -1;
  1034. }
  1035. //防呆 => 若總噸數為0,則總金額為0 !!
  1036. if(tmpWeight==0){
  1037. return price;
  1038. }
  1039. if(this.expenseRules.length>0){
  1040. for(let i=0;i<this.expenseRules.length;i++){
  1041. let subArr = this.expenseRules[i].StackerCostRules;
  1042. console.log('subArr', subArr)
  1043. if(this.expenseRules[i].Guid == data2.package_id && subArr.length>0){
  1044. for(let j=0;j<subArr.length;j++){
  1045. // 需要判斷按數量還是重量
  1046. if(subArr[j].Weight_Min!="" && subArr[j].Weight_Max!=""){
  1047. if(Number(subArr[j].Weight_Min)<=tmpWeight && Number(subArr[j].Weight_Max)>=tmpWeight){
  1048. if(subArr[j].PricingMode=="N"){
  1049. price = subArr[j].Price;
  1050. }else{
  1051. price = subArr[j].Price*tmpWeight;
  1052. }
  1053. break;
  1054. }
  1055. }
  1056. }
  1057. break;
  1058. }
  1059. }
  1060. }
  1061. let num = (data1.quantity =="" || data1.quantity =="0") ? 0 : Number(data1.quantity);
  1062. price = price*num;
  1063. return price;
  1064. },
  1065. TruckCostRules(){
  1066. let price = 0;
  1067. let quantityData = this.$refs.ref_quantitySelectGroup.formData;
  1068. let pickupServiceData = this.$refs.ref_pickupService.formData;
  1069. if(this.expenseRules.length>0){
  1070. let list = filterData({ItemType: '02'},this.expenseRules);
  1071. if(list.length>0){
  1072. if(list[0].TruckCostRules.length>0 && quantityData.selectList.length>0 && pickupServiceData.address1!="" && pickupServiceData.address1!="0"){
  1073. price += this.updateForData(quantityData.selectList,list[0].TruckCostRules,pickupServiceData.address1);
  1074. }
  1075. if(list[0].TruckMarkupByModel.length>0 && quantityData.truckList.length>0){
  1076. price += this.updateForData(quantityData.truckList,list[0].TruckMarkupByModel,null);
  1077. }
  1078. // 壓車費
  1079. if(list[0].TruckEscortCostRules.length>0 && pickupServiceData.delivery_type=="2" && quantityData.selectList.length>0
  1080. && list[0].EscortFreeCityID!="" && pickupServiceData.address1!="0"){
  1081. price += this.updateForData(quantityData.selectList,list[0].TruckEscortCostRules,list[0].EscortFreeCityID);
  1082. }
  1083. if(list[0].TruckHolidayPay.length>0 && pickupServiceData.select_date!=""){
  1084. let inWeekend = dateIsInWeekend(pickupServiceData.select_date);
  1085. if(inWeekend==5 && pickupServiceData.delivery_type=="2"){
  1086. price += this.updateForData(quantityData.selectList,list[0].TruckHolidayPay,null);
  1087. }else if(inWeekend==6 && pickupServiceData.delivery_type=="2"){
  1088. price += this.updateForData(quantityData.selectList,list[0].TruckHolidayPay,null)*2;
  1089. }else if(inWeekend==0 && pickupServiceData.delivery_type=="2"){
  1090. price += this.updateForData(quantityData.selectList,list[0].TruckHolidayPay,null);
  1091. }else if(inWeekend==6 && pickupServiceData.delivery_type=="1"){
  1092. price += this.updateForData(quantityData.selectList,list[0].TruckHolidayPay,null);
  1093. }else if(inWeekend==0 && pickupServiceData.delivery_type=="1"){
  1094. price += this.updateForData(quantityData.selectList,list[0].TruckHolidayPay,null);
  1095. }
  1096. }
  1097. }
  1098. }
  1099. return price;
  1100. },
  1101. updateForData(data1,data2,address1){
  1102. let price = 0;
  1103. if(data1.length>0 && data2.length>0){
  1104. for(let n=0;n<data1.length;n++){
  1105. let truckID = data1[n].id;
  1106. let num = data1[n].number;
  1107. for(let i=0;i<data2.length;i++){
  1108. if(data2[i].CityID!=undefined && data2[i].CityID!="" && data2[i].TruckID!=""){
  1109. if(data2[i].CityID==address1 && data2[i].TruckID == truckID){
  1110. price += data2[i].Price*num;
  1111. break;
  1112. }
  1113. }else if(data2[i].CityID ==undefined && data2[i].TruckID!=""){
  1114. if(data2[i].TruckID == truckID){
  1115. price += data2[i].Price*num;
  1116. break;
  1117. }
  1118. }
  1119. }
  1120. }
  1121. }
  1122. return price;
  1123. },
  1124. OtherCostRules(data1,data2){
  1125. console.log('OtherCostRules data1: ',data1)
  1126. console.log('OtherCostRules data2: ',data2)
  1127. let price = 0;
  1128. let tmpValue = 0;
  1129. if(data1.length =="" && data1.width=="" && data1.height==""){
  1130. return price;
  1131. }else{
  1132. tmpValue = Number(data1.length)*Number(data1.width)*Number(data1.height)/1000000;
  1133. }
  1134. if(Number(data1.length) > 1000 || Number(data1.width) > 1000 || Number(data1.height)>330){
  1135. this.dialog = true;
  1136. this.openTimer();
  1137. return -1;
  1138. }
  1139. if(this.expenseRules.length>0){
  1140. for(let i=0;i<this.expenseRules.length;i++){
  1141. let subArr = this.expenseRules[i].OtherCostRules;
  1142. if(this.expenseRules[i].Guid == data2.package_id && subArr.length>0){
  1143. for(let j=0;j<subArr.length;j++){
  1144. if(subArr[j].Unit_Min!=""){
  1145. if(Number(subArr[j].Unit_Min)<tmpValue){
  1146. price = subArr[j].Price*tmpValue;
  1147. }else{
  1148. price = subArr[j].Price*subArr[j].Unit_Min;
  1149. }
  1150. break;
  1151. }
  1152. }
  1153. break;
  1154. }
  1155. }
  1156. }
  1157. let num = (data1.quantity =="" || data1.quantity =="0") ? 0 : Number(data1.quantity);
  1158. price = price*num;
  1159. return price;
  1160. },
  1161. colseDialog(){
  1162. this.dialog = false;
  1163. },
  1164. openTimer(){
  1165. this.countdown = 15;
  1166. this.timer = setInterval(() => {
  1167. if (this.countdown > 0) {
  1168. this.countdown--;
  1169. } else {
  1170. clearInterval(this.timer);
  1171. this.dialog = false;
  1172. }
  1173. }, 1000);
  1174. },
  1175. },
  1176. };
  1177. </script>
  1178. <style lang="scss" scoped>
  1179. :deep() {
  1180. // .serviceDetails,
  1181. // .cancellationPolicy {
  1182. // p {
  1183. // margin-bottom: 6px;
  1184. // }
  1185. // }
  1186. }
  1187. .service-content {
  1188. .serviceDetails img {
  1189. width: 100%;
  1190. height: auto;
  1191. }
  1192. .fix-right {
  1193. position: fixed;
  1194. top: 120px;
  1195. right: 0 px;
  1196. max-width: 400px;
  1197. height: auto;
  1198. z-index: 100;
  1199. }
  1200. .title-icon-left {
  1201. background-position: left 0px center;
  1202. }
  1203. ul {
  1204. padding-left: 24px;
  1205. }
  1206. img {
  1207. // image-rendering: pixelated;
  1208. }
  1209. }
  1210. .seeMore {
  1211. &-hide {
  1212. position: relative;
  1213. max-height: 295px;
  1214. overflow: hidden;
  1215. &::after {
  1216. content: "";
  1217. display: block;
  1218. position: absolute;
  1219. background: url("~/assets/img/gradient_white.png") repeat-x left bottom;
  1220. width: 100%;
  1221. height: 130px;
  1222. left: 0;
  1223. bottom: 0;
  1224. z-index: 1;
  1225. transition: bottom 0.5s;
  1226. }
  1227. }
  1228. &-show {
  1229. position: relative;
  1230. max-height: 100%;
  1231. overflow: initial;
  1232. &::after {
  1233. display: none;
  1234. }
  1235. }
  1236. @media screen and (min-width: 1366px) {
  1237. position: relative;
  1238. display: flex;
  1239. align-items: center;
  1240. justify-content: center;
  1241. &::after {
  1242. content: "";
  1243. display: inline-block;
  1244. position: relative;
  1245. background-image: url("~/assets/svg/arrow-down-primary.svg");
  1246. background-position: center center;
  1247. background-repeat: no-repeat;
  1248. background-size: 100%;
  1249. width: 9px;
  1250. height: 6px;
  1251. margin-left: 16px;
  1252. }
  1253. &.open {
  1254. &::after {
  1255. transform: rotate(180deg);
  1256. }
  1257. }
  1258. }
  1259. }
  1260. .section-7 {
  1261. >div {
  1262. box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.25), 0px 1px 2px rgba(0, 0, 0, 0.1);
  1263. }
  1264. }
  1265. .tablecss{
  1266. line-height: 36px;
  1267. text-align: center;
  1268. color: #343434;
  1269. // border-radius: 10px;
  1270. }
  1271. table{
  1272. border: 1px solid #cecece;
  1273. border-collapse: separate;
  1274. border-radius: 10px;
  1275. text-align: center;
  1276. border-spacing: 0px;
  1277. // padding: 10px;
  1278. }
  1279. table thead{
  1280. border-radius: 10px;
  1281. }
  1282. th{
  1283. border: 1px solid #343434;
  1284. text-align: center;
  1285. }
  1286. td{
  1287. border-top: 1px solid #cecece;
  1288. text-align: center;
  1289. }
  1290. table thead>tr:first-of-type>th:first-of-type{
  1291. border-top-left-radius: 10px;
  1292. }
  1293. table thead>tr:first-of-type>th:last-of-type{
  1294. border-top-right-radius: 10px;
  1295. }
  1296. table tfoot>tr:last-of-type>td:first-of-type{
  1297. border-bottom-left-radius: 10px;
  1298. }
  1299. table tfoot>tr:last-of-type>td:last-of-type{
  1300. border-bottom-right-radius: 10px;
  1301. }
  1302. table::before{
  1303. border-radius: 10px;
  1304. }
  1305. // table tr:first-child th:first-child {
  1306. // border-top-left-radius: 10px; /* 设置table左下圆角 */
  1307. // }
  1308. // table tr:first-child th:last-child {
  1309. // border-top-right-radius: 10px; /* 设置table右下圆角 */
  1310. // }
  1311. table tr:last-child td:first-child {
  1312. border-bottom-left-radius: 10px; /* 设置table左下圆角 */
  1313. }
  1314. table tr:last-child td:last-child {
  1315. border-bottom-right-radius: 10px; /* 设置table右下圆角 */
  1316. }
  1317. </style>