details.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. <template>
  2. <div>
  3. <div class="pc-page">
  4. <div class="box">
  5. <div class="topbox">
  6. <div style="display: flex;align-items: center;">
  7. <div style="flex:1;font-weight: bold;">
  8. {{ list.productName }}
  9. </div>
  10. <div
  11. style="display: flex;align-items: center;margin-left: 20px;gap: 10px;flex:1;"
  12. >
  13. <div @click="clickCoa">
  14. <img
  15. src="@/assets/img/productDetail/coa.png"
  16. style="width: 43px;height: 47px;cursor: pointer;"
  17. alt=""
  18. class="butt_image"
  19. />
  20. </div>
  21. <div @click="clickMsds">
  22. <img
  23. src="@/assets/img/productDetail/msds.png"
  24. style="width: 43px;height: 47px;cursor: pointer;"
  25. alt=""
  26. class="butt_image"
  27. />
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. <div class="contentbox">
  33. <info :list="list" v-loading="getProductDetaiLoading" />
  34. <validation :list="list" v-loading="getProductDetaiLoading" />
  35. </div>
  36. <div class="rightbox">
  37. <price-table
  38. class="common-border"
  39. :list="list"
  40. :sku-list="skuList"
  41. v-loading="getProductDetaiLoading"
  42. />
  43. <!-- 最近访问 -->
  44. <recently-list
  45. v-if="recentlyList.length > 0"
  46. class="common-border"
  47. :recentlyList="recentlyList"
  48. />
  49. <!-- <div
  50. class="rightcenterbox common-border"
  51. v-if="recentlyList.length > 0"
  52. >
  53. <div class="box-title">{{ $t("inquiry.RecentlyViewed") }}</div>
  54. <div class="rightcenterbox_text">
  55. <div
  56. class="topage"
  57. v-for="one in recentlyList.slice(0, 5)"
  58. :key="one.id"
  59. @click="tapRoduct(one)"
  60. >
  61. <div class="list_name">
  62. {{ one.catalog }} / {{ one.product }}
  63. </div>
  64. <i class="el-icon-arrow-right"></i>
  65. </div>
  66. </div>
  67. </div> -->
  68. <!-- 相关产品 -->
  69. <related-product
  70. class="common-border"
  71. v-if="relatedProductlist.length > 0"
  72. :relatedProductlist="relatedProductlist"
  73. />
  74. <!-- <div
  75. class="rightcenterbox common-border"
  76. v-if="relatedProductlist.length > 0"
  77. >
  78. <div class="box-title">{{ $t("button.RelatedProducts") }}</div>
  79. <div class="rightcenterbox_text">
  80. <div
  81. class="topage"
  82. v-for="one in relatedProductlist.slice(0, 5)"
  83. :key="one.id"
  84. @click="tapRoduct(one)"
  85. >
  86. <div class="list_name">
  87. {{ one.catalog }} / {{ one.productName }}
  88. </div>
  89. <i class="el-icon-arrow-right"></i>
  90. </div>
  91. </div>
  92. </div> -->
  93. </div>
  94. </div>
  95. </div>
  96. <div class="mobile-page">
  97. <div class="box">
  98. <div class="topbox">
  99. <div class="product-title">
  100. {{ list.productName }}
  101. </div>
  102. <div class="img-group">
  103. <div @click="clickCoa">
  104. <img
  105. src="@/assets/img/productDetail/coa.png"
  106. style="width: 43px;height: 47px;cursor: pointer;"
  107. alt=""
  108. class="butt_image"
  109. />
  110. </div>
  111. <div @click="clickMsds">
  112. <img
  113. src="@/assets/img/productDetail/msds.png"
  114. style="width: 43px;height: 47px;cursor: pointer;"
  115. alt=""
  116. class="butt_image"
  117. />
  118. </div>
  119. </div>
  120. </div>
  121. </div>
  122. <price-table
  123. class="common-border"
  124. :list="list"
  125. :sku-list="skuList"
  126. v-loading="getProductDetaiLoading"
  127. />
  128. <info :list="list" v-loading="getProductDetaiLoading" />
  129. <validation :list="list" v-loading="getProductDetaiLoading" />
  130. <!-- 最近访问 -->
  131. <recently-list
  132. v-if="recentlyList.length > 0"
  133. class="common-border"
  134. :recentlyList="recentlyList"
  135. />
  136. <!-- 相关产品 -->
  137. <related-product
  138. class="common-border"
  139. v-if="relatedProductlist.length > 0"
  140. :relatedProductlist="relatedProductlist"
  141. />
  142. </div>
  143. </div>
  144. </template>
  145. <script>
  146. import Bus from "@/js/bus";
  147. import sites from "@/assets/josn/search";
  148. import axios from "axios";
  149. import info from "./components/info.vue";
  150. import validation from "./components/validation.vue";
  151. import PriceTable from "./components/PriceTable";
  152. import RecentlyList from "./components/RecentlyList";
  153. import RelatedProduct from "./components/RelatedProduct";
  154. export default {
  155. components: {
  156. info,
  157. validation,
  158. PriceTable,
  159. RecentlyList,
  160. RelatedProduct
  161. },
  162. name: "product",
  163. data() {
  164. return {
  165. type: "",
  166. tapoption: 1,
  167. list: {},
  168. skuList: [], // 价格
  169. options: [
  170. {
  171. value: 0,
  172. label: 0
  173. },
  174. {
  175. value: 1,
  176. label: 1
  177. },
  178. {
  179. value: 2,
  180. label: 2
  181. },
  182. {
  183. value: 3,
  184. label: 3
  185. },
  186. {
  187. value: 4,
  188. label: 4
  189. },
  190. {
  191. value: 5,
  192. label: 5
  193. },
  194. {
  195. value: 6,
  196. label: 6
  197. },
  198. {
  199. value: 7,
  200. label: 7
  201. },
  202. {
  203. value: 8,
  204. label: 8
  205. },
  206. {
  207. value: 9,
  208. label: 9
  209. },
  210. {
  211. value: 10,
  212. label: 10
  213. }
  214. ],
  215. recentlyList: [],
  216. relatedProductlist: [],
  217. swiperOption: {
  218. // loop: true,
  219. slidesPerView: 2,
  220. slidesPerGroup: 2,
  221. // 设置点击箭头
  222. navigation: {
  223. nextEl: ".swiper-button-next",
  224. prevEl: ".swiper-button-prev"
  225. }
  226. },
  227. menuList: {},
  228. changeNumList: [],
  229. pageable: {
  230. // 文献
  231. page: 0,
  232. size: 10
  233. },
  234. literature: false,
  235. busShow: false,
  236. num: 1,
  237. msdsUrl: ""
  238. };
  239. },
  240. computed: {
  241. swiper() {
  242. return this.$refs.mySwiper.swiper;
  243. }
  244. },
  245. methods: {
  246. clickCoa() {
  247. if (this.list.coaUrl) {
  248. window.location.href = this.list.coaUrl;
  249. } else {
  250. this.$message.error(this.$t("taps.service"));
  251. }
  252. },
  253. clickMsds() {
  254. // this.$message({
  255. // message: this.$t('message.MDSD'),
  256. // type: 'warning'
  257. // });
  258. this.$alert(this.$t('message.MDSD'), {
  259. confirmButtonText: this.$t('button.determine'),
  260. customClass: "tankuang",
  261. callback: action => {
  262. }
  263. });
  264. // if (this.list.msdsUrl) {
  265. // window.location.href = this.list.msdsUrl;
  266. // } else {
  267. // if (this.msdsUrl) {
  268. // window.location.href = this.msdsUrl;
  269. // } else {
  270. // axios
  271. // .post("https://crs.sanyoubio.com/api/product/msds", {
  272. // catalog: this.$route.params.catalog
  273. // })
  274. // .then(res => {
  275. // if (res.data.data) {
  276. // // console.log(res)
  277. // this.msdsUrl = res.data.data;
  278. // window.location.href = res.data.data;
  279. // } else {
  280. // this.$message.error(this.$t("taps.service"));
  281. // }
  282. // });
  283. // }
  284. // }
  285. },
  286. datasheet() {
  287. window.open(
  288. "https://crs.sanyoubio.com/ds/SYD100_Mix_and_Go_Competent_Cells_DH5α_COA221011.pdf" +
  289. "?response-content-type=application/pdf"
  290. );
  291. },
  292. goMsds() {
  293. window.open(
  294. "https://crs.sanyoubio.com/ds/SYD100_Mix_and_Go_Competent_Cells_DH5α_MSDS.pdf"
  295. );
  296. },
  297. changeNum() {
  298. // 计数器
  299. let that = this;
  300. that.changeNumList = [];
  301. for (var i = 0; i < that.skuList.length; i++) {
  302. if (that.skuList[i].num > 0) {
  303. let datas = {
  304. skuId: that.skuList[i].id,
  305. cnDiscountPrice: that.skuList[i].cnDiscountPrice,
  306. productCatalog: that.skuList[i].catalog,
  307. productName: that.skuList[i].productName,
  308. size: that.skuList[i].specifications,
  309. number: that.skuList[i].num,
  310. discountPrice: that.skuList[i].discountPrice,
  311. price: that.skuList[i].price,
  312. checked: true,
  313. id: that.list.id,
  314. cnPrice: that.skuList[i].cnPrice
  315. };
  316. this.changeNumList.push(datas);
  317. }
  318. }
  319. },
  320. tapShoppingCart() {
  321. // 购物车
  322. let that = this;
  323. // var obj = []
  324. var cartList = [];
  325. if (this.skuList.length > 0) {
  326. if (this.changeNumList.length === 0) {
  327. this.$message.error(this.$t("button.Article"));
  328. } else {
  329. if (JSON.parse(localStorage.getItem("token"))) {
  330. that.skuList.forEach(item => {
  331. if (item.num > 0) {
  332. var data = {
  333. checked: true,
  334. id: that.list.id,
  335. number: item.num,
  336. productCatalog: item.catalog,
  337. skuId: item.id
  338. };
  339. cartList.push(data);
  340. }
  341. });
  342. this.$api
  343. .post("cart/batchAdd", {
  344. cartList: cartList
  345. })
  346. .then(res => {
  347. if (res.code === 0) {
  348. this.getIndex();
  349. this.$message({
  350. message: this.$t("button.successfully"),
  351. type: "success"
  352. });
  353. // localStorage.setItem('cartTap', '1')
  354. } else {
  355. this.$message(res.msg);
  356. }
  357. });
  358. } else {
  359. this.localList();
  360. }
  361. }
  362. }
  363. },
  364. localList() {
  365. // 本地存储
  366. var shoppingCart = null;
  367. var arrObj = null; // 选中数量
  368. var list = []; // 新增数据
  369. arrObj = JSON.parse(JSON.stringify(this.changeNumList));
  370. shoppingCart = JSON.parse(localStorage.getItem("shoppingCart")) || []; // 获取购物车数据
  371. if (shoppingCart.length > 0) {
  372. for (var i = 0; i < this.changeNumList.length; i++) {
  373. for (var j = 0; j < shoppingCart.length; j++) {
  374. if (
  375. Number(this.changeNumList[i].skuId) ===
  376. Number(shoppingCart[j].skuId)
  377. ) {
  378. this.$set(arrObj[i], "checked", false);
  379. shoppingCart[j].number =
  380. Number(this.changeNumList[i].number) +
  381. Number(shoppingCart[j].number);
  382. }
  383. }
  384. }
  385. } else {
  386. localStorage.setItem(
  387. "shoppingCart",
  388. JSON.stringify(this.changeNumList)
  389. );
  390. localStorage.setItem(
  391. "shoppingNum",
  392. JSON.stringify(this.changeNumList.length)
  393. );
  394. this.elementByValue();
  395. this.$message({
  396. message: this.$t("button.successfully"),
  397. type: "success"
  398. });
  399. return;
  400. }
  401. for (var n = 0; n < arrObj.length; n++) {
  402. if (arrObj[n].checked) {
  403. list.push(arrObj[n]);
  404. }
  405. }
  406. this.$message({
  407. message: this.$t("button.successfully"),
  408. type: "success"
  409. });
  410. var arr = shoppingCart.concat(list);
  411. localStorage.setItem("shoppingCart", JSON.stringify(arr));
  412. localStorage.setItem("shoppingNum", JSON.stringify(arr.length));
  413. // localStorage.setItem('cartTap', '1')
  414. this.elementByValue();
  415. },
  416. getIndex() {
  417. // 获取购物车数量
  418. this.$api
  419. .post("cart/index", {
  420. cartList: null
  421. })
  422. .then(res => {
  423. if (res.code === 0) {
  424. localStorage.removeItem("shoppingCart");
  425. localStorage.setItem(
  426. "shoppingNum",
  427. JSON.stringify(res.data.cartList.length)
  428. );
  429. this.elementByValue();
  430. }
  431. });
  432. },
  433. postLIstanbul() {
  434. let that = this;
  435. that.getProductDetaiLoading = true;
  436. this.$api
  437. .post("product/getProductDetail", {
  438. catalog: this.$route.params.catalog
  439. // catalog: this.$route.query.catalog
  440. })
  441. .then(res => {
  442. if (res.code === 0) {
  443. this.$store.commit("setProductName", res.data.productName);
  444. this.list = res.data;
  445. that.skuList = res.data.skuList || [];
  446. that.skuList.forEach((item, index) => {
  447. this.$set(that.skuList[index], "num", 0);
  448. });
  449. this.getList(); // 文献
  450. this.postpageRelatedProduct();
  451. }
  452. that.getProductDetaiLoading = false;
  453. })
  454. .catch(() => {
  455. that.getProductDetaiLoading = false;
  456. });
  457. },
  458. getrecentlyList() {
  459. // 最近浏览
  460. this.$api.post("product/recentlyList").then(res => {
  461. if (res.code === 0) {
  462. this.recentlyList = res.data.content;
  463. }
  464. });
  465. },
  466. postpageRelatedProduct() {
  467. this.$api
  468. .post("product/pageRelatedProduct", {
  469. criteria: {
  470. catalog: this.list.catalog,
  471. type: this.list.type,
  472. targetId: this.list.target,
  473. category: this.list.category
  474. },
  475. pageable: this.pageable
  476. })
  477. .then(res => {
  478. if (res.code === 0) {
  479. this.relatedProductlist = res.data.content;
  480. }
  481. });
  482. },
  483. goBack() {
  484. console.log(sites.obj[this.list.type].url);
  485. let kes = JSON.parse(sessionStorage.getItem("keywords"));
  486. this.$router.replace({
  487. path: "/search/by-category",
  488. // name: sites.obj[this.list.type].url,
  489. query: {
  490. keywords: kes.keywords,
  491. category: sites.obj[this.list.type].value
  492. }
  493. });
  494. sessionStorage.removeItem("keywords");
  495. },
  496. getList() {
  497. // 文献
  498. this.$api
  499. .post("citations/list", {
  500. criteria: {
  501. catalog: this.list.catalog
  502. },
  503. pageable: this.pageable
  504. })
  505. .then(res => {
  506. if (res.code === 0) {
  507. if (res.data.content && res.data.content.length > 0) {
  508. this.literature = true;
  509. } else {
  510. this.literature = false;
  511. }
  512. }
  513. });
  514. },
  515. elementByValue() {
  516. // localStorage.setItem('cartTap', 1)
  517. Bus.$emit("onmycar", "1");
  518. // console.log('---------888888-')
  519. // this.num = this.num + 1
  520. // this.$store.commit('settapscart', this.num)
  521. // console.log('----77777-----888888-')
  522. }
  523. },
  524. mounted() {
  525. // 浏览器返回
  526. if (sessionStorage.getItem("keywords")) {
  527. if (window.history && window.history.pushState) {
  528. // 向历史记录中插入了当前页
  529. history.pushState(null, null, document.URL);
  530. window.addEventListener("popstate", this.goBack, false);
  531. }
  532. }
  533. },
  534. destroyed() {
  535. window.removeEventListener("popstate", this.goBack, false);
  536. },
  537. created() {
  538. this.postLIstanbul();
  539. this.getrecentlyList();
  540. }
  541. };
  542. </script>
  543. <style lang="scss" scoped>
  544. .common-border {
  545. border-top: 1px solid #0166b4;
  546. border-left: 1px solid #d6eaff;
  547. border-right: 1px solid #d6eaff;
  548. border-bottom: 1px solid #d6eaff;
  549. }
  550. @media screen and (min-width: 751px) and (max-width: 9999px) {
  551. .pc-page {
  552. display: block;
  553. }
  554. .mobile-page {
  555. display: none;
  556. }
  557. .box {
  558. overflow: hidden;
  559. margin-bottom: 3rem;
  560. }
  561. .topbox {
  562. margin-bottom: 26px;
  563. margin-top: 30px;
  564. font-size: 20px;
  565. color: #313131;
  566. // font-weight: 700;
  567. }
  568. .contentbox {
  569. width: 66%;
  570. float: left;
  571. }
  572. .rightbox {
  573. width: 32%;
  574. float: right;
  575. }
  576. .rightcenterbox:not(:nth-child(1)) {
  577. margin-top: 2rem;
  578. }
  579. .rightcenterbox {
  580. width: 100%;
  581. .box-title {
  582. font-size: 14px;
  583. height: 36px;
  584. line-height: 36px;
  585. background-color: #f4faff;
  586. font-weight: bold;
  587. text-indent: 16px;
  588. }
  589. }
  590. // .rightcenterbox > div:nth-of-type(1) {
  591. // height: 3rem;
  592. // font-size: 18px;
  593. // font-weight: 700;
  594. // color: #313131;
  595. // background: #f5f5f5;
  596. // line-height: 3rem;
  597. // text-indent: 1rem;
  598. // }
  599. .rightcenterbox > div:nth-of-type(2) {
  600. font-size: 0.16rem;
  601. padding: 1rem;
  602. font-size: 16px;
  603. }
  604. .rightcenterbox_text /deep/ {
  605. font-size: 1rem !important;
  606. .topage {
  607. display: block;
  608. height: 42px;
  609. line-height: 42px;
  610. font-size: 16px;
  611. color: #6f6f6f;
  612. padding-left: 12px;
  613. margin-left: -12px;
  614. display: flex;
  615. align-items: center;
  616. justify-content: space-between;
  617. cursor: pointer;
  618. &:hover {
  619. background: rgba(0, 91, 171, 0.11);
  620. border-radius: 2px;
  621. border: 1px solid #005bab;
  622. color: #005bab;
  623. .el-icon-arrow-right {
  624. color: #005bab;
  625. }
  626. }
  627. .list_name {
  628. font-size: 14px;
  629. white-space: nowrap;
  630. overflow: hidden;
  631. text-overflow: ellipsis;
  632. }
  633. }
  634. .el-icon-arrow-right {
  635. height: 42px;
  636. line-height: 42px;
  637. margin-right: 10px;
  638. }
  639. }
  640. .rightcenterbox > div:nth-of-type(2) > p:nth-of-type(1) {
  641. margin-top: 0;
  642. }
  643. // .rightcenterbox>div:nth-of-type(2)>p{
  644. // margin-top: 1rem;
  645. // color: #6f6f6f;
  646. // }
  647. .rightcenterbox > div > p {
  648. word-wrap: break-word;
  649. word-break: normal;
  650. cursor: pointer;
  651. a {
  652. color: #6f6f6f;
  653. text-decoration: none;
  654. }
  655. }
  656. .rightbox_ds {
  657. line-height: 24px;
  658. color: #6f6f6f;
  659. }
  660. .rightcenterbox > div:nth-of-type(2) > .rightbox_b {
  661. color: #005bab;
  662. // font-weight: 600;
  663. margin-top: 10px;
  664. }
  665. }
  666. @media screen and (min-width: 0px) and (max-width: 750px) {
  667. .pc-page {
  668. display: none;
  669. }
  670. .mobile-page {
  671. display: block;
  672. }
  673. .box {
  674. overflow: hidden;
  675. margin-bottom: 0.1rem;
  676. .topbox {
  677. margin-bottom: 0.2rem;
  678. font-size: 0.18rem;
  679. color: #313131;
  680. font-weight: 600;
  681. .img-group {
  682. display: flex;
  683. margin-top: 0.2rem;
  684. gap: 0.1rem;
  685. }
  686. }
  687. .contentbox {
  688. width: 100%;
  689. overflow: hidden;
  690. }
  691. }
  692. .not_list {
  693. height: 100%;
  694. display: flex;
  695. align-items: center;
  696. justify-content: center;
  697. .block_img {
  698. width: 80%;
  699. }
  700. }
  701. .tankuang, .el-message-box{
  702. width: 80% !important;
  703. }
  704. }
  705. </style>