<template> <v-container> <div> <!-- <v-breadcrumbs divider="/" style="padding-top: 0"> <template v-for="(item, index) in items" :key="index"> <v-breadcrumbs-item :disabled="item.disabled" :href="item.href" :class="{ 'breadcrumb-disabled': item.disabled, 'breadcrumb-active': !item.disabled, 'breadcrumb-last': index === items.length - 1, }" :style=" index === items.length - 1 ? 'color: black;font-size:15px' : 'font-size:15px;' " > {{ item.title }} </v-breadcrumbs-item> <span v-if="index < items.length - 1" class="breadcrumb-divider" >/</span > </template> </v-breadcrumbs> --> <v-breadcrumbs divider="/" style="padding-top: 0"> <template v-for="(item, index) in items" :key="index"> <v-breadcrumbs-item :disabled="item.disabled" :href="item.href" :class="{ 'breadcrumb-disabled': item.disabled, 'breadcrumb-active': !item.disabled, }" style="font-size: 14px" > {{ item.title }} </v-breadcrumbs-item> <!-- 添加分隔符,排除最后一个 item --> <span v-if="index < items.length - 1" class="breadcrumb-divider" style="color: gray" >/</span > </template> </v-breadcrumbs> </div> <v-row class="mb-16 ma-0"> <v-col cols="12" sm="5" class="carousel-container"> <v-carousel class="tw-float-left tw-sticky tw-top-[16px]" height="450" v-model="slide" hide-delimiter-background style="top: 16px" > <v-carousel-item cover v-for="(slide, i) in info.productimageliststore" :src="slide.url" :key="i" :alt="info.name" > </v-carousel-item> </v-carousel> </v-col> <v-col cols="12" sm="7" class="table-container"> <!-- <v-row class="bg-white mb-sm-10 text-h4 font-weight-medium"> <v-col>{{ info.name }}</v-col> </v-row> --> <h1 class="tw-m-[12px] tw-mb-[36px]">{{ info.name }}</h1> <div class="tw-flex tw-flex-wrap"> <div class="tw-w-1/2 tw-mb-[12px]"> <span class="tw-leading-[10px] tw-m-[12px]"> Brand:{{ info.brandName }} </span> </div> <div class="tw-w-1/2 tw-mb-[12px]"> <span class="tw-leading-[10px] tw-m-[12px]" >Product Model:{{ info.model }}</span > </div> <div class="tw-w-1/2 tw-mb-[12px]" v-if="info.basename1"> <span class="tw-leading-[10px] tw-m-[12px]" >{{ info.basename1 }}:{{ info.basecore1 }}</span > </div> <div class="tw-w-1/2 tw-mb-[12px]" v-if="info.basename2"> <span class="tw-leading-[10px] tw-m-[12px]" >{{ info.basename2 }}:{{ info.basecore2 }}</span > </div> <div class="tw-w-1/2 tw-mb-[12px]" v-if="info.basename3"> <span class="tw-leading-[10px] tw-m-[12px]" >{{ info.basename3 }}:{{ info.basecore3 }}</span > </div> </div> <div class="tw-flex tw-flex-wrap" v-if=" info.productAttributeList && info.productAttributeList.length > 0 " > <div v-for="(attribute, index) in info.productAttributeList" :key="index" class="tw-w-1/2 tw-mb-[12px]" > <span class="tw-leading-normal tw-m-0 tw-block tw-max-w-full tw-break-words tw-ml-[12px]" >{{ attribute.name }}:{{ attribute.value }}</span > </div> </div> <!-- <v-table density="comfortable" class="table1 tw-mt-[32px]" v-if="info.ticketTypes?.length" > --> <v-table density="comfortable" class="table1 tw-mt-[32px] tw-overflow-x-auto" v-if="info.ticketTypes?.length" > <thead> <tr class="bg-grey-lighten-3"> <th class="text-left headerBorder text-grey-darken-1"> Product Name / Code </th> <th class="text-left headerBorder text-grey-darken-1"> Specification and model </th> <th v-if="info.priceShow !== undefined && info.priceShow" class="text-left headerBorder text-grey-darken-1" > Price </th> <th class="text-left headerBorder text-grey-darken-1">Actions</th> </tr> </thead> <tbody> <tr class="tr" v-for="item in info.ticketTypes || []" :key="item.rank" > <td class="td text-grey-darken-4 font-weight-medium"> {{ item.rank }} </td> <td class="td text-grey-darken-4 font-weight-medium"> {{ item.typeName }} </td> <td v-if="item.priceShow" class="td"> {{ item.price + " " + item.priceUnit }} </td> <td class="td"> <v-btn size="small" color="blue-darken-1" @click="router.push('/contact')" > <!-- Quotation Inquiry --> Quote </v-btn> </td> </tr> </tbody> </v-table> <!-- <v-dialog v-model="dialog" activator="parent" width="auto"> <v-card> Contact us Email: contact@canrd.com QQ: 3003597584 / 2902385824 </v-card> </v-dialog> --> </v-col> </v-row> <v-tabs class="tabs" v-model="tabRecom" color="white" bg-color="#eeeeee" slider-color="blue-lighten-1" selected-class="active" v-if="recommendImages[0] !== null" > <v-tab :value="1">Product Recommendations</v-tab> <!-- <v-tab :value="3">商品百科</v-tab> --> </v-tabs> <div id="image-container" v-if="recommendImages[0] !== null"> <div class="recommend-left-box"> <v-img src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/76c987e13a334be481a346c19c2284f3qy4tjnxps7.png" alt="往左移" class="recommend-img-left" @click="toggleRow" /> </div> <div v-if="currentIndex === 0" class="image-row" id="row1"> <!-- <img v-for="(imageObj, index) in recommendImages.slice(0, 5)" :key="'row1-' + index" :src="imageObj[0]?.url" :alt="'Image ' + (index + 1)" style="margin: 0 5px; width: 200px; height: 200px" /> --> <div v-for="(imageObj, index) in recommendImages.slice(0, 5)" :key="'row1-' + index" style=" display: inline-block; margin: 0 5px; text-align: center; width: 200px; " > <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank"> <img :src="imageObj[0]?.url" :alt="'Image ' + (index + 1)" style="width: 200px; height: 200px; margin-right: 10px" /> <span style=" display: block; margin-top: 5px; font-size: 16px; width: 180px; color: #555; text-align: left; margin-left: 10px; " > {{ imageObj[0]?.name }} </span> </a> <div v-else style="width: 200px; height: 200px"></div> </div> </div> <div v-else class="image-row" id="row2"> <!-- <img v-for="(imageObj, index) in recommendImages.slice(5, 10)" :key="'row2-' + index" :src="imageObj[0]?.url" :alt="'Image ' + (index + 6)" style="margin: 0 5px; width: 200px; height: 200px" /> --> <div v-for="(imageObj, index) in recommendImages.slice(5, 10)" :key="'row2-' + index" style=" display: inline-block; margin: 0 5px; text-align: center; width: 200px; " > <a v-if="imageObj" :href="imageObj[0]?.productUrl" target="_blank"> <img :src="imageObj[0]?.url" :alt="'Image ' + (index + 6)" style="width: 200px; height: 200px; margin-right: 10px" /> <span style=" display: block; margin-top: 5px; font-size: 16px; color: #555; text-align: left; width: 180px; margin-left: 10px; " > {{ imageObj[0]?.name }} </span> </a> <div v-else style="width: 200px; height: 200px; margin-right: 10px" ></div> </div> </div> <div class="recommend-right-box"> <v-img src="https://m-canrd.oss-cn-shenzhen.aliyuncs.com/crmebimage/public/maintain/2024/09/14/b5daa0a8f2f140f5b406e984c730a453iznzlekysg.png" alt="往右移" class="recommend-img-right" @click="toggleRow" /> </div> </div> <div class="tw-pb-[64px]"> <v-tabs class="tabs" v-model="tab" color="white" bg-color="#eeeeee" slider-color="blue-lighten-1" selected-class="active" > <v-tab :value="1">Product Details</v-tab> <v-tab :value="2">Specification</v-tab> <!-- <v-tab :value="3">商品百科</v-tab> --> </v-tabs> <v-window v-model="tab" class="tw-p-[24px]"> <v-window-item key="1" :value="1"> <div v-if="info.advantage" class="tw-mb-[24px]"> <div class="text-h6">Advantage</div> <v-divider class="tw-mb-[12px]"></v-divider> <div v-html="info.advantage"></div> </div> <div v-if="info.physicalproperty" class="tw-mb-[24px]"> <div class="text-h6">Physical Property</div> <v-divider class="tw-mb-[12px]"></v-divider> <div v-html="info.physicalproperty"></div> </div> <div v-if="info.storage" class="tw-mb-[24px]"> <div class="text-h6">Storage</div> <v-divider class="tw-mb-[12px]"></v-divider> <div v-html="info.storage"></div> </div> <div v-if="info.introduction" class="tw-mb-[24px]"> <div class="text-h6">Introduction</div> <v-divider class="tw-mb-[12px]"></v-divider> <div v-html="info.introduction"></div> </div> <div v-if="info.description" class="tw-mb-[24px]"> <div class="text-h6">Description</div> <v-divider class="tw-mb-[12px]"></v-divider> <div v-html="info.description"></div> </div> </v-window-item> <v-window-item key="2" :value="2"> <v-table density="compact" class="table2"> <tbody> <tr class="tr" v-for="item in info.productAttributeList || []" :key="item.name" > <td class="td tw-w-[400px]">{{ item.name }}</td> <td class="td">{{ item.value }}</td> </tr> </tbody> </v-table> </v-window-item> <!-- <v-window-item key="3" :value="3"> 2 </v-window-item> --> </v-window> </div> <div class="social-share-container"> <SocialShare network="facebook" :styled="true" :label="true" :title="info.name" :url="currentUrl" style="color: #1e88e5; width: 140px" /> <SocialShare network="twitter" :styled="true" :label="true" :title="info.name" :url="currentUrl" style="color: #1e88e5; width: 140px" /> <SocialShare network="linkedin" :styled="true" :label="true" :title="info.name" :url="currentUrl" style="color: #1e88e5; width: 140px" /> </div> <!-- <div class="social-share-container"> <div v-for="network in ['facebook', 'twitter', 'linkedin']" :key="network" class="social-share-item" > <h3 class="social-share-title" style="color: #1e88e5"> {{ getTitle(network) }} </h3> <SocialShare :network="network" :styled="true" style="color: #1e88e5" :label="getTitle(network)" :title="info.name" :url="currentUrl" class="p-4 rounded-none" /> </div> </div> --> </v-container> </template> <script setup lang="ts"> import type { Product, ProductImage } from "~/type"; import { onMounted, ref } from "vue"; import { useDialogStore } from "~/stores/dialog"; import { useRouter, useRoute } from "vue-router"; import { useRouteQuery } from "@/stores/route_query"; const recommendList = ref(); const recommendImages = ref(); const selectedItem = ref(); const tabRecom = ref(0); const tabRecommend = ref(0); const tabPeriodical = ref(0); const route = useRoute(); const router = useRouter(); const routeQuery = useRouteQuery(); const dialogStore = useDialogStore(); const href1 = ref("/products"); const href2 = ref("/products"); const idHref = ref("/products"); const productStore = useProductListStore(); const currentUrl = ref("https://www.canrud.com/products"); // 定义单个 item 的接口 interface BreadcrumbItem { title: string; // 标题 disabled: boolean; // 是否禁用 href: string; // 链接地址 } // 示例数据 const items = ref<BreadcrumbItem[]>([ { title: "Products", disabled: false, href: "https://www.canrud.com/products", }, { title: "CATEGORY", disabled: false, href: href1.value, }, { title: "DEVICE TYPE", disabled: false, href: href2.value, }, { title: "FUNCTION", disabled: false, href: "/products", }, ]); const props = defineProps<{ info: Product; }>(); const info = props.info; let { data: resData } = await useAsyncData( "detail", () => $fetch("/shop/product/list", { method: "GET", params: { pageNo: 1, pageSize: 20, ids: info.relatedProductIds, }, }), { server: true, // 仅在服务器端获取数据 } ); watchEffect(() => { currentUrl.value = "https://www.canrud.com/products/detail/" + info.id; if (info?.productCrumbsVO?.category1 && productStore.keyword) { items.value[1].title = info.productCrumbsVO.category1; items.value[1].href = "https://www.canrud.com/products?categories=" + info.productCrumbsVO.category1; href1.value = "https://www.canrud.com/products?categories=" + info.productCrumbsVO.category1; if (info?.productCrumbsVO?.category2) { items.value[2].title = info.productCrumbsVO.category2; href2.value = href1.value + "," + info.productCrumbsVO.category2; items.value[2].href = href1.value + "," + info.productCrumbsVO.category2; } if (info?.productCrumbsVO?.function) { // items.value.push({ // title: info.productCrumbsVO.function, // disabled: false, // href: href2.value + "&function=" + info.productCrumbsVO.function, // }); items.value[3].title = info.productCrumbsVO.function; items.value[3].href = href2.value + "&function=" + info.productCrumbsVO.function; } } else if (routeQuery.categories) { if (!routeQuery.categories.includes("Energy materials")) { routeQuery.updateFunction("Not specified"); } const categories = routeQuery.categories.split(","); const mainCategory = categories[0].trim(); // 取第一个值 const subCategoryName = ref( categories[1] ? categories[1].trim() : "Not specified" ); // 取第二个值(如果存在) if (subCategoryName.value == "Accessories & fixtures") { subCategoryName.value = encodeURIComponent("Accessories & fixtures"); items.value[2].title = "Accessories & fixtures"; } else { items.value[2].title = subCategoryName.value; } items.value[1].title = mainCategory; items.value[1].href = "https://www.canrud.com/products?categories=" + mainCategory; href1.value = "https://www.canrud.com/products?categories=" + mainCategory; // items.value[1].title = subCategoryName.value; href2.value = href1.value + "," + subCategoryName.value; items.value[2].href = href1.value + "," + subCategoryName.value; if (routeQuery?.selectedFunction) { // items.value.push({ // title: routeQuery.selectedFunction, // disabled: false, // href: href2.value + "&function=" + routeQuery.selectedFunction, // }); items.value[3].title = routeQuery.selectedFunction; items.value[3].href = href2.value + "&function=" + routeQuery.selectedFunction; // routeQuery.updateFunction(null); } } else if (info?.productCrumbsVO?.category1) { items.value[1].title = info.productCrumbsVO.category1; items.value[1].href = "https://www.canrud.com/products?categories=" + info.productCrumbsVO.category1; href1.value = "https://www.canrud.com/products?categories=" + info.productCrumbsVO.category1; if (info?.productCrumbsVO?.category2) { items.value[2].title = info.productCrumbsVO.category2; href2.value = href1.value + "," + info.productCrumbsVO.category2; items.value[2].href = href1.value + "," + info.productCrumbsVO.category2; } if (info?.productCrumbsVO?.function) { // items.value.push({ // title: info.productCrumbsVO.function, // disabled: false, // href: href2.value + "&function=" + info.productCrumbsVO.function, // }); items.value[3].title = info.productCrumbsVO.function; items.value[3].href = href2.value + "&function=" + info.productCrumbsVO.function; } } recommendList.value = resData.value.data.records; // recommendImages.value = recommendList.value.slice(0, 10).map((item) => { recommendImages.value = Array.from({ length: 10 }).map((_, index) => { const item = recommendList.value[index]; if (!item) { return null; } // 检查 productimageliststore 是否为字符串格式,如果是,则尝试解析 if (typeof item.productimageliststore === "string") { try { item.productimageliststore = JSON.parse(item.productimageliststore); } catch (error) { item.productimageliststore = []; // 解析失败时,设置为空数组 } } const ree = (item.productimageliststore = item?.productimageliststore.map( (productItem: ProductImage) => ({ ...productItem, // url: `http://112.74.45.244:8100/api/show/image?fileKey=${item.fileKey}`, url: `/api/show/image?fileKey=${productItem.fileKey}&psize=p512`, name: item.name, productUrl: `http://www.canrud.com/products/detail/${item.id}`, }) )); return ree; }); }); // onMounted(() => { // dialogStore.updateDialog(true) // }) const currentIndex = ref(0); const navigateToUrl = (url) => { // window.open(url); // 在新标签页中打开链接 }; const toggleRow = () => { currentIndex.value = currentIndex.value === 0 ? 1 : 0; }; const tab = ref(0); const slide = ref(0); </script> <style lang="scss" scoped> .headerBorder { border-top: 3px solid #1f88e5 !important; } .tabs { border-bottom: 2px solid #1f88e5; } .active { background-color: #1086e8; } .td, th { border: 1px solid #dcdcdc; border-right: 0px; border-bottom: 0px !important; height: 50px !important; &:last-child { border: 1px solid #dcdcdc; } } .tr:last-child { .td { border-bottom: 1px solid #dcdcdc !important; } } .tw-sticky { position: sticky; } .carousel-container { position: relative; } .table-container { overflow-x: auto; /* 防止表格超出页面宽度 */ } .table1 { width: 100%; min-width: 600px; /* 设置表格最小宽度 */ } .tr { border-bottom: 1px solid #e0e0e0; /* 表格行样式 */ } .headerBorder { border-bottom: 2px solid #ccc; /* 表头边框 */ } .text-grey-darken-4 { color: #333; /* 表格文字颜色 */ } .breadcrumb-disabled { color: black; pointer-events: none; /* 禁用点击 */ text-decoration: none; /* 移除链接样式 */ } .breadcrumb-active { color: #1e88e5; } #image-container { display: flex; align-items: center; justify-content: center; height: 320px; margin-top: 10px; margin-bottom: 10px; } .image-row { display: flex; height: 245px; } .image-row img { width: 120px; height: 120px; } button .recommendButton { margin: 0 0px; cursor: pointer; } .recommend-left-box { } .recommend-img-left { width: 26px; height: 27px; margin-right: 30px; } .recommend-img-left:hover { cursor: pointer; } .recommend-right-box { } .recommend-img-right { width: 26px; height: 27px; margin-left: 30px; } .recommend-img-right:hover { cursor: pointer; } .social-share-container { display: flex; flex-direction: row; /* 父容器横向排列 */ gap: 1rem; /* 设置每个分享项之间的间距 */ } .social-share-item { display: flex; flex-direction: row; /* 每个分享项横向排列 */ align-items: center; /* 垂直居中对齐 */ gap: 0.5rem; /* 标题与按钮之间的间距 */ } .social-share-title { font-size: 1rem; font-weight: bold; } </style>