PcHeader.vue 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539
  1. <template>
  2. <header>
  3. <div class="topbar com-margin-auto com-flex com-width-1400">
  4. <nuxt-link :to="{ name: 'index' }">
  5. <img
  6. src="@/assets/img/logo.png"
  7. alt="PromoCollection Logo"
  8. id="logo" />
  9. </nuxt-link>
  10. <div class="search-input">
  11. <el-input
  12. v-model="keyword"
  13. placeholder="Search item here"
  14. @focus="focus"
  15. @blur="blur"
  16. @keyup.enter.native="goSearchResultPage">
  17. <i
  18. slot="suffix"
  19. class="el-input__icon el-icon-search"
  20. @click="goSearchResultPage"></i>
  21. </el-input>
  22. <div
  23. v-loading="loading"
  24. class="search-detail flex column stretch"
  25. :style="{ display: showType }">
  26. <div
  27. class="flex-auto flex center stretch no-result"
  28. v-if="!loading && result.cate.length < 1 && productsList.length < 1">
  29. No results found for “{{ keyword }}”
  30. </div>
  31. <div
  32. v-else
  33. class="flex-auto flex stretch"
  34. style="overflow: hidden">
  35. <div class="category-list flex column start stretch">
  36. <p class="autocomplete-title sub">CATEGORIES</p>
  37. <ul class="stretch">
  38. <li
  39. v-for="item in result.firstCate"
  40. :key="item.id"
  41. class="flex column stretch">
  42. <nuxt-link
  43. :to="{
  44. name: 'category-firstCategory',
  45. params: {
  46. firstCategory: item.name.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  47. },
  48. }">
  49. <p>{{ item.name }}</p>
  50. </nuxt-link>
  51. </li>
  52. <p
  53. v-if="result.subCate.length"
  54. class="autocomplete-title">
  55. SUB CATEGORIES
  56. </p>
  57. <li
  58. v-for="item in result.subCate"
  59. :key="item.id"
  60. class="flex column stretch">
  61. <nuxt-link
  62. v-if="item.lev === 2"
  63. :to="{
  64. name: 'category-firstCategory-secondCategory',
  65. params: {
  66. firstCategory: item.parentName.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  67. secondCategory: item.name.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  68. },
  69. }">
  70. <p>{{ item.name }}</p>
  71. </nuxt-link>
  72. <nuxt-link
  73. v-else
  74. :to="{
  75. name: 'category-firstCategory-secondCategory-thirdCategory',
  76. params: {
  77. firstCategory: item.grandName.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  78. secondCategory: item.parentName.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  79. thirdCategory: item.name.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  80. },
  81. }">
  82. <p>{{ item.name }}</p>
  83. </nuxt-link>
  84. </li>
  85. </ul>
  86. </div>
  87. <div class="product-list flex-auto flex column stretch">
  88. <div class="flex between start">
  89. <p class="autocomplete-title">PRODUCTS</p>
  90. <nuxt-link
  91. v-if="result.total"
  92. :to="{
  93. name: 'category-searchResult',
  94. query: { keyword: keyword },
  95. }">
  96. <div class="seeAllResult">Show all {{ result.total }} Results</div>
  97. </nuxt-link>
  98. </div>
  99. <ul
  100. class="flex-auto flex column stretch"
  101. style="overflow-y: auto">
  102. <li
  103. v-for="item in productsList"
  104. :key="item.id">
  105. <nuxt-link
  106. :to="{
  107. name: 'product-code',
  108. params: { code: item.product_code },
  109. }">
  110. <img
  111. :src="
  112. item.image && !$mediaRegExp.test(item.image)
  113. ? $OSS_PREFIX + item.image
  114. : $utils.generateResizedImageUrl(item.image, 100)
  115. "
  116. alt="" />
  117. <div class="product-info">
  118. <p style="width: 94%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
  119. {{ item.alias_name || item.product_name }}
  120. </p>
  121. <p>{{ item.product_code }}</p>
  122. </div>
  123. </nuxt-link>
  124. </li>
  125. <div
  126. class="no-result"
  127. v-if="!loading && productsList.length < 1">
  128. No results found for “{{ keyword }}”
  129. </div>
  130. </ul>
  131. </div>
  132. </div>
  133. <div class="sth-else">
  134. <span>Can't find what you're looking for?</span>
  135. <nuxt-link
  136. :to="{
  137. name: 'news-newsName',
  138. params: { newsName: 'indent-ideas', id: indentIdeasArticle.id },
  139. hash: '#formTag',
  140. }">
  141. click here
  142. </nuxt-link>
  143. </div>
  144. </div>
  145. </div>
  146. <div
  147. class="topbar-item com-flex"
  148. style="cursor: default"
  149. v-if="email">
  150. <img
  151. src="@/assets/img/help.png"
  152. alt="help" />
  153. <div class="topbar-item-right com-flex-item">
  154. <p style="margin-bottom: 6px">(+44)203 916 5098</p>
  155. <p>info@promocollection.uk</p>
  156. </div>
  157. </div>
  158. <div class="topbar-item com-flex">
  159. <div
  160. class="topbar-item com-flex"
  161. v-if="!email">
  162. <img src="@/assets/img/login.png" />
  163. <div class="topbar-item-right com-flex-item">
  164. <p @click="openDialog">Login</p>
  165. </div>
  166. </div>
  167. <div
  168. class="topbar-item"
  169. v-else>
  170. <el-popover
  171. placement="bottom-end"
  172. width="292"
  173. trigger="click"
  174. ref="userPopover">
  175. <div
  176. slot="reference"
  177. class="topbar-item-right-myAccount">
  178. <!-- <div class="greeting">
  179. Hello {{ $store.state.userInfo.contacts }}
  180. </div> -->
  181. <div class="flex center">
  182. <img src="@/assets/img/login.png" />
  183. <p>Hello, {{ $store.state.userInfo.contacts }}</p>
  184. <span class="el-icon-caret-bottom"></span>
  185. </div>
  186. </div>
  187. <div
  188. class="user-menu-panel flex column center"
  189. @click="closePopoverAndNavigate">
  190. <!-- <div class="greeting">
  191. Hello {{ $store.state.userInfo.contacts }}
  192. </div> -->
  193. <div class="user-menu-wrap">
  194. <div class="user-menu">
  195. <div class="menu-title">Client Portal</div>
  196. <!-- <div class="sub-menu">
  197. <nuxt-link
  198. :to="{
  199. path: '/home/myDetail',
  200. query: { type: 'enquiry' },
  201. }">
  202. <div class="flex">
  203. <div class="icon order"></div>
  204. <div class="sub-title">My Enquires</div>
  205. </div>
  206. </nuxt-link>
  207. </div> -->
  208. <div class="sub-menu">
  209. <nuxt-link
  210. :to="{
  211. path: '/home/myDetail',
  212. query: { type: 'all-orders' },
  213. }">
  214. <div class="flex">
  215. <div class="icon order"></div>
  216. <div class="sub-title">My Orders</div>
  217. </div>
  218. </nuxt-link>
  219. </div>
  220. <div style="height: 4px; width: 1px"></div>
  221. <div class="menu-title">Marketing Resources</div>
  222. <!-- <div class="sub-menu">
  223. <nuxt-link to="/home/video">
  224. <div class="flex">
  225. <div class="icon video"></div>
  226. <div class="sub-title">Videos</div>
  227. </div>
  228. </nuxt-link>
  229. </div> -->
  230. <!-- <div class="sub-menu">
  231. <a
  232. href="https://www.flipsnack.com/promocollection/"
  233. target="_blank">
  234. <div class="flex">
  235. <div class="icon book"></div>
  236. <div class="sub-title">Catalogue</div>
  237. </div>
  238. </a>
  239. </div> -->
  240. <div class="sub-menu">
  241. <nuxt-link to="/media">
  242. <div class="flex">
  243. <div class="icon book"></div>
  244. <div class="sub-title">Media Centre</div>
  245. </div>
  246. </nuxt-link>
  247. </div>
  248. <div class="sub-menu">
  249. <a href="mailto:Info@promocollection.uk?subject=Sample%20Request">
  250. <div class="flex">
  251. <div class="icon mail"></div>
  252. <div class="sub-title">Sample Request</div>
  253. </div>
  254. </a>
  255. </div>
  256. <div class="sub-menu">
  257. <a href="mailto:Info@promocollection.uk?subject=Free%20Mockup%20Request">
  258. <div class="flex">
  259. <div class="icon mail"></div>
  260. <div class="sub-title">Mockup Request</div>
  261. </div>
  262. </a>
  263. </div>
  264. <div class="menu-title">
  265. <nuxt-link
  266. :to="{
  267. path: '/home/myDetail',
  268. query: { type: 'profile' },
  269. }">
  270. My Profile
  271. </nuxt-link>
  272. </div>
  273. <div class="menu-title">
  274. <div
  275. class="btn-logout"
  276. @click="logout">
  277. Sign Out
  278. </div>
  279. </div>
  280. </div>
  281. </div>
  282. </div>
  283. </el-popover>
  284. </div>
  285. </div>
  286. </div>
  287. <nav>
  288. <ul class="com-width-1400 com-minwidth-1024 com-margin-auto">
  289. <li class="nav-list">
  290. <div class="nav-list-title">
  291. <span
  292. class="shopProducts"
  293. @click.stop="openShopProduct">
  294. Shop Products
  295. <i :class="isShopBlock ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
  296. </span>
  297. </div>
  298. <Transition name="category">
  299. <div
  300. class="nav-menu border-radius"
  301. v-show="isShopBlock"
  302. @click="closeAllBlock">
  303. <div class="nav-menu-content">
  304. <div
  305. class="nav-menu-item"
  306. v-for="item1 in categoryList"
  307. :key="item1.id">
  308. <div class="primary-classification">
  309. <nuxt-link
  310. :to="{
  311. name: 'category-firstCategory',
  312. params: {
  313. firstCategory: item1.name.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  314. },
  315. }">
  316. <div class="menu-item-icon">
  317. <img
  318. :src="
  319. item1.style && !$mediaRegExp.test(item1.style) ? $OSS_PREFIX + item1.style : item1.style
  320. "
  321. alt="" />
  322. </div>
  323. <div class="menu-item-title">
  324. {{ item1.name }}
  325. </div>
  326. </nuxt-link>
  327. <div class="menu-separator"></div>
  328. </div>
  329. <div
  330. class="secondary-classification"
  331. v-for="item2 in item1.child"
  332. :key="item2.id">
  333. <nuxt-link
  334. :to="{
  335. name: 'category-firstCategory-secondCategory',
  336. params: {
  337. firstCategory: item1.name.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  338. secondCategory: item2.name.replace(/\s+/g, '-').replace('-&', '').toLowerCase(),
  339. },
  340. }">
  341. {{ item2.name }}
  342. </nuxt-link>
  343. </div>
  344. </div>
  345. </div>
  346. </div>
  347. </Transition>
  348. </li>
  349. <!-- <li class="nav-list">
  350. <div class="nav-list-title">
  351. <span
  352. class="LeadTime"
  353. @click.stop="openLeadTime">
  354. By Lead Time
  355. <i :class="isShopBlock?'el-icon-arrow-up':'el-icon-arrow-down'"></i>
  356. </span>
  357. </div>
  358. <Transition name="leadTime">
  359. <ul
  360. class="leadTime-list border-radius"
  361. v-show="isLeadTimeBlock"
  362. @click="closeAllBlock">
  363. <li
  364. class="leadTime-list-item"
  365. v-for="item in leadTime"
  366. :key="item.id">
  367. <nuxt-link
  368. :to="{ name: 'category', query: { lead_time: item.id } }">
  369. {{ item.name }}
  370. </nuxt-link>
  371. </li>
  372. </ul>
  373. </Transition>
  374. </li>
  375. <li class="nav-list">
  376. <div class="nav-list-title">
  377. <span
  378. class="Budget"
  379. @click.stop="openBudget"
  380. >By Budget
  381. <i :class="isShopBlock?'el-icon-arrow-up':'el-icon-arrow-down'"></i>
  382. </span>
  383. </div>
  384. <Transition name="budge">
  385. <ul
  386. class="budget-list border-radius"
  387. v-show="isBudgetBlock"
  388. @click.stop="closeAllBlock">
  389. <div
  390. class="budget-list-item"
  391. v-for="item in budget"
  392. :key="item.id">
  393. {{ item.name }}
  394. <div class="sub-item-wrap border-radius flex column stretch">
  395. <div class="budget-list-sub-item-title">QTY Needed</div>
  396. <div
  397. class="budget-list-item"
  398. v-for="(v, i2) in qtyList"
  399. :key="`${item.id}-${i2}`">
  400. <nuxt-link
  401. :to="{
  402. name: 'category',
  403. query: { pricetype: item.id, qty: v.value },
  404. }">
  405. {{ v.name }}
  406. </nuxt-link>
  407. </div>
  408. </div>
  409. </div>
  410. </ul>
  411. </Transition>
  412. </li> -->
  413. <li
  414. class="nav-list"
  415. @click="closeAllBlock">
  416. <div class="nav-list-title">
  417. <nuxt-link
  418. :to="{ name: 'category', query: { feature: 54 } }"
  419. target="_self">
  420. New Products
  421. </nuxt-link>
  422. </div>
  423. </li>
  424. <li
  425. class="nav-list"
  426. @click="closeAllBlock">
  427. <div class="nav-list-title">
  428. <a href="/article/Compliance"> Compliance </a>
  429. </div>
  430. </li>
  431. <li
  432. class="nav-list"
  433. @click="closeAllBlock">
  434. <div class="nav-list-title">
  435. <nuxt-link
  436. id="indentLink"
  437. :to="{
  438. name: 'news-newsName',
  439. params: { newsName: 'indent-ideas', id: indentIdeasArticle.id },
  440. }"
  441. target="_self">
  442. Bespoke Service
  443. </nuxt-link>
  444. </div>
  445. </li>
  446. <li
  447. class="nav-list"
  448. @click="closeAllBlock">
  449. <div class="nav-list-title">
  450. <nuxt-link
  451. :to="{ name: 'category', query: { feature: 282 } }"
  452. target="_self">
  453. Carbon Footprint
  454. </nuxt-link>
  455. </div>
  456. </li>
  457. <!-- <li
  458. class="nav-list"
  459. @click="closeAllBlock">
  460. <div class="nav-list-title">
  461. <nuxt-link
  462. to="/category/apparel/socks"
  463. target="_self">
  464. Sock Collection
  465. </nuxt-link>
  466. </div>
  467. </li> -->
  468. <!-- <li
  469. class="nav-list compare-list"
  470. @click="closeAllBlock">
  471. <div class="nav-list-title">
  472. <el-badge
  473. :value="compareList.length"
  474. class="item"
  475. v-show="compareList.length">
  476. </el-badge>
  477. <span>Wishlist</span>
  478. </div>
  479. <div class="compare-product">
  480. <div class="compare-product-title">
  481. <p>Product to Compare</p>
  482. <el-button
  483. class="compare-btn"
  484. size="mini"
  485. @click="compareAll">
  486. Compare All
  487. </el-button>
  488. </div>
  489. <div class="red-line"></div>
  490. <div
  491. class="prompt-info"
  492. v-show="!compareList.length">
  493. <ul>
  494. <li>
  495. Select products to compare by clicking the "Compare list +"
  496. batton on any product listing.
  497. </li>
  498. <li>You can compare up to 5 products.</li>
  499. <li>
  500. After selecting products, click on the "Compare All" button to
  501. view the comparison chart.
  502. </li>
  503. </ul>
  504. </div>
  505. <ul>
  506. <li
  507. v-for="item in compareList"
  508. :key="item.id">
  509. <div class="item-left">
  510. <img
  511. :src="
  512. item.main.image &&
  513. item.main.image.indexOf(
  514. 'http://promocollection.s3.ap-southeast-2.amazonaws.com'
  515. ) != -1
  516. ? item.main.image
  517. : 'https://www.promocollection.uk/' +
  518. item.main.image
  519. " />
  520. <p>{{ item.product_name }}</p>
  521. </div>
  522. <div
  523. class="item-right"
  524. @click="clearCompare(item.id)">
  525. <i class="el-icon-error"></i>
  526. </div>
  527. </li>
  528. </ul>
  529. <el-button
  530. class="clear-btn"
  531. size="mini"
  532. @click="clearAll"
  533. v-show="compareList.length">
  534. Clear All
  535. </el-button>
  536. </div>
  537. </li> -->
  538. </ul>
  539. </nav>
  540. <div class="header-redLine"></div>
  541. </header>
  542. </template>
  543. <script>
  544. import { mapMutations } from 'vuex'
  545. import cloneDeep from 'lodash.clonedeep'
  546. import algoliasearch from 'algoliasearch'
  547. export default {
  548. data() {
  549. return {
  550. // loaded: false,
  551. loading: false,
  552. timer: '',
  553. keyword: '',
  554. result: { cate: [], subCate: [], firstCate: [] },
  555. showType: 'none',
  556. matchingList: [],
  557. categoryList: [],
  558. // leadTime: [],
  559. budget: [],
  560. compareList: [],
  561. indentIdeasArticle: {},
  562. complianceArticle: {},
  563. isShopBlock: false,
  564. isLeadTimeBlock: false,
  565. isBudgetBlock: false,
  566. qtyList: [
  567. {
  568. value: 50,
  569. name: 50,
  570. },
  571. {
  572. value: 100,
  573. name: 100,
  574. },
  575. {
  576. value: 250,
  577. name: 250,
  578. },
  579. {
  580. value: 500,
  581. name: 500,
  582. },
  583. {
  584. value: 1000,
  585. name: '1,000',
  586. },
  587. {
  588. value: 2500,
  589. name: '2,500',
  590. },
  591. {
  592. value: 5000,
  593. name: '5,000',
  594. },
  595. {
  596. value: 10000,
  597. name: '10,000',
  598. },
  599. ],
  600. index: null,
  601. }
  602. },
  603. async fetch() {
  604. const p1 = this.$axios.post('/uk-api/common/shopProductList').then(res => {
  605. if (res.code === 1) {
  606. this.categoryList = res.result
  607. }
  608. })
  609. // const p2 = this.$axios.get('/api/home/lead_time').then(res => {
  610. // if (res.code === 1) {
  611. // this.leadTime = res.result.sort((a, b) => a.rank - b.rank)
  612. // }
  613. // })
  614. // const p3 = this.$axios
  615. // .post('/api/common/goodsFilterList', { pid: 2 })
  616. // .then(res => {
  617. // if (res.code === 1) {
  618. // this.budget = res.result
  619. // }
  620. // })
  621. const p4 = this.$axios.post('/uk-api/home/articleList', { keyword: 'Indent Ideas' }).then(res => {
  622. this.indentIdeasArticle = res.result.data[0] || {}
  623. })
  624. const p5 = this.$axios.post('/uk-api/home/articleList', { keyword: 'Compliance' }).then(res => {
  625. this.complianceArticle = res.result.data[0] || {}
  626. })
  627. // 并联异步操作,总耗时===耗时最长的单个请求。之前的逻辑是串联,总耗时为所有请求耗时的累加
  628. await Promise.all([p1, p4, p5])
  629. },
  630. computed: {
  631. email() {
  632. return this.$store.state.userInfo?.email
  633. },
  634. compareLists() {
  635. return this.$store.state.compareList
  636. },
  637. productsList() {
  638. if (this.result?.goods) {
  639. return this.result.goods.map(item => {
  640. const temp = {
  641. ...item,
  642. }
  643. if (item.img) {
  644. temp.image = !this.$mediaRegExp.test(item.img) ? this.$OSS_PREFIX + item.img : item.img
  645. }
  646. return temp
  647. })
  648. } else {
  649. return []
  650. }
  651. },
  652. },
  653. watch: {
  654. keyword: {
  655. handler(newValue, oldValue) {
  656. // if (newValue.length > 2 && this.loaded) {
  657. if (newValue.length > 2) {
  658. this.debounce(this.search, 700)
  659. } else {
  660. setTimeout(() => {
  661. this.showType = 'none'
  662. }, 501)
  663. }
  664. },
  665. deep: true,
  666. },
  667. compareLists: {
  668. handler(newValue, oldValue) {
  669. if (newValue) {
  670. this.compareList = cloneDeep(newValue)
  671. }
  672. },
  673. deep: true,
  674. immediate: true,
  675. },
  676. $route(to, from) {
  677. if (to.path == from.path && to.query.keyword != from.query.keyword) {
  678. location.reload()
  679. }
  680. if (!to.query.keyword) {
  681. this.keyword = ''
  682. }
  683. },
  684. },
  685. created() {},
  686. mounted() {
  687. // if (this.$route.query.keyword && this.$route.query.keyword.length) {
  688. // this.keyword = this.$route.query.keyword
  689. // }
  690. // setTimeout(() => {
  691. // this.loaded = true
  692. // }, 0)
  693. window.addEventListener('click', this.closeLeadtimeAndBudget)
  694. if (process.env.NODE_ENV === 'development') {
  695. const client = algoliasearch('7KGEFE6I2Z', 'e39e202ace0a2fa12ea61095e6ede35d')
  696. this.index = client.initIndex('test_uk')
  697. } else {
  698. const client = algoliasearch('2340OWI595', '2d4c53cdcf2bab0c361e589c2c2272fa')
  699. this.index = client.initIndex('product_uk')
  700. }
  701. },
  702. beforeDestroy() {
  703. window.removeEventListener('click', this.closeLeadtimeAndBudget)
  704. },
  705. methods: {
  706. ...mapMutations([
  707. 'openDialog',
  708. 'clearUserInfo',
  709. // 'clearCompareList',
  710. ]),
  711. debounce(fn, wait) {
  712. if (this.timer !== null) {
  713. clearTimeout(this.timer)
  714. }
  715. this.timer = setTimeout(fn, wait)
  716. },
  717. search() {
  718. this.result = { cate: [], subCate: [], firstCate: [] }
  719. this.showType = 'flex'
  720. this.loading = true
  721. const key = this.keyword ? this.keyword.trim() : ''
  722. if (this.index) {
  723. this.index
  724. .search(key, {
  725. hitsPerPage: 1000,
  726. })
  727. .then(({ nbHits, hits }) => {
  728. const temp = {
  729. goods: [],
  730. total: nbHits || hits.length || 0,
  731. cate: [],
  732. firstCate: [],
  733. subCate: [],
  734. }
  735. const t1 = []
  736. const t2 = []
  737. hits
  738. .filter(i => i.status === 1 || i.status === '1' || i.status)
  739. .forEach(item => {
  740. let colorImg = ''
  741. item.colour_imgs = JSON.parse(item.colour_imgs)
  742. item.colour_imgs.sort((a, b) => a.name.length - b.name.length)
  743. if (Array.isArray(item.colour_imgs) && item.colour_imgs.length) {
  744. item.colour_imgs.forEach(colorItem => {
  745. if (colorItem.name && colorItem.name.length) {
  746. if (new RegExp(colorItem.name.toLowerCase(), 'i').test(key)) {
  747. console.log(item.product_code, colorItem.name, 'replace')
  748. colorImg = colorItem.img
  749. } else if (
  750. /\s/.test(colorItem.name) &&
  751. colorItem.name
  752. .split(' ')
  753. .filter(a => a.length > 0)
  754. .some(b => new RegExp(b.toLowerCase(), 'i').test(key))
  755. ) {
  756. console.log(item.product_code, colorItem.name, 'advance replace')
  757. colorImg = colorItem.img
  758. }
  759. }
  760. })
  761. item.colour_imgs.forEach(i => {
  762. if (i.name && i.name.length) {
  763. if (key.toLowerCase().includes(i.name.toLowerCase())) {
  764. console.log(item.product_code, i.name, 'complete replace')
  765. colorImg = i.img
  766. }
  767. }
  768. })
  769. console.log('---')
  770. }
  771. temp.goods.push({
  772. ...item,
  773. img: colorImg || item.image || item.img,
  774. product_name: item.alias_name || item.product_name || item.name,
  775. })
  776. if (!item.category_id) return
  777. const id = parseInt(item.category_id)
  778. const categoryResult = this.getCategoryFromTree(id, this.categoryList)
  779. switch (categoryResult.lev) {
  780. case 1:
  781. if (!t1.includes(id)) {
  782. t1.push(id)
  783. temp.firstCate.push(categoryResult)
  784. }
  785. break
  786. case 2:
  787. case 3:
  788. if (!t2.includes(id)) {
  789. t2.push(id)
  790. temp.subCate.push(categoryResult)
  791. }
  792. // 当前商品在2 3 级, 搜索出来的分类里面应同时展示1级.
  793. if (!t1.includes(categoryResult.root.id)) {
  794. t1.push(categoryResult.root.id)
  795. temp.firstCate.push(categoryResult.root)
  796. }
  797. // no default
  798. }
  799. })
  800. this.result = temp
  801. })
  802. .finally(() => {
  803. this.loading = false
  804. })
  805. }
  806. },
  807. focus() {
  808. clearTimeout(this.timer)
  809. if (this.keyword) {
  810. this.showType = 'flex'
  811. }
  812. },
  813. blur() {
  814. this.timer = setTimeout(() => {
  815. this.showType = 'none'
  816. }, 200)
  817. },
  818. goSearchResultPage() {
  819. // 匹配同组件的路由更改query时, 页面不会被刷新
  820. // this.$router.push({
  821. // name: 'category-searchResult',
  822. // query: { keyword: this.keyword },
  823. // })
  824. location.href = location.origin + `/category/searchResult?keyword=${encodeURIComponent(this.keyword)}`
  825. },
  826. logout() {
  827. this.$store.dispatch('logout').then(() => {
  828. this.$router.push('/')
  829. })
  830. },
  831. compareAll() {
  832. if (this.compareList.length) {
  833. this.$router.push('/home/compareList')
  834. }
  835. },
  836. // clearCompare(id) {
  837. // this.$axios
  838. // .post('/api/home/compare_clear', {
  839. // id,
  840. // compare_keys: 'keys',
  841. // })
  842. // .then(res => {
  843. // if (res.code === 1) {
  844. // this.compareList.splice(
  845. // this.compareList.findIndex(item => item.id === id),
  846. // 1
  847. // )
  848. // }
  849. // })
  850. // },
  851. // clearAll() {
  852. // if (this.compareList.length) {
  853. // this.$axios
  854. // .post('/api/home/compare_clear', {
  855. // id: 0,
  856. // compare_keys: 'keys',
  857. // })
  858. // .then(res => {
  859. // if (res.code === 1) {
  860. // this.clearCompareList()
  861. // }
  862. // })
  863. // }
  864. // },
  865. openShopProduct() {
  866. this.isShopBlock = !this.isShopBlock
  867. this.isLeadTimeBlock = false
  868. this.isBudgetBlock = false
  869. },
  870. // openLeadTime() {
  871. // this.isLeadTimeBlock = !this.isLeadTimeBlock
  872. // this.isShopBlock = false
  873. // this.isBudgetBlock = false
  874. // },
  875. openBudget() {
  876. this.isBudgetBlock = !this.isBudgetBlock
  877. this.isLeadTimeBlock = false
  878. this.isShopBlock = false
  879. },
  880. closeAllBlock() {
  881. this.isShopBlock = false
  882. this.isLeadTimeBlock = false
  883. this.isBudgetBlock = false
  884. },
  885. closeLeadtimeAndBudget(e) {
  886. const className = e.target?.className
  887. if (!['shopProducts', 'LeadTime', 'Budget'].includes(className)) {
  888. this.isShopBlock = false
  889. this.isLeadTimeBlock = false
  890. this.isBudgetBlock = false
  891. }
  892. },
  893. closePopoverAndNavigate() {
  894. this.$refs.userPopover.doClose()
  895. },
  896. // 从分类树数据里面找到对应分类
  897. getCategoryFromTree(id, tree) {
  898. let result = {}
  899. if (!tree.length) return result
  900. tree.forEach(i => {
  901. if (i.id === id) {
  902. result = cloneDeep(i)
  903. result.lev = 1
  904. }
  905. if (!Array.isArray(i.child)) return
  906. i.child.forEach(secondCate => {
  907. if (secondCate.id === id) {
  908. result = cloneDeep(secondCate)
  909. result.parentName = i.name
  910. result.lev = 2
  911. result.root = {
  912. name: i.name,
  913. id: i.id,
  914. pid: 0,
  915. }
  916. }
  917. if (!Array.isArray(secondCate.child)) return
  918. secondCate.child.forEach(thirdCate => {
  919. if (thirdCate.id === id) {
  920. result = cloneDeep(thirdCate)
  921. result.parentName = secondCate.name
  922. result.grandName = i.name
  923. result.lev = 3
  924. result.root = {
  925. name: i.name,
  926. id: i.id,
  927. pid: 0,
  928. }
  929. }
  930. })
  931. })
  932. })
  933. return result
  934. },
  935. },
  936. }
  937. </script>
  938. <style lang="scss" scoped>
  939. .product-info {
  940. width: 100%;
  941. }
  942. header {
  943. width: 100%;
  944. position: fixed;
  945. top: 0px;
  946. left: 0px;
  947. z-index: 100;
  948. background-color: #fff;
  949. .topbar {
  950. min-width: 800px;
  951. height: 92px;
  952. display: flex;
  953. align-items: center;
  954. #logo {
  955. cursor: pointer;
  956. }
  957. .search-input {
  958. flex: 1;
  959. padding: 0 26px 0 50px;
  960. position: relative;
  961. .search-detail {
  962. z-index: 101;
  963. padding: 12px 0 8px;
  964. box-sizing: border-box;
  965. width: calc(100% - 76px);
  966. height: 320px;
  967. position: absolute;
  968. top: 52px;
  969. background: #ffffff;
  970. border: 1px solid #bebebe;
  971. border-radius: 4px;
  972. font-size: 12px;
  973. font-weight: 400;
  974. color: #333333;
  975. .autocomplete-title {
  976. height: 36px;
  977. line-height: 36px;
  978. margin-bottom: 8px;
  979. font-size: 14px;
  980. font-weight: bold;
  981. color: #000000;
  982. }
  983. .category-list {
  984. box-sizing: border-box;
  985. padding: 0 12px;
  986. height: 100%;
  987. width: 35%;
  988. min-width: 35%;
  989. border-right: 1px solid #7f7f7f;
  990. position: relative;
  991. ul {
  992. overflow-y: auto;
  993. li {
  994. width: 100%;
  995. position: relative;
  996. p {
  997. box-sizing: border-box;
  998. padding: 0 8px;
  999. width: 100%;
  1000. height: 50px;
  1001. line-height: 50px;
  1002. color: #333;
  1003. font-size: 14px;
  1004. cursor: pointer;
  1005. &:hover {
  1006. background-color: #f5f5f5;
  1007. color: #0b6dc9;
  1008. }
  1009. }
  1010. }
  1011. }
  1012. }
  1013. .product-list {
  1014. padding: 0 16px;
  1015. ul li {
  1016. margin-bottom: 10px;
  1017. a {
  1018. display: flex;
  1019. justify-content: flex-start;
  1020. align-items: center;
  1021. img {
  1022. width: 43px;
  1023. height: 43px;
  1024. }
  1025. p {
  1026. height: 24px;
  1027. line-height: 24px;
  1028. margin-left: 5px;
  1029. }
  1030. }
  1031. &:hover {
  1032. background: #f5f5f5;
  1033. p {
  1034. color: #0b6dc9;
  1035. }
  1036. }
  1037. }
  1038. .seeAllResult {
  1039. text-align: center;
  1040. font-size: 14px;
  1041. font-weight: bold;
  1042. background-color: #00213b;
  1043. color: #fff;
  1044. padding: 0 12px;
  1045. line-height: 26px;
  1046. height: 26px;
  1047. border-radius: 4px;
  1048. }
  1049. }
  1050. .sth-else {
  1051. margin-top: 4px;
  1052. text-align: center;
  1053. height: 24px;
  1054. line-height: 24px;
  1055. font-size: 18px;
  1056. font-weight: 600;
  1057. color: #00213b;
  1058. a {
  1059. display: inline-block;
  1060. padding: 0 6px;
  1061. border-radius: 4px;
  1062. background-color: #00213b;
  1063. color: #fff;
  1064. box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.2);
  1065. }
  1066. a:hover {
  1067. background-color: #000;
  1068. }
  1069. }
  1070. }
  1071. }
  1072. .topbar-item {
  1073. font-weight: bold;
  1074. white-space: nowrap;
  1075. cursor: pointer;
  1076. .topbar-item-right {
  1077. padding: 0 30px 0 12px;
  1078. }
  1079. .topbar-item-right-myAccount {
  1080. // display: flex;
  1081. // align-items: center;
  1082. position: relative;
  1083. p {
  1084. margin-left: 10px;
  1085. }
  1086. .greeting {
  1087. position: absolute;
  1088. top: -20px;
  1089. left: 30px;
  1090. }
  1091. }
  1092. }
  1093. }
  1094. nav {
  1095. background-color: #00213b;
  1096. height: 52px;
  1097. // font-family: ProximaNova-Regular;
  1098. ul {
  1099. display: flex;
  1100. justify-content: space-between;
  1101. align-items: center;
  1102. li.nav-list {
  1103. width: 170px;
  1104. height: 52px;
  1105. font-size: 16px;
  1106. font-weight: 400;
  1107. color: #ffffff;
  1108. text-align: center;
  1109. line-height: 52px;
  1110. .nav-list-title {
  1111. font-weight: 600;
  1112. }
  1113. a {
  1114. display: block;
  1115. width: 100%;
  1116. color: #ffffff;
  1117. }
  1118. span {
  1119. display: inline-block;
  1120. cursor: pointer;
  1121. .el-icon-arrow-up,
  1122. .el-icon-arrow-down {
  1123. margin-left: 5px;
  1124. text-align: center;
  1125. }
  1126. }
  1127. .nav-menu {
  1128. width: 1400px;
  1129. height: 395px;
  1130. color: #fff;
  1131. background-color: RGB(56 54 55);
  1132. overflow: hidden;
  1133. .nav-menu-content {
  1134. box-sizing: border-box;
  1135. padding: 20px 0 0 20px;
  1136. margin: 0 auto;
  1137. display: flex;
  1138. justify-content: space-between;
  1139. .nav-menu-item {
  1140. position: relative;
  1141. width: 130px;
  1142. }
  1143. .primary-classification {
  1144. $width: 85px;
  1145. .menu-item-icon {
  1146. width: $width;
  1147. height: $width;
  1148. img {
  1149. width: 100%;
  1150. height: 100%;
  1151. }
  1152. }
  1153. &:hover {
  1154. .menu-item-title {
  1155. color: #0b6dc9;
  1156. }
  1157. }
  1158. .menu-item-title {
  1159. margin-top: 5px;
  1160. height: 24px;
  1161. font-size: 15px;
  1162. // font-size: 1.1rem;
  1163. font-weight: bold;
  1164. text-align: left;
  1165. line-height: 24px;
  1166. cursor: pointer;
  1167. white-space: normal;
  1168. word-break: keep-all;
  1169. overflow: hidden;
  1170. }
  1171. .menu-separator {
  1172. width: $width;
  1173. height: 1px;
  1174. background-color: #666;
  1175. margin: 12px 0;
  1176. }
  1177. }
  1178. .secondary-classification {
  1179. width: 100%;
  1180. font-size: 13px;
  1181. font-weight: 400;
  1182. line-height: 24px;
  1183. text-align: left;
  1184. cursor: pointer;
  1185. white-space: normal;
  1186. word-break: keep-all;
  1187. overflow: hidden;
  1188. }
  1189. }
  1190. }
  1191. .leadTime-list,
  1192. .budget-list {
  1193. display: flex;
  1194. flex-direction: column;
  1195. justify-content: flex-start;
  1196. color: #fff;
  1197. background-color: RGB(56 54 55);
  1198. text-align: center;
  1199. font-size: 14px;
  1200. width: 171px;
  1201. box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.15);
  1202. .budget-list-item,
  1203. .leadTime-list-item {
  1204. width: 171px;
  1205. height: 40px;
  1206. line-height: 40px;
  1207. min-height: 40px;
  1208. a {
  1209. display: block;
  1210. width: 100%;
  1211. height: 100%;
  1212. }
  1213. }
  1214. }
  1215. .sub-item-wrap {
  1216. display: none;
  1217. z-index: 1;
  1218. background-color: rgb(56 54 55);
  1219. position: absolute;
  1220. top: 0;
  1221. left: 170px;
  1222. .budget-list-item {
  1223. cursor: pointer;
  1224. }
  1225. .budget-list-sub-item-title {
  1226. width: 171px;
  1227. height: 40px;
  1228. line-height: 40px;
  1229. min-height: 40px;
  1230. }
  1231. // color: red;
  1232. }
  1233. .budget-list-item {
  1234. position: relative;
  1235. overflow: visible;
  1236. &:hover {
  1237. .sub-item-wrap {
  1238. display: flex;
  1239. }
  1240. }
  1241. }
  1242. .leadTime-list {
  1243. height: 280px;
  1244. }
  1245. .budget-list {
  1246. height: 360px;
  1247. }
  1248. .compare-product {
  1249. width: 543px;
  1250. background: #fff;
  1251. color: #333333;
  1252. box-shadow: 0px 1px 10px 0px rgba(7, 5, 5, 0.13);
  1253. margin-left: -372px;
  1254. padding: 31px 13px 14px 29px;
  1255. box-sizing: border-box;
  1256. visibility: hidden;
  1257. opacity: 0;
  1258. .compare-product-title {
  1259. display: flex;
  1260. justify-content: space-between;
  1261. align-items: center;
  1262. p {
  1263. font-size: 24px;
  1264. font-weight: bold;
  1265. }
  1266. .compare-btn {
  1267. width: 136px;
  1268. height: 38px;
  1269. background: #00213b;
  1270. border-radius: 4px;
  1271. color: #ffffff;
  1272. font-size: 14px;
  1273. }
  1274. }
  1275. .red-line {
  1276. width: 27px;
  1277. height: 7px;
  1278. background: #e90000;
  1279. }
  1280. .prompt-info {
  1281. font-size: 14px;
  1282. text-align: left;
  1283. line-height: 24px;
  1284. }
  1285. ul {
  1286. display: flex;
  1287. flex-direction: column;
  1288. justify-content: flex-start;
  1289. margin-top: 10px;
  1290. li {
  1291. display: flex;
  1292. justify-content: space-between;
  1293. align-items: center;
  1294. width: 500px;
  1295. .item-left {
  1296. display: flex;
  1297. justify-content: flex-start;
  1298. align-items: center;
  1299. img {
  1300. width: 30px;
  1301. height: 30px;
  1302. margin-right: 10px;
  1303. }
  1304. }
  1305. .el-icon-error {
  1306. color: #e90000;
  1307. font-size: 21px;
  1308. }
  1309. }
  1310. }
  1311. .clear-btn {
  1312. background: #e90000;
  1313. color: #fff;
  1314. font-size: 14px;
  1315. padding: 10px 20px;
  1316. }
  1317. }
  1318. &:hover {
  1319. div.nav-list-title {
  1320. color: #333333;
  1321. background-color: #e3e3e3;
  1322. a {
  1323. color: #333333;
  1324. background-color: #e3e3e3;
  1325. }
  1326. .el-icon-arrow-down {
  1327. color: #333333;
  1328. }
  1329. }
  1330. .compare-product {
  1331. opacity: 1;
  1332. visibility: visible;
  1333. transition: all 0.5s;
  1334. }
  1335. }
  1336. .menu-item-title:hover,
  1337. .secondary-classification:hover a {
  1338. color: #0b6dc9;
  1339. }
  1340. .leadTime-list-item:hover,
  1341. .budget-list-item:hover {
  1342. background: #0b6dc9;
  1343. color: #f5f5f5;
  1344. & > a {
  1345. background: #0b6dc9;
  1346. color: #f5f5f5;
  1347. width: 100%;
  1348. height: 100%;
  1349. }
  1350. }
  1351. }
  1352. }
  1353. }
  1354. :deep(.el-badge.item .el-badge__content) {
  1355. background-color: #e90000;
  1356. }
  1357. .header-redLine {
  1358. height: 4px;
  1359. background: #e90000;
  1360. }
  1361. }
  1362. :deep(.el-input) {
  1363. .el-input__inner {
  1364. border-radius: 18px;
  1365. }
  1366. }
  1367. :deep(.el-menu-item-group__title) {
  1368. padding: 0;
  1369. }
  1370. :deep(.el-submenu__title) {
  1371. font-family: Proxima Nova;
  1372. font-size: 14px;
  1373. color: #333333;
  1374. height: 40px;
  1375. line-height: 40px;
  1376. font-weight: bold;
  1377. &:hover {
  1378. color: #1a72b7;
  1379. }
  1380. }
  1381. :deep(.el-menu-item) {
  1382. font-family: Proxima Nova;
  1383. height: 40px;
  1384. line-height: 40px;
  1385. font-weight: bold;
  1386. color: #333333;
  1387. a {
  1388. display: inline-block;
  1389. width: 100%;
  1390. }
  1391. &:hover a {
  1392. color: #1a72b7;
  1393. }
  1394. }
  1395. :deep(.el-menu-item.is-active) {
  1396. a {
  1397. color: #1a72b7;
  1398. }
  1399. }
  1400. :deep(.el-menu-item-group) {
  1401. font-family: Proxima Nova;
  1402. .el-menu-item {
  1403. font-size: 12px;
  1404. font-weight: 400;
  1405. color: #333333;
  1406. &:hover a {
  1407. color: #1a72b7;
  1408. }
  1409. }
  1410. .is-active a {
  1411. color: #1a72b7;
  1412. font-size: 12px;
  1413. font-weight: 400;
  1414. }
  1415. }
  1416. @keyframes fade {
  1417. 0% {
  1418. height: 0;
  1419. }
  1420. }
  1421. .category-enter-active,
  1422. .leadTime-enter-active,
  1423. .budge-enter-active {
  1424. overflow: hidden;
  1425. animation: fade 0.3s ease-in-out;
  1426. }
  1427. .category-leave-active,
  1428. .leadTime-leave-active,
  1429. .budge-leave-active {
  1430. overflow: hidden;
  1431. animation: fade 0.3s ease-in-out reverse;
  1432. }
  1433. .border-radius {
  1434. border-radius: 6px;
  1435. }
  1436. .no-result {
  1437. margin-top: 120px;
  1438. font-size: 34px;
  1439. font-family: Proxima Nova;
  1440. font-weight: 600;
  1441. color: #797979;
  1442. }
  1443. .user-menu-panel {
  1444. width: 292px;
  1445. box-sizing: border-box;
  1446. padding: 0 0 20px;
  1447. font-size: 15px;
  1448. font-family: ProximaNova-Semibold, sans-serif;
  1449. color: #333;
  1450. & div {
  1451. box-sizing: border-box;
  1452. }
  1453. & > div {
  1454. padding-left: 27px;
  1455. padding-right: 27px;
  1456. }
  1457. .greeting {
  1458. width: 270px;
  1459. font-weight: 600;
  1460. padding-top: 18px;
  1461. padding-bottom: 18px;
  1462. padding-left: 11px;
  1463. padding-right: 11px;
  1464. border-bottom: 1px solid rgba(#002369, 0.3);
  1465. }
  1466. .btn-logout {
  1467. display: inline-block;
  1468. cursor: pointer;
  1469. }
  1470. }
  1471. .user-menu-wrap {
  1472. width: 100%;
  1473. padding-top: 6px;
  1474. padding-bottom: 24px;
  1475. }
  1476. .user-menu {
  1477. margin-top: 8px;
  1478. .menu-title {
  1479. font-weight: 600;
  1480. line-height: 36px;
  1481. }
  1482. .sub-menu {
  1483. font-family: Proxima Nova, sans-serif;
  1484. padding-left: 14px;
  1485. display: flex;
  1486. align-items: center;
  1487. .icon {
  1488. display: inline-block;
  1489. width: 20px;
  1490. height: 20px;
  1491. margin-right: 8px;
  1492. background-position: center;
  1493. background-repeat: no-repeat;
  1494. background-size: contain;
  1495. &.book {
  1496. background-image: url(~@/assets/img/header/book.png);
  1497. }
  1498. &.folder {
  1499. background-image: url(~@/assets/img/header/folder.png);
  1500. }
  1501. &.mail {
  1502. background-image: url(~@/assets/img/header/mail.png);
  1503. }
  1504. &.order {
  1505. background-image: url(~@/assets/img/header/order.png);
  1506. }
  1507. &.video {
  1508. background-image: url(~@/assets/img/header/video.png);
  1509. }
  1510. }
  1511. .sub-title {
  1512. display: inline-block;
  1513. line-height: 36px;
  1514. font-size: 14px;
  1515. }
  1516. &:hover {
  1517. .sub-title {
  1518. color: #409eff;
  1519. }
  1520. }
  1521. }
  1522. }
  1523. </style>