|
@@ -1,487 +0,0 @@
|
|
|
-<!-- @format -->
|
|
|
-
|
|
|
-<script lang="ts" setup>
|
|
|
-import { ArrowRight } from '@element-plus/icons-vue'
|
|
|
-import { Swiper, SwiperSlide } from 'swiper/vue'
|
|
|
-import { Navigation, Pagination } from 'swiper/modules'
|
|
|
-import dayjs from 'dayjs'
|
|
|
-import { ConstKeys } from '~/enums/const-enums'
|
|
|
-import { PageSizeEnum } from '~/enums/sizeEnum'
|
|
|
-import {
|
|
|
- getFeatureAlumDetailApi,
|
|
|
- getFeatureBrandsListApi,
|
|
|
- getFeatureDetailApi,
|
|
|
- getFeatureGoodsListApi,
|
|
|
-} from '~/api/model/feature'
|
|
|
-import img02 from '~/assets/images/featured_img02.png'
|
|
|
-import img03 from '~/assets/images/featured_img03.png'
|
|
|
-import img04 from '~/assets/images/featured_img04.png'
|
|
|
-import img05 from '~/assets/images/featured_img05.png'
|
|
|
-
|
|
|
-import 'swiper/css'
|
|
|
-import 'swiper/css/navigation'
|
|
|
-// import "swiper/css/pagination"
|
|
|
-
|
|
|
-import { useUserStore } from '@/stores/modules/user'
|
|
|
-
|
|
|
-enum Type {
|
|
|
- Detail = '0',
|
|
|
- Album = '1',
|
|
|
-}
|
|
|
-
|
|
|
-const userStore = useUserStore()
|
|
|
-const { isLogin } = storeToRefs(userStore)
|
|
|
-const { openLoginModal } = useLoginModal()
|
|
|
-
|
|
|
-const modules = [Navigation, Pagination]
|
|
|
-const brandList = ref<any>([])
|
|
|
-const swiperVertical = ref<any>(null)
|
|
|
-
|
|
|
-const detail = ref()
|
|
|
-const list = ref<any>([])
|
|
|
-const currentPage = ref(0)
|
|
|
-const total = ref(0)
|
|
|
-const page_size = ref(20)
|
|
|
-const isEffective = ref(true)
|
|
|
-const staticList = ref([
|
|
|
- {
|
|
|
- icon: img02,
|
|
|
- title: 'Source Manufacturers',
|
|
|
- subTitle:
|
|
|
- 'Selected product suppliers with the capability to develop unique products.',
|
|
|
- },
|
|
|
- {
|
|
|
- icon: img03,
|
|
|
- title: 'Competitive Pricing',
|
|
|
- subTitle:
|
|
|
- 'Get the best quality products at the most competitive wholesale prices.',
|
|
|
- },
|
|
|
- {
|
|
|
- icon: img04,
|
|
|
- title: 'Strict Quality Control',
|
|
|
- subTitle:
|
|
|
- 'Strict quality inspection to ensure the products meet our high standards.',
|
|
|
- },
|
|
|
- {
|
|
|
- icon: img05,
|
|
|
- title: 'Dedicated Support',
|
|
|
- subTitle:
|
|
|
- 'Smooth wholesale experience with dedicated customer manager service.',
|
|
|
- },
|
|
|
-])
|
|
|
-
|
|
|
-const route = useRoute()
|
|
|
-const paintingId = route.query.paintingId
|
|
|
-const slug = route.params.name
|
|
|
-
|
|
|
-const { data, pending, error, refresh } = await useAsyncData(
|
|
|
- 'featured-detail',
|
|
|
- () => $fetch(`${ConstKeys.DOMAINPRO}/client/topic/detail`, { params: { slug } }),
|
|
|
-)
|
|
|
-const seoData = data.value?.result
|
|
|
-
|
|
|
-useHead({
|
|
|
- title: seoData?.title,
|
|
|
- meta: [
|
|
|
- {
|
|
|
- name: 'description',
|
|
|
- content: seoData?.headImageText,
|
|
|
- },
|
|
|
- {
|
|
|
- property: 'og:title',
|
|
|
- content: seoData?.title,
|
|
|
- },
|
|
|
- {
|
|
|
- property: 'og:description',
|
|
|
- content: seoData?.headImageText,
|
|
|
- },
|
|
|
- {
|
|
|
- property: 'og:type',
|
|
|
- content: 'website',
|
|
|
- },
|
|
|
- {
|
|
|
- property: 'twitter:title',
|
|
|
- content: seoData?.title,
|
|
|
- },
|
|
|
- {
|
|
|
- property: 'twitter:description',
|
|
|
- content: seoData?.headImageText,
|
|
|
- },
|
|
|
- {
|
|
|
- property: 'twitter:card',
|
|
|
- content: 'summary_large_image',
|
|
|
- },
|
|
|
- ],
|
|
|
- link: [
|
|
|
- {
|
|
|
- rel: 'canonical',
|
|
|
- href: `${ConstKeys.DOMAINPRO}/collections/${slug}`,
|
|
|
- },
|
|
|
- ],
|
|
|
-})
|
|
|
-const isType = computed(() => detail.value?.type === Type.Detail)
|
|
|
-async function getFeatureDetail() {
|
|
|
- try {
|
|
|
- const result = await getFeatureDetailApi({ slug })
|
|
|
- detail.value = result
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.log('error', error)
|
|
|
- }
|
|
|
-}
|
|
|
-async function getFeatureAlumDetail() {
|
|
|
- try {
|
|
|
- const result = await getFeatureAlumDetailApi({ paintingId })
|
|
|
- isEffective.value = true
|
|
|
- detail.value = result
|
|
|
- }
|
|
|
- catch (error: any) {
|
|
|
- if (error.code === 10010)
|
|
|
- isEffective.value = false
|
|
|
- console.log('error', error)
|
|
|
- }
|
|
|
-}
|
|
|
-async function getFeatureProductList(
|
|
|
- pageNo = PageSizeEnum.PAGE,
|
|
|
- pageSize = page_size.value,
|
|
|
-) {
|
|
|
- const res: any = await getFeatureGoodsListApi({
|
|
|
- pageNo,
|
|
|
- pageSize,
|
|
|
- topicSlug: slug,
|
|
|
- })
|
|
|
- list.value = res.records
|
|
|
- currentPage.value = res.current
|
|
|
- total.value = res.total
|
|
|
-}
|
|
|
-function updatePage(currentPage: number, pageSize: number) {
|
|
|
- getFeatureProductList(currentPage, pageSize)
|
|
|
-}
|
|
|
-async function getHomeBrandList() {
|
|
|
- try {
|
|
|
- const data: any = await getFeatureBrandsListApi({
|
|
|
- pageNo: 1,
|
|
|
- pageSize: page_size.value,
|
|
|
- topicSlug: slug,
|
|
|
- })
|
|
|
- brandList.value = data.records
|
|
|
- }
|
|
|
- catch (error) {
|
|
|
- console.log('error', error)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function onVerticalSwiper(swiper: any) {
|
|
|
- swiperVertical.value = swiper
|
|
|
-}
|
|
|
-function onClickLeft() {
|
|
|
- swiperVertical.value.slidePrev()
|
|
|
-}
|
|
|
-function onClickRight() {
|
|
|
- swiperVertical.value.slideNext()
|
|
|
-}
|
|
|
-function getData() {
|
|
|
- if (!paintingId) {
|
|
|
- getHomeBrandList()
|
|
|
- getFeatureProductList()
|
|
|
- getFeatureDetail()
|
|
|
- }
|
|
|
- else {
|
|
|
- getFeatureAlumDetail()
|
|
|
- }
|
|
|
-}
|
|
|
-getData()
|
|
|
-async function openLogin() {
|
|
|
- await openLoginModal()
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<template>
|
|
|
- <div class="pos-relative">
|
|
|
- <div v-if="isType" class="fixed-image">
|
|
|
- <img
|
|
|
- :src="detail?.headImageUrl"
|
|
|
- class="w-full h-360px object-cover"
|
|
|
- alt=""
|
|
|
- srcset=""
|
|
|
- >
|
|
|
- </div>
|
|
|
- <div class="scrollable-content">
|
|
|
- <div
|
|
|
- v-if="isType"
|
|
|
- :class="isType ? 'h-360px' : ''"
|
|
|
- class="content-header"
|
|
|
- >
|
|
|
- <h1 class="!text-36px !fw-700 custom-title-font">
|
|
|
- {{ detail?.title }}
|
|
|
- </h1>
|
|
|
- <div class="text-18px">
|
|
|
- {{ detail?.headImageText }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div :class="isType ? 'bg-#fff' : ''">
|
|
|
- <div v-if="isEffective" class="w-1400px mx-auto pt-40px pb-60px">
|
|
|
- <el-breadcrumb :separator-icon="ArrowRight">
|
|
|
- <el-breadcrumb-item :to="{ path: '/' }">
|
|
|
- Home
|
|
|
- </el-breadcrumb-item>
|
|
|
- <el-breadcrumb-item :to="{ path: '/collections' }">
|
|
|
- Collections
|
|
|
- </el-breadcrumb-item>
|
|
|
- <el-breadcrumb-item> {{ detail?.title }}</el-breadcrumb-item>
|
|
|
- </el-breadcrumb>
|
|
|
- </div>
|
|
|
- <div v-if="isEffective" class="w-1400px mx-auto mb-60px">
|
|
|
- <h1 class="!text-26px !fw-700 text-#363C40 custom-title-font">
|
|
|
- {{ detail?.title }}
|
|
|
- </h1>
|
|
|
- <div class="flex my-24px text-#7C7C7C text-18px">
|
|
|
- <div class="mr-48px">
|
|
|
- {{ dayjs(detail?.createTime).format('MMMM D, YYYY') }}
|
|
|
- </div>
|
|
|
- <div v-if="isType">
|
|
|
- {{ detail?.merchandiseQuantity }} products
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="text-18px lh-24px line-clamp-3 text-#666"
|
|
|
- :title="detail?.headImageText"
|
|
|
- >
|
|
|
- {{ detail?.headImageText }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <div v-if="isType">
|
|
|
- <div
|
|
|
- v-if="isLogin || !detail?.userEnable"
|
|
|
- class="w-1400px mx-auto pb-160px"
|
|
|
- >
|
|
|
- <div
|
|
|
- v-if="list.length"
|
|
|
- class="grid grid-gap-x-65px grid-gap-y-80px grid-cols-4"
|
|
|
- >
|
|
|
- <div v-for="item in list" :key="item.id">
|
|
|
- <common-goods-item :item />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <common-empty v-else class="py-50px" title="">
|
|
|
- <template #icon>
|
|
|
- <img
|
|
|
- src="~/assets/images/featured_empty.png"
|
|
|
- class="w-200px h-200px"
|
|
|
- alt=""
|
|
|
- srcset=""
|
|
|
- >
|
|
|
- </template>
|
|
|
- </common-empty>
|
|
|
- <div v-if="list.length" class="mt-60px flex justify-center">
|
|
|
- <el-pagination
|
|
|
- v-model:current-page="currentPage"
|
|
|
- :page-size="page_size"
|
|
|
- :pager-count="10"
|
|
|
- layout="prev, pager, next"
|
|
|
- :total="total"
|
|
|
- @change="updatePage"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-else
|
|
|
- class="w-1400px mx-auto pt-80px pb-160px flex justify-center"
|
|
|
- >
|
|
|
- <div class="cursor-pointer" @click="openLogin">
|
|
|
- <svgo-lock class="!w-100px !h-100px text-#999 m-auto" />
|
|
|
- <div class="text-#999 text-42px mt-20px">
|
|
|
- Login to view
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div v-else class="text-#000 w-1400px mx-auto pb-160px">
|
|
|
- <div
|
|
|
- v-if="isEffective"
|
|
|
- class="text-#333333 content-detail custom-html"
|
|
|
- v-html="detail?.content"
|
|
|
- />
|
|
|
- <div v-else class="pt-160px">
|
|
|
- Sorry, the shared content has expired.
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-if="isType"
|
|
|
- class="flex justify-center items-center py-82px bg-#FAF5F1"
|
|
|
- >
|
|
|
- <div class="w-600px">
|
|
|
- <h2 class="fw-700 text-32px text-#333 !mb-60px">
|
|
|
- Quality Wholesale, Inspiring Global Retail
|
|
|
- </h2>
|
|
|
- <div
|
|
|
- v-for="(item, index) in staticList"
|
|
|
- :key="index"
|
|
|
- class="flex items-center mb-40px last:mb-0"
|
|
|
- >
|
|
|
- <img :src="item.icon" alt="" srcset="" class="w-40px h-40px">
|
|
|
- <div class="ml-30px w-430px">
|
|
|
- <h3 class="!fw-500 text-26px text-#333 lh-30px">
|
|
|
- {{ item.title }}
|
|
|
- </h3>
|
|
|
- <div class="mt-10px text-18px text-#999 lh-28px">
|
|
|
- {{ item.subTitle }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <img
|
|
|
- src="~/assets/images/featured_img01.png"
|
|
|
- class="w-566px h-480px object-cover ml-10px"
|
|
|
- alt=""
|
|
|
- srcset=""
|
|
|
- >
|
|
|
- </div>
|
|
|
- <div v-if="isType" class="py-160px w-1400px mx-auto">
|
|
|
- <h2 class="!mb-40px fw-700 text-40px text-#363C40">
|
|
|
- Collection Brands
|
|
|
- </h2>
|
|
|
- <div v-if="brandList.length">
|
|
|
- <div class="w-1300px mx-auto pos-relative">
|
|
|
- <div
|
|
|
- class="pos-absolute cursor-pointer left--46px top-200px w-28px h-28px transform-translate-y--50% cursor-not-allowed !cursor-pointer flex justify-center items-center"
|
|
|
- @click="onClickLeft()"
|
|
|
- >
|
|
|
- <img
|
|
|
- src="~/assets/images/arrow_left.png"
|
|
|
- alt=""
|
|
|
- class="w-26px h-26px"
|
|
|
- srcset=""
|
|
|
- >
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="pos-absolute cursor-pointer right--46px top-200px w-28px h-28px transform-translate-y--50% cursor-not-allowed !cursor-pointer flex justify-center items-center"
|
|
|
- @click="onClickRight()"
|
|
|
- >
|
|
|
- <img
|
|
|
- src="~/assets/images/arrow_right.png"
|
|
|
- alt=""
|
|
|
- class="w-26px h-26px"
|
|
|
- srcset=""
|
|
|
- >
|
|
|
- </div>
|
|
|
- <Swiper
|
|
|
- :slides-per-view="4"
|
|
|
- :space-between="55"
|
|
|
- :modules="modules"
|
|
|
- :loop="true"
|
|
|
- :navigation="false"
|
|
|
- :pagination="true"
|
|
|
- class="pos-relative"
|
|
|
- @swiper="onVerticalSwiper"
|
|
|
- >
|
|
|
- <SwiperSlide v-for="(item, index) in brandList" :key="index">
|
|
|
- <common-brand-item :item="item" />
|
|
|
- </SwiperSlide>
|
|
|
- </Swiper>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <common-empty v-else class="pt-50px" title="">
|
|
|
- <template #icon>
|
|
|
- <img
|
|
|
- src="~/assets/images/featured_empty.png"
|
|
|
- class="w-200px h-200px"
|
|
|
- alt=""
|
|
|
- srcset=""
|
|
|
- >
|
|
|
- </template>
|
|
|
- </common-empty>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <AppFooter class="bg-#fff" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<style lang="less" scoped>
|
|
|
-.fixed-image {
|
|
|
- position: fixed;
|
|
|
- top: 151px;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 360px;
|
|
|
- z-index: 1;
|
|
|
- overflow: hidden;
|
|
|
-}
|
|
|
-
|
|
|
-.scrollable-content {
|
|
|
- position: relative;
|
|
|
- z-index: 2;
|
|
|
- width: 100%;
|
|
|
- color: white;
|
|
|
-
|
|
|
- .content-header {
|
|
|
- display: flex;
|
|
|
- // height: 360px;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- text-align: center;
|
|
|
- background: rgba(0, 0, 0, 0.4);
|
|
|
- /* 半透明背景使文字在图片上更可读 */
|
|
|
- }
|
|
|
- ::v-deep(.content-detail) {
|
|
|
- font-family: sans-serif;
|
|
|
- h2 {
|
|
|
- font-size: 1.5em;
|
|
|
- font-family: 'CustomTitleFont';
|
|
|
- margin-top: 1em !important;
|
|
|
- margin-bottom: 1em !important;
|
|
|
- font-weight: bold;
|
|
|
- }
|
|
|
- h3 {
|
|
|
- display: block;
|
|
|
- font-size: 1.17em;
|
|
|
- margin-block-start: 1em;
|
|
|
- margin-block-end: 1em;
|
|
|
- margin-inline-start: 0px;
|
|
|
- margin-inline-end: 0px;
|
|
|
- margin-bottom: 1em !important;
|
|
|
- font-weight: bold;
|
|
|
- unicode-bidi: isolate;
|
|
|
- font-family: 'CustomTitleFont';
|
|
|
- }
|
|
|
- p {
|
|
|
- display: block;
|
|
|
- margin-block-start: 1em;
|
|
|
- margin-block-end: 1em;
|
|
|
- margin-inline-start: 0px;
|
|
|
- margin-inline-end: 0px;
|
|
|
- unicode-bidi: isolate;
|
|
|
- }
|
|
|
- ul {
|
|
|
- display: block;
|
|
|
- list-style-type: disc;
|
|
|
- margin-block-start: 1em;
|
|
|
- margin-block-end: 1em;
|
|
|
- margin-inline-start: 0px;
|
|
|
- margin-inline-end: 0px;
|
|
|
- padding-inline-start: 40px;
|
|
|
- unicode-bidi: isolate;
|
|
|
- li {
|
|
|
- display: list-item;
|
|
|
- text-align: -webkit-match-parent;
|
|
|
- unicode-bidi: isolate;
|
|
|
- }
|
|
|
- }
|
|
|
- ol {
|
|
|
- list-style-type: decimal;
|
|
|
- display: block;
|
|
|
- list-style-type: decimal;
|
|
|
- margin-block-start: 1em;
|
|
|
- margin-block-end: 1em;
|
|
|
- margin-inline-start: 0px;
|
|
|
- margin-inline-end: 0px;
|
|
|
- padding-inline-start: 40px;
|
|
|
- unicode-bidi: isolate;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|