123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- import request from '@/helpers/request'
- import { browser, moneyFormat } from '@/helpers/utils'
- import {
- Swipe,
- SwipeItem,
- Image,
- CellGroup,
- Cell,
- ImagePreview,
- RadioGroup,
- Radio,
- Tag,
- Row,
- Col,
- Badge,
- Button,
- Dialog
- } from 'vant'
- import { defineComponent } from 'vue'
- import styles from './index.module.less'
- import ColSticky from '@/components/col-sticky'
- import { shareCall } from '../share'
- import { state } from '@/state'
- import qs from 'query-string'
- export default defineComponent({
- name: 'goods-detail',
- data() {
- const query = this.$route.query
- return {
- id: query.id,
- albumPics: [] as any[],
- product: {} as Record<string | number | symbol, any>,
- radio: 0,
- skuStockList: [] as any[],
- detailMobileHtml: '',
- loading: false
- }
- },
- computed: {
- getPrice() {
- let item = this.skuStockList.filter(n => n.id == this.radio) as any
- if (item && Array.isArray(item) && item.length) {
- return item[0].price
- }
- const price = this.product.price as any
- return price
- }
- },
- mounted() {
- this.getProduct()
- if (browser().isApp) {
- if (state.platformType === 'STUDENT') {
- const { query } = this.$route as any
- const params = Object.assign(
- {
- id: query.bizId,
- promoterId: query.userId
- },
- query
- )
- // 自动跳转到学生端商品详情
- // window.location.replace(
- // `${location.origin}/student/#/goodsDetail?${qs.stringify(params)}`
- // )
- this.locationReplace(
- `${location.origin}/student/#/goodsDetail?${qs.stringify(params)}`
- )
- } else if (state.platformType === 'TEACHER') {
- Dialog.alert({
- title: '提示',
- message: '请使用酷乐秀学生端扫码打开'
- }).then(() => {
- postMessage({ api: 'back' })
- })
- }
- } else {
- const { origin } = location
- const query = this.$route.query
- let str =
- origin +
- `/student/#/goodsDetail?id=${query.bizId}&promoterId=${query.userId}`
- shareCall(str, {})
- }
- },
- methods: {
- locationReplace(url: string) {
- // alert(url)
- if (history.replaceState) {
- history.replaceState(null, document.title, url)
- window.location.reload()
- } else {
- location.replace(url)
- }
- },
- async getProduct() {
- this.loading = true
- let product = {} as any
- let skuStockList = []
- // 获取产品信息
- try {
- const result = await request.post(
- `/api-mall-portal/open/productProfit`,
- {
- data: {
- bizId: this.$route.query.bizId,
- userId: this.$route.query.userId
- }
- }
- )
- if (result.data && result.data.productDetail) {
- product = result.data.productDetail.product
- skuStockList = result.data.productDetail.skuStockList || []
- }
- } catch {}
- this.product = product
- this.skuStockList = skuStockList.map((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 item
- })
- this.albumPics = [product.pic]
- .concat(product.albumPics.split(','))
- .filter(n => n)
- this.detailMobileHtml = product.detailMobileHtml
- this.loading = false
- },
- onPreview(index: number) {
- // 图片预览
- ImagePreview({
- images: this.albumPics,
- startPosition: index,
- closeable: true
- })
- },
- onShowImg(target: any) {
- const { localName } = target.srcElement
- if (localName !== 'img') {
- return
- }
- let startPosition = 0
- const domList = document.querySelectorAll('.msgWrap img')
- let imgList = Array.from(domList).map((item: any, index: number) => {
- if (target.srcElement == item) {
- startPosition = index
- }
- return item.src
- })
- ImagePreview({
- images: imgList,
- startPosition: startPosition,
- closeable: true
- })
- },
- //打开APP
- onDetail() {
- const { origin } = location
- const query = this.$route.query
- let str =
- origin +
- `/student/#/goodsDetail?id=${query.bizId}&promoterId=${query.userId}`
- shareCall(str, {})
- setTimeout(() => {
- location.href = origin + '/student/#/download'
- }, 3000)
- }
- },
- 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.getPrice)}
- </span>
- {/* <del class={styles.delPrice}>
- ¥{moneyFormat(product.originalPrice)}
- </del> */}
- </div>
- )
- }}
- />
- <Cell
- center
- border={false}
- title={product.name}
- titleClass={[styles.goodsName, 'van-ellipsis']}
- />
- </CellGroup>
- <Row class={[styles.row, 'mb12']}>
- <Col span={4} class={styles.col}>
- 规格
- </Col>
- <Col span={20}>
- {selectSku ? (
- <div class={styles.selectWrap}>
- {selectSku.stock <= 0
- ? `当前款式暂时缺货`
- : `已选择 ${selectSku.spDataJson}`}
- </div>
- ) : (
- <div class={styles.selectWrap}>请选择 规格</div>
- )}
- <RadioGroup
- class={styles['radio-group']}
- modelValue={this.radio}
- onUpdate:modelValue={val => (this.radio = val)}
- >
- {this.skuStockList.map((item: any) => {
- const isActive = item.id === this.radio
- const type = isActive ? 'primary' : 'default'
- return (
- <Badge
- position="top-right"
- content={item.stock <= 0 ? '缺货' : ''}
- color={'#999999'}
- class={styles.badge}
- offset={[-20, 0]}
- >
- <Radio
- class={styles.radio}
- name={item.id}
- disabled={item.stock <= 0}
- onClick={() => {
- // 判断是否有库存
- if (item.stock <= 0) {
- return
- }
- this.radio = item.id
- }}
- >
- <Tag size="large" plain={isActive} type={type}>
- {item.spDataJson}
- </Tag>
- </Radio>
- </Badge>
- )
- })}
- </RadioGroup>
- </Col>
- </Row>
- {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>
- )}
- <ColSticky position="bottom">
- <div class={['btnGroup']} style={{ paddingTop: '12px' }}>
- <Button block round type="primary" onClick={this.onDetail}>
- 下载酷乐秀购买商品
- </Button>
- </div>
- </ColSticky>
- </div>
- )
- }
- })
|