123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- import request from '@/helpers/request'
- import { moneyFormat } from '@/helpers/utils'
- import {
- Swipe,
- SwipeItem,
- Image,
- CellGroup,
- Cell,
- ImagePreview,
- RadioGroup,
- Radio,
- Tag,
- Row,
- Col,
- Sticky,
- ActionBar,
- ActionBarButton,
- ActionBarIcon,
- Icon,
- Badge,
- Toast,
- Popup,
- SubmitBar
- } from 'vant'
- import { defineComponent } from 'vue'
- import styles from './index.module.less'
- import iconShopCart from '../images/icon-shop-cart.png'
- import AddGoodsCart from '../modal/add-goods-cart'
- export default defineComponent({
- name: 'goods-detail',
- data() {
- const query = this.$route.query
- return {
- id: query.id,
- albumPics: [] as any[],
- product: {} as any,
- radio: 0,
- skuStockListTemp: [],
- detailMobileHtml: '',
- loading: false,
- addGoodsShow: false,
- selectGoodsItem: {},
- cartCount: 0,
- showType: 'cart'
- }
- },
- 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)
- let str = ''
- spData.forEach((sp: any) => {
- str += `${sp.value}`
- })
- item.spDataJson = str
- } else {
- item.spDataJson = '默认'
- }
- })
- return skuStockList
- },
- getPrice() {
- let 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-mall-portal/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) {
- let len = this.skuStockListTemp.length
- for (let i = 0; i < len; i++) {
- let item = this.skuStockListTemp[i] as any
- if (item.stock >= 0) {
- this.radio = item.id
- break
- }
- }
- }
- this.detailMobileHtml = result.product.detailMobileHtml
- } catch {}
- this.getCartCount()
- },
- methods: {
- 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
- })
- },
- 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
- },
- onBuy() {
- // 购买
- if (!this.radio) {
- return Toast('请选择规格')
- }
- console.log(true)
- },
- async getCartCount() {
- try {
- let { code, data } = await request.get('/api-mall-portal/cart/list')
- if (code === 200) {
- this.cartCount = data.length
- }
- } catch (err) {}
- }
- },
- render() {
- const product = this.product
- 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}
- title={product.name}
- titleClass={[styles.goodsName, 'van-ellipsis']}
- />
- <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>
- )
- // default: () => <div class={styles.stock}>销量4件</div>
- }}
- />
- </CellGroup>
- <Row class={[styles.row, 'mb12']}>
- <Col span={4} class={styles.col}>
- 规格
- </Col>
- <Col span={20}>
- <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>
- )}
- {!this.loading && (
- <>
- {/* <ActionBar class={styles.actionBar}>
- <ActionBarIcon
- icon="cart-o"
- // text="购物车"
- onClick={() => {
- this.$router.push('/cart')
- }}
- v-slots={{
- icon: () => (
- <Badge content={this.cartCount} showZero={false}>
- <Icon name={iconShopCart} size={30} />
- </Badge>
- )
- }}
- />
- <div class={styles.buyGroup}>
- <ActionBarButton
- type="primary"
- class={styles.addCertBtn}
- text="加入购物车"
- onClick={() => this.onShowCart()}
- />
- <ActionBarButton
- type="primary"
- text="立即购买"
- onClick={() => this.onShowCart('cartConfirm')}
- />
- </div>
- </ActionBar> */}
- <SubmitBar
- class={styles.actionBar}
- safe-area-inset-bottom
- v-slots={{
- button: () => (
- <div class={styles.buyGroup}>
- <ActionBarButton
- type="primary"
- class={styles.addCertBtn}
- text="加入购物车"
- onClick={() => this.onShowCart()}
- />
- <ActionBarButton
- type="primary"
- text="立即购买"
- onClick={() => this.onShowCart('cartConfirm')}
- />
- </div>
- )
- }}
- >
- <Badge
- content={this.cartCount}
- showZero={false}
- onClick={() => {
- this.$router.push('/cart')
- }}
- >
- <Icon name={iconShopCart} size={30} />
- </Badge>
- </SubmitBar>
- </>
- )}
- <Popup
- show={this.addGoodsShow}
- closeable
- position="bottom"
- round
- onClose={() => {
- this.addGoodsShow = false
- }}
- >
- <AddGoodsCart
- onGetCartCount={() => this.getCartCount()}
- item={this.selectGoodsItem}
- defaultRadio={this.radio}
- showType={this.showType}
- />
- </Popup>
- </div>
- )
- }
- })
|