|
@@ -1,232 +1,234 @@
|
|
|
-import request from '@/helpers/request'
|
|
|
-import { moneyFormat } from '@/helpers/utils'
|
|
|
-import { Swipe, SwipeItem, Image, CellGroup, Cell, showImagePreview } from 'vant'
|
|
|
-import { defineComponent } from 'vue'
|
|
|
-import styles from './index.module.less'
|
|
|
-import iconGives from '../pre-apply/images/icon-gives.png'
|
|
|
-
|
|
|
-export default defineComponent({
|
|
|
- name: 'goods-detail',
|
|
|
- props: {
|
|
|
- groupPrice: {
|
|
|
- type: Number,
|
|
|
- default: 0
|
|
|
- },
|
|
|
- goodsInfo: {
|
|
|
- type: Object,
|
|
|
- default: () => ({})
|
|
|
- },
|
|
|
- id: {
|
|
|
- type: String,
|
|
|
- defualt: ''
|
|
|
- }
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- albumPics: [] as any[],
|
|
|
- product: {} as Record<string | number | symbol, any>,
|
|
|
- radio: 0,
|
|
|
- skuStockListTemp: [],
|
|
|
- detailMobileHtml: '',
|
|
|
- loading: false,
|
|
|
- addGoodsShow: false,
|
|
|
- selectGoodsItem: {},
|
|
|
- cartCount: 0,
|
|
|
- showType: 'cart',
|
|
|
- shareShow: false // 分享弹窗
|
|
|
- }
|
|
|
- },
|
|
|
- computed: {
|
|
|
- skuStockList() {
|
|
|
- // 处理规格
|
|
|
- const product = this.product
|
|
|
- const skuStockList: any =
|
|
|
- this.skuStockListTemp.length > 0
|
|
|
- ? this.skuStockListTemp
|
|
|
- : [
|
|
|
- {
|
|
|
- id: -1,
|
|
|
- price: product.price,
|
|
|
- pic: product.pic,
|
|
|
- stock: product.stock,
|
|
|
- spData: null
|
|
|
- }
|
|
|
- ]
|
|
|
- skuStockList.forEach((item: any) => {
|
|
|
- if (item.spData) {
|
|
|
- const spData = JSON.parse(item.spData)
|
|
|
- item.spDataJson = spData.reduce((spDataJson, value) => {
|
|
|
- spDataJson += value.value
|
|
|
- return spDataJson
|
|
|
- }, '')
|
|
|
- item.sku = spData
|
|
|
- .reduce((sku, value) => {
|
|
|
- sku.push(`${value.key}: ${value.value}`)
|
|
|
- return sku
|
|
|
- }, [])
|
|
|
- .join(',')
|
|
|
- } else {
|
|
|
- item.spDataJson = '默认'
|
|
|
- }
|
|
|
- })
|
|
|
- return skuStockList
|
|
|
- },
|
|
|
- getPrice() {
|
|
|
- const item = this.skuStockList.filter((n) => n.id == this.radio) as any
|
|
|
- if (item && Array.isArray(item) && item.length) {
|
|
|
- return item[0].price
|
|
|
- }
|
|
|
- return 0
|
|
|
- }
|
|
|
- },
|
|
|
- async mounted() {
|
|
|
- try {
|
|
|
- this.loading = true
|
|
|
- const res = await request.get(`/api-student/open/mall/product/detail/${this.id}`)
|
|
|
- this.loading = false
|
|
|
- const result = res.data || {}
|
|
|
- this.albumPics = [result.product.pic]
|
|
|
- .concat(result.product.albumPics.split(','))
|
|
|
- .filter((n) => n)
|
|
|
- this.product = result.product
|
|
|
- this.skuStockListTemp = result.skuStockList || []
|
|
|
- if (this.skuStockListTemp.length) {
|
|
|
- const len = this.skuStockListTemp.length
|
|
|
- for (let i = 0; i < len; i++) {
|
|
|
- const item = this.skuStockListTemp[i] as any
|
|
|
- if (item.stock >= 0) {
|
|
|
- this.radio = item.id
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- this.detailMobileHtml = result.product.detailMobileHtml || result.product.detailHtml
|
|
|
- } catch {
|
|
|
- //
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- onPreview(index: number) {
|
|
|
- // 图片预览
|
|
|
- showImagePreview({
|
|
|
- images: this.albumPics,
|
|
|
- startPosition: index,
|
|
|
- closeable: true,
|
|
|
- className: styles.imagesOverlayWrap
|
|
|
- })
|
|
|
- },
|
|
|
- onShowImg(target: any) {
|
|
|
- const { localName } = target.srcElement
|
|
|
- if (localName !== 'img') {
|
|
|
- return
|
|
|
- }
|
|
|
- let startPosition = 0
|
|
|
- const domList = document.querySelectorAll('.msgWrap img')
|
|
|
- const imgList = Array.from(domList).map((item: any, index: number) => {
|
|
|
- if (target.srcElement == item) {
|
|
|
- startPosition = index
|
|
|
- }
|
|
|
- return item.src
|
|
|
- })
|
|
|
-
|
|
|
- showImagePreview({
|
|
|
- images: imgList,
|
|
|
- startPosition: startPosition,
|
|
|
- closeable: true,
|
|
|
- className: styles.imagesOverlayWrap
|
|
|
- })
|
|
|
- },
|
|
|
- onShowCart(type = 'cart') {
|
|
|
- this.selectGoodsItem = {
|
|
|
- price: this.product.pic,
|
|
|
- stock: this.product.stock,
|
|
|
- skuStockList: this.skuStockListTemp.length ? this.skuStockListTemp : undefined,
|
|
|
- brandName: this.product.brandName,
|
|
|
- productCategoryId: this.product.productCategoryId,
|
|
|
- name: this.product.name,
|
|
|
- productSn: this.product.productSn,
|
|
|
- productSubTitle: this.product.subTitle,
|
|
|
- id: this.product.id
|
|
|
- }
|
|
|
- this.showType = type
|
|
|
- // 打开购物弹框
|
|
|
- this.addGoodsShow = true
|
|
|
- }
|
|
|
- },
|
|
|
- render() {
|
|
|
- const product = this.product
|
|
|
- const selectSku = this.skuStockList.find((n: any) => n.id === this.radio)
|
|
|
- return (
|
|
|
- <div class={styles.goodsDetail}>
|
|
|
- <Swipe
|
|
|
- class={styles.swipe}
|
|
|
- lazyRender
|
|
|
- v-slots={{
|
|
|
- indicator: (item: any) =>
|
|
|
- item.total > 1 && (
|
|
|
- <div class={styles['custom-indicator']}>
|
|
|
- {(item.active || 0) + 1} / {item.total}
|
|
|
- </div>
|
|
|
- )
|
|
|
- }}
|
|
|
- >
|
|
|
- {this.albumPics.map((item: string, index: number) => (
|
|
|
- <SwipeItem>
|
|
|
- <Image
|
|
|
- class={styles.swipeItemImg}
|
|
|
- src={item}
|
|
|
- onClick={() => this.onPreview(index)}
|
|
|
- fit="cover"
|
|
|
- />
|
|
|
- </SwipeItem>
|
|
|
- ))}
|
|
|
- </Swipe>
|
|
|
-
|
|
|
- <CellGroup border={false} class={[styles.goodsHead, 'mb12']}>
|
|
|
- <Cell
|
|
|
- center
|
|
|
- border={false}
|
|
|
- v-slots={{
|
|
|
- title: () => (
|
|
|
- <div class={styles.priceGroup}>
|
|
|
- <span class={styles.price}>
|
|
|
- <i>¥ </i>
|
|
|
- {moneyFormat(this.groupPrice)}
|
|
|
- </span>
|
|
|
- <del class={styles.delPrice}>¥ {moneyFormat(product.originalPrice)}</del>
|
|
|
- </div>
|
|
|
- )
|
|
|
- // default: () => <div class={styles.stock}>销量4件</div>
|
|
|
- }}
|
|
|
- />
|
|
|
- <Cell
|
|
|
- center
|
|
|
- border={false}
|
|
|
- title={product.name}
|
|
|
- titleClass={[styles.goodsName, 'van-ellipsis']}
|
|
|
- />
|
|
|
- {this.goodsInfo.showFree && (
|
|
|
- <div class={styles.sectionTips}>
|
|
|
- <Image src={iconGives} class={styles.iconGives} />
|
|
|
- 赠价值{this.goodsInfo.originalPrice}元乐器维保服务一年
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </CellGroup>
|
|
|
-
|
|
|
- {this.detailMobileHtml && (
|
|
|
- <div class={[styles.section]}>
|
|
|
- <div class={styles.detail}>
|
|
|
- <span>图文详情</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div
|
|
|
- class={[styles.photoDetail, 'msgWrap']}
|
|
|
- onClick={this.onShowImg}
|
|
|
- v-html={this.detailMobileHtml}
|
|
|
- ></div>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- )
|
|
|
- }
|
|
|
-})
|
|
|
+import request from '@/helpers/request'
|
|
|
+import { browser, moneyFormat } from '@/helpers/utils'
|
|
|
+import { Swipe, SwipeItem, Image, CellGroup, Cell, showImagePreview } from 'vant'
|
|
|
+import { defineComponent } from 'vue'
|
|
|
+import styles from './index.module.less'
|
|
|
+import iconGives from '../pre-apply/images/icon-gives.png'
|
|
|
+import OHeader from '@/components/o-header'
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'goods-detail',
|
|
|
+ props: {
|
|
|
+ groupPrice: {
|
|
|
+ type: Number,
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ goodsInfo: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({})
|
|
|
+ },
|
|
|
+ id: {
|
|
|
+ type: String,
|
|
|
+ defualt: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ albumPics: [] as any[],
|
|
|
+ product: {} as Record<string | number | symbol, any>,
|
|
|
+ radio: 0,
|
|
|
+ skuStockListTemp: [],
|
|
|
+ detailMobileHtml: '',
|
|
|
+ loading: false,
|
|
|
+ addGoodsShow: false,
|
|
|
+ selectGoodsItem: {},
|
|
|
+ cartCount: 0,
|
|
|
+ showType: 'cart',
|
|
|
+ shareShow: false // 分享弹窗
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ skuStockList() {
|
|
|
+ // 处理规格
|
|
|
+ const product = this.product
|
|
|
+ const skuStockList: any =
|
|
|
+ this.skuStockListTemp.length > 0
|
|
|
+ ? this.skuStockListTemp
|
|
|
+ : [
|
|
|
+ {
|
|
|
+ id: -1,
|
|
|
+ price: product.price,
|
|
|
+ pic: product.pic,
|
|
|
+ stock: product.stock,
|
|
|
+ spData: null
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ skuStockList.forEach((item: any) => {
|
|
|
+ if (item.spData) {
|
|
|
+ const spData = JSON.parse(item.spData)
|
|
|
+ item.spDataJson = spData.reduce((spDataJson, value) => {
|
|
|
+ spDataJson += value.value
|
|
|
+ return spDataJson
|
|
|
+ }, '')
|
|
|
+ item.sku = spData
|
|
|
+ .reduce((sku, value) => {
|
|
|
+ sku.push(`${value.key}: ${value.value}`)
|
|
|
+ return sku
|
|
|
+ }, [])
|
|
|
+ .join(',')
|
|
|
+ } else {
|
|
|
+ item.spDataJson = '默认'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return skuStockList
|
|
|
+ },
|
|
|
+ getPrice() {
|
|
|
+ const item = this.skuStockList.filter((n) => n.id == this.radio) as any
|
|
|
+ if (item && Array.isArray(item) && item.length) {
|
|
|
+ return item[0].price
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ try {
|
|
|
+ this.loading = true
|
|
|
+ const res = await request.get(`/api-student/open/mall/product/detail/${this.id}`)
|
|
|
+ this.loading = false
|
|
|
+ const result = res.data || {}
|
|
|
+ this.albumPics = [result.product.pic]
|
|
|
+ .concat(result.product.albumPics.split(','))
|
|
|
+ .filter((n) => n)
|
|
|
+ this.product = result.product
|
|
|
+ this.skuStockListTemp = result.skuStockList || []
|
|
|
+ if (this.skuStockListTemp.length) {
|
|
|
+ const len = this.skuStockListTemp.length
|
|
|
+ for (let i = 0; i < len; i++) {
|
|
|
+ const item = this.skuStockListTemp[i] as any
|
|
|
+ if (item.stock >= 0) {
|
|
|
+ this.radio = item.id
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.detailMobileHtml = result.product.detailMobileHtml || result.product.detailHtml
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onPreview(index: number) {
|
|
|
+ // 图片预览
|
|
|
+ showImagePreview({
|
|
|
+ images: this.albumPics,
|
|
|
+ startPosition: index,
|
|
|
+ closeable: true,
|
|
|
+ className: styles.imagesOverlayWrap
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onShowImg(target: any) {
|
|
|
+ const { localName } = target.srcElement
|
|
|
+ if (localName !== 'img') {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let startPosition = 0
|
|
|
+ const domList = document.querySelectorAll('.msgWrap img')
|
|
|
+ const imgList = Array.from(domList).map((item: any, index: number) => {
|
|
|
+ if (target.srcElement == item) {
|
|
|
+ startPosition = index
|
|
|
+ }
|
|
|
+ return item.src
|
|
|
+ })
|
|
|
+
|
|
|
+ showImagePreview({
|
|
|
+ images: imgList,
|
|
|
+ startPosition: startPosition,
|
|
|
+ closeable: true,
|
|
|
+ className: styles.imagesOverlayWrap
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onShowCart(type = 'cart') {
|
|
|
+ this.selectGoodsItem = {
|
|
|
+ price: this.product.pic,
|
|
|
+ stock: this.product.stock,
|
|
|
+ skuStockList: this.skuStockListTemp.length ? this.skuStockListTemp : undefined,
|
|
|
+ brandName: this.product.brandName,
|
|
|
+ productCategoryId: this.product.productCategoryId,
|
|
|
+ name: this.product.name,
|
|
|
+ productSn: this.product.productSn,
|
|
|
+ productSubTitle: this.product.subTitle,
|
|
|
+ id: this.product.id
|
|
|
+ }
|
|
|
+ this.showType = type
|
|
|
+ // 打开购物弹框
|
|
|
+ this.addGoodsShow = true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ render() {
|
|
|
+ const product = this.product
|
|
|
+ const selectSku = this.skuStockList.find((n: any) => n.id === this.radio)
|
|
|
+ return (
|
|
|
+ <div class={styles.goodsDetail}>
|
|
|
+ {browser().isApp && <OHeader border={false} />}
|
|
|
+ <Swipe
|
|
|
+ class={styles.swipe}
|
|
|
+ lazyRender
|
|
|
+ v-slots={{
|
|
|
+ indicator: (item: any) =>
|
|
|
+ item.total > 1 && (
|
|
|
+ <div class={styles['custom-indicator']}>
|
|
|
+ {(item.active || 0) + 1} / {item.total}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {this.albumPics.map((item: string, index: number) => (
|
|
|
+ <SwipeItem>
|
|
|
+ <Image
|
|
|
+ class={styles.swipeItemImg}
|
|
|
+ src={item}
|
|
|
+ onClick={() => this.onPreview(index)}
|
|
|
+ fit="cover"
|
|
|
+ />
|
|
|
+ </SwipeItem>
|
|
|
+ ))}
|
|
|
+ </Swipe>
|
|
|
+
|
|
|
+ <CellGroup border={false} class={[styles.goodsHead, 'mb12']}>
|
|
|
+ <Cell
|
|
|
+ center
|
|
|
+ border={false}
|
|
|
+ v-slots={{
|
|
|
+ title: () => (
|
|
|
+ <div class={styles.priceGroup}>
|
|
|
+ <span class={styles.price}>
|
|
|
+ <i>¥ </i>
|
|
|
+ {moneyFormat(this.groupPrice)}
|
|
|
+ </span>
|
|
|
+ <del class={styles.delPrice}>¥ {moneyFormat(product.originalPrice)}</del>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ // default: () => <div class={styles.stock}>销量4件</div>
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <Cell
|
|
|
+ center
|
|
|
+ border={false}
|
|
|
+ title={product.name}
|
|
|
+ titleClass={[styles.goodsName, 'van-ellipsis']}
|
|
|
+ />
|
|
|
+ {this.goodsInfo.showFree && (
|
|
|
+ <div class={styles.sectionTips}>
|
|
|
+ <Image src={iconGives} class={styles.iconGives} />
|
|
|
+ 赠价值{this.goodsInfo.originalPrice}元乐器维保服务一年
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </CellGroup>
|
|
|
+
|
|
|
+ {this.detailMobileHtml && (
|
|
|
+ <div class={[styles.section]}>
|
|
|
+ <div class={styles.detail}>
|
|
|
+ <span>图文详情</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class={[styles.photoDetail, 'msgWrap']}
|
|
|
+ onClick={this.onShowImg}
|
|
|
+ v-html={this.detailMobileHtml}
|
|
|
+ ></div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|