index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <script setup lang="ts">
  2. import { StaticUrl } from '@/config'
  3. import router from '@/router'
  4. const { statusBarHeight, MenuButtonHeight } = useSysStore()
  5. definePage({
  6. name: 'xsb-goods',
  7. islogin: false,
  8. style: {
  9. navigationStyle: 'custom',
  10. navigationBarTitleText: '星闪豹商品详情',
  11. },
  12. })
  13. // const goodsTab = ref(0)
  14. const current = ref<number>(0)
  15. const currentDetaile = ref(0)
  16. // const goodsTabList = ref([
  17. // { title: '相似商品', id: 0 },
  18. // { title: '经常一起买', id: 1 },
  19. // ])
  20. const goodsDetaileTabList = ref([
  21. { title: '商品', id: 0 },
  22. { title: '评价', id: 1 },
  23. { title: '详情', id: 2 },
  24. { title: '推荐', id: 3 },
  25. ])
  26. const goodsTabData = ref([])
  27. const isShowTab = ref(false)
  28. // const currentTabGoods = ref(0)
  29. const goodsId = ref()
  30. onLoad((option: any) => {
  31. goodsId.value = option.id
  32. getGoodsDetaile()
  33. })
  34. const goodsInfo = ref<Api.xsbProductDetail>()
  35. const swiperList = computed(() => {
  36. if (goodsInfo.value) {
  37. return goodsInfo.value.imgs?.split(',')
  38. }
  39. return []
  40. })
  41. const goodsContent = computed(() => {
  42. if (goodsInfo.value?.content) {
  43. return goodsInfo.value.content.replace(
  44. /<img/gi,
  45. '<img style="max-width:100%;height:auto" ',
  46. )
  47. }
  48. return '暂无数据'
  49. })
  50. onMounted(() => {
  51. // goodsTabData.value = splitArrayToPages([{ id: 1, name: '商品' }, { id: 2, name: '商品' }, { id: 3, name: '商品' }, { id: 4, name: '商品' }, { id: 8, name: '商品' }, { id: 5, name: '商品' }, { id: 10, name: '商品' }, { id: 6, name: '商品' }, { id: 9, name: '商品' }, { id: 7, name: '商品' }, { id: 11, name: '商品' }])
  52. console.log(goodsTabData.value, 'goodsTabData')
  53. })
  54. // function splitArrayToPages<T>(arr: T[]): T[][] {
  55. // const PAGE_SIZE = 6
  56. // const MAX_PAGES = 3
  57. // const result: T[][] = []
  58. // for (let i = 0; i < Math.min(MAX_PAGES, Math.ceil(arr.length / PAGE_SIZE)); i++) {
  59. // const start = i * PAGE_SIZE
  60. // const end = start + PAGE_SIZE
  61. // result.push(arr.slice(start, end))
  62. // }
  63. // return result
  64. // }
  65. onPageScroll((e) => {
  66. if (e.scrollTop >= 315) {
  67. isShowTab.value = true
  68. }
  69. else {
  70. isShowTab.value = false
  71. }
  72. })
  73. function handleGoCurren(id: number) {
  74. currentDetaile.value = id
  75. uni.pageScrollTo({ selector: `.view-${id}` })
  76. }
  77. async function getGoodsDetaile() {
  78. const res = await Apis.xsb.getProductDetail({ data: { id: goodsId.value } })
  79. console.log(res, '请求')
  80. goodsInfo.value = res
  81. }
  82. </script>
  83. <template>
  84. <view class="page-xsb">
  85. <wd-navbar
  86. title="商品详情" :custom-style="`background-color:${isShowTab ? '#FFF !important' : 'transparent !important'}`" :bordered="false" :z-index="99"
  87. safe-area-inset-top left-arrow fixed @click-left="router.back()"
  88. />
  89. <template v-if="goodsInfo">
  90. <wd-swiper v-model:current="current" :list="swiperList" autoplay :height="375">
  91. <template #indicator="{ current: currentIndex, total }">
  92. <view class="custom-indicator absolute bottom-60rpx right-20rpx px26rpx">
  93. {{ currentIndex + 1 }}/{{ total }}
  94. </view>
  95. </template>
  96. </wd-swiper>
  97. <view class="header view-0 relative z-3 rounded-t-32rpx px24rpx pt24rpx -mt30rpx">
  98. <view class="flex items-center justify-between">
  99. <view class="flex items-end text-#FF4D3A font-semibold">
  100. <view class="text-24rpx">
  101. </view>
  102. <view class="text-36rpx line-height-[36rpx]">
  103. {{ goodsInfo?.channelProdPrice }}
  104. </view>
  105. </view>
  106. <!-- <view>
  107. <image class="h40rpx w40rpx" :src="`${StaticUrl}/collect-yes.png`" />
  108. </view> -->
  109. </view>
  110. </view>
  111. <view class="sticky left-0 z-99 box-border h84rpx w-full flex items-center justify-between bg-white px24rpx" :style="{ top: `${statusBarHeight + MenuButtonHeight}px`, opacity: isShowTab ? 1 : 0 }" :class="[isShowTab ? '' : '']">
  112. <view v-for="item in goodsDetaileTabList" :key="item.id" class="relative flex items-center text-32rpx font-semibold" @click="handleGoCurren(item.id)">
  113. {{ item.title }}
  114. <view v-show="currentDetaile == item.id" class="line absolute left-50% h12rpx w40rpx rounded-8rpx bg-[var(--them-color)] -bottom-15rpx -translate-x-50%" />
  115. </view>
  116. </view>
  117. <view class="px24rpx">
  118. <view class="-mt64rpx">
  119. <view class="text-left text-28rpx font-semibold">
  120. <!-- <view v-for="i in 2" :key="i" class="mr5px inline-block">
  121. <wd-tag type="primary">
  122. 新品{{ i }}
  123. </wd-tag>
  124. </view> -->
  125. {{ goodsInfo.prodName }}
  126. </view>
  127. </view>
  128. <!-- <view class="mt16rpx text-24rpx text-#AAAAAA">
  129. 优选产地,皮薄核小,维c满满
  130. </view> -->
  131. <!-- <view class="mt20rpx flex items-center">
  132. <view
  133. v-for="item in 2" :key="item"
  134. class="mr16rpx flex items-center justify-center border-1rpx border-#BC9264 rounded-8rpx border-solid bg-[#FFF5E9] px16rpx py6rpx text-24rpx text-#BC9264 font-semibold"
  135. >
  136. 一口化渣{{ item }}
  137. </view>
  138. </view> -->
  139. <view class="mt20rpx flex items-center justify-between rounded-16rpx bg-white p24rpx">
  140. <view class="flex items-center">
  141. <view class="flex-shrink-0">
  142. <view class="text-28rpx font-semibold">
  143. {{ goodsInfo.brandName }}
  144. </view>
  145. <view class="mt16rpx text-24rpx text-#AAAAAA">
  146. 品牌
  147. </view>
  148. </view>
  149. </view>
  150. <view class="mx24rpx">
  151. <wd-divider vertical color="#F0F0F0" />
  152. </view>
  153. <view class="flex items-center">
  154. <view class="flex-shrink-0">
  155. <view class="text-28rpx font-semibold">
  156. {{ goodsInfo.weight }}
  157. </view>
  158. <view class="mt16rpx text-24rpx text-#AAAAAA">
  159. 重量
  160. </view>
  161. </view>
  162. </view>
  163. <view class="mx24rpx">
  164. <wd-divider vertical color="#F0F0F0" />
  165. </view>
  166. <view class="flex items-center">
  167. <view class="flex-shrink-0">
  168. <view class="text-28rpx font-semibold">
  169. {{ goodsInfo.weightUnit }}
  170. </view>
  171. <view class="mt16rpx text-24rpx text-#AAAAAA">
  172. 单位
  173. </view>
  174. </view>
  175. </view>
  176. <wd-icon name="chevron-right" size="22px" color="#AAAAAA" />
  177. </view>
  178. <!-- <view class="view-1 mt20rpx flex items-center rounded-16rpx bg-white p24rpx">
  179. <view class="w-full flex items-center justify-between">
  180. <view class="text-32rpx font-semibold">
  181. 评价(10万+)
  182. </view>
  183. <view class="flex items-center">
  184. <view class="mr10rpx flex items-center text-28rpx text-#FF4D3A">
  185. <view>好评率</view>
  186. <view class="ml5rpx font-semibold">
  187. 99.8%
  188. </view>
  189. </view>
  190. <wd-icon name="chevron-right" size="22px" color="#AAAAAA" />
  191. </view>
  192. </view>
  193. </view> -->
  194. <!-- <view class="mt20rpx rounded-16rpx bg-white p24rpx">
  195. <wd-tabs v-model="goodsTab">
  196. <block v-for="item in goodsTabList" :key="item.id">
  197. <wd-tab :title="item.title" />
  198. </block>
  199. </wd-tabs>
  200. <swiper class="mt20rpx h900rpx" indicator-active-color="var(--them-color)" @change="(e) => currentTabGoods = e.detail.current">
  201. <swiper-item
  202. v-for="items in goodsTabData" :key="items"
  203. class="grid grid-cols-3 items-start gap-x-16rpx gap-y-16rpx pb20rpx"
  204. >
  205. <view
  206. v-for="goods in items" :key="goods"
  207. class="box-border w204rpx border border-2rpx border-#F0F0F0 rounded-16rpx border-solid px4rpx py8rpx"
  208. >
  209. <image lazy-load :src="`${StaticUrl}/shu.png`" class="h188rpx w198rpx" />
  210. <view class="mt20rpx px16rpx text-24rpx font-semibold">
  211. 新鲜现宰杀肋排200g
  212. </view>
  213. <view class="mt12rpx truncate px16rpx text-24rpx text-#AAAAAA">
  214. 维c满满,营养qweqwe
  215. </view>
  216. <view class="my20rpx flex items-center justify-between px16rpx">
  217. <view class="flex items-end text-#FF4D3A font-semibold">
  218. <view class="text-24rpx">
  219. </view>
  220. <view class="text-32rpx line-height-[32rpx]">
  221. 1.395
  222. </view>
  223. </view>
  224. <image :src="`${StaticUrl}/cart-yes.png`" class="h44rpx w44rpx" />
  225. </view>
  226. </view>
  227. </swiper-item>
  228. </swiper>
  229. <view class="mt24rpx flex items-center justify-center">
  230. <view v-for="item, idx in goodsTabData" :key="idx" class="mr14rpx transition-all transition-duration-400 ease-in" :class="[currentTabGoods == idx ? 'rounded-12rpx w-40rpx h12rpx bg-[var(--them-color)]' : 'w12rpx h12rpx rounded-50% bg-#F0F0F0']" />
  231. </view>
  232. </view> -->
  233. </view>
  234. <view class="view-2 mt20rpx bg-white">
  235. <view class="p24rpx text-32rpx font-semibold">
  236. 商品详情
  237. <rich-text :nodes="goodsContent" />
  238. </view>
  239. </view>
  240. <!-- <view class="view-3 mt28rpx flex items-center justify-center">
  241. <view class="flex items-center">
  242. <image
  243. :src="`${StaticUrl}/goods-recommend.png`"
  244. class="mr12rpx h25rpx w26rpx"
  245. />
  246. <view class="text-36rpx text-[var(--them-color)] font-semibold">
  247. 为你推荐
  248. </view>
  249. <image
  250. :src="`${StaticUrl}/goods-recommend.png`"
  251. class="ml12rpx h25rpx w26rpx"
  252. />
  253. </view>
  254. </view> -->
  255. <view class="h180rpx" />
  256. <view class="ios shadow-fixed fixed bottom-0 left-0 w-full rounded-t-32rpx bg-white">
  257. <view class="flex items-center justify-between px24rpx py20rpx">
  258. <view class="mr36rpx" @click="router.replace({ name: 'xsb-homeTabbar' })">
  259. <image
  260. :src="`${StaticUrl}/goods-home.png`"
  261. class="h44rpx w44rpx"
  262. />
  263. <view class="text-20rpx">
  264. 首页
  265. </view>
  266. </view>
  267. <view class="mr36rpx">
  268. <view class="h44rpx w44rpx">
  269. <wd-button :icon="`${StaticUrl}/goods-kf.png`" type="icon" open-type="contact" />
  270. </view>
  271. <view class="text-20rpx">
  272. 客服
  273. </view>
  274. </view>
  275. <view @click="router.replace({ name: 'xsb-homeTabbar', animationType: 'fade-out', params: { name: 'xsb-cart' } })">
  276. <image
  277. :src="`${StaticUrl}/goods-cart.png`"
  278. class="h44rpx w44rpx"
  279. />
  280. <view class="text-20rpx">
  281. 购物车
  282. </view>
  283. </view>
  284. <view class="flex items-center">
  285. <view class="w220rpx">
  286. <wd-button hairline plain block>
  287. 加入购物车
  288. </wd-button>
  289. </view>
  290. <view class="ml20rpx w220rpx" @click="router.push({ name: 'common-confirmOrder' })">
  291. <wd-button block class="w-full">
  292. 立即购买
  293. </wd-button>
  294. </view>
  295. </view>
  296. </view>
  297. </view>
  298. </template>
  299. </view>
  300. </template>
  301. <style scoped lang="scss">
  302. .custom-indicator {
  303. border-radius: 16rpx;
  304. background: rgba(0, 0, 0, 0.5);
  305. color: #ffffff;
  306. font-size: 24rpx;
  307. }
  308. .shadow-fixed{
  309. box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0,0,0,0.09);
  310. }
  311. .header {
  312. background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 62%, #F6F6F6 100%);
  313. }
  314. .page-xsb {
  315. :deep() {
  316. .wd-tabs__nav-container .wd-tabs__nav-item:nth-child(2){
  317. width: 220rpx !important ;
  318. }
  319. .wd-tabs__nav-item {
  320. flex:unset !important;
  321. .wd-tabs__nav-item-text {
  322. font-size: 32rpx !important;
  323. }
  324. }
  325. .ios .wd-button{
  326. min-width: unset !important;
  327. }
  328. }
  329. }
  330. </style>