diff --git a/src/subpackage/mall/components/appraise_item.vue b/src/subpackage/mall/components/appraise_item.vue new file mode 100644 index 0000000..aefc6e0 --- /dev/null +++ b/src/subpackage/mall/components/appraise_item.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/src/subpackage/mall/components/bottom_modal.vue b/src/subpackage/mall/components/bottom_modal.vue index 0bf5c64..fc7b550 100644 --- a/src/subpackage/mall/components/bottom_modal.vue +++ b/src/subpackage/mall/components/bottom_modal.vue @@ -1,10 +1,10 @@ @@ -54,6 +54,12 @@ export default { lineButton, numberOperate }, + props: { + buttonTxt: { + type: String, + default: '确定' + } + }, computed: { goodsSpecArr(){ let { initData } = this; @@ -109,6 +115,10 @@ export default { * @param {Number} specArr[].id 规格id * @param {String} specArr[].name 规格名称 * @param {Array} specArr[].value 规格值 + * @param {Boolean} onlyGet 是否只获取选择数据 + * @param {Function} success 回调函数 +} +} */ }, @@ -131,12 +141,21 @@ export default { }, methods: { // 加入购物车 - addCartBtn: debounce(async function() { + buttonClick: debounce(async function() { let { goodsNum, initData, goodsSpecSelInfo, specSelectedArr, isCompleteSpecSelected } = this; if(!isCompleteSpecSelected)return showNone('请选择规格!'); if(goodsNum == 0)return showNone('请选择购买数量!'); if(goodsSpecSelInfo === null)return showNone('库存加载失败,稍后重试!'); if(goodsSpecSelInfo?.nums < goodsNum)return showNone('库存不足!'); + if(initData?.onlyGet){ + let _selectInfo = { + nums: goodsNum, + spec_arr: specSelectedArr.map(item => item.val) + } + initData?.success?.(_selectInfo); + this.$emit('click:confirm') + return + } await this.goodsCartAdd({ brand_id: initData?.brand_id || '', id: initData?.id || '', @@ -205,7 +224,7 @@ export default { if(_data.code === 0){ console.log('subpackage mall components specification goodsCartAdd res --->', _data); showNone('加入购物车成功~'); - return _data?.data; + return _data?.data ?? true; }else{ return Promise.reject(_data); } diff --git a/src/subpackage/mall/js/api.js b/src/subpackage/mall/js/api.js index 5de9aca..6ed1d8d 100644 --- a/src/subpackage/mall/js/api.js +++ b/src/subpackage/mall/js/api.js @@ -5,6 +5,9 @@ export const MALL_API = { goodsCartAdd:`${ORIGIN}/shop2/goodsCartAdd`, //购物车 - 添加商品 goodsSpecSel:`${ORIGIN}/shop2/goodsSpecSel`, //商品规格选择【返回库存&价格】 goodsInfo:`${ORIGIN}/shop2/goodsInfo`, //商品详情 + homeGoodsBuy:`${ORIGIN}/shop2/homeGoodsBuy`, //商品详情 - 立即购买 + goodsCartList:`${ORIGIN}/shop2/goodsCartList`, //购物车 - 商品列表 + goodsComment:`${ORIGIN}/shop2/goodsComment`, //商品评价列表 } export default { ORIGIN, MALL_API }; \ No newline at end of file diff --git a/src/subpackage/mall/pages/goods_info.vue b/src/subpackage/mall/pages/goods_info.vue index 8c4bd58..faed8cb 100644 --- a/src/subpackage/mall/pages/goods_info.vue +++ b/src/subpackage/mall/pages/goods_info.vue @@ -3,7 +3,7 @@ - + @@ -47,14 +47,14 @@ - + 配送 {{ getDeliveryTxt }} - + 说明 @@ -64,17 +64,37 @@ - + 已选 - - - 配送/自提 - + {{ selectedSpecificationText }} + + + + 评价({{ appraiseList.length || 0 }}) + + 查看全部 + + + + + + + + + + @@ -94,17 +114,19 @@ 购物车 - 99 + {{ goodsCartNum }} - 加入购物车 - 立即购买 + 加入购物车 + 立即购买 - - + + + + @@ -112,17 +134,24 @@ import { routeTo, showLoad, hideLoad, showModal, tsRoute, jsonStr, jsonPar } from "@/utils/util.js"; import serviceModal from "./modules/goods_info/service_modal.vue"; import deliveryModal from "./modules/goods_info/delivery_modal.vue"; +import specificationModal from "../components/specification_modal.vue"; +import appraiseItem from "../components/appraise_item.vue"; import { MALL_API } from "../js/api"; import server from "../js/server"; export default { components: { serviceModal, deliveryModal, + specificationModal, + appraiseItem, }, data(){ return { - goodsInfo: {}, - curBannerIdx: 0, + goodsInfo: {}, // 商品详情数据 + curBannerIdx: 0, // 当前banner索引 + selectedSpecificationInfo: {}, // 已选规格信息 + goodsCartNum: 0, // 购物车数量 + appraiseList: [], // 评价列表 } }, computed: { @@ -180,15 +209,137 @@ export default { if(isNaN(_num))return 0; let _rNum = Math.round(_num) return _rNum > 5 ? 5 : _rNum; + }, + selectedSpecificationText(){ + let { selectedSpecificationInfo } = this; + if(selectedSpecificationInfo?.spec_arr?.length)return selectedSpecificationInfo?.spec_arr?.join(';'); + return '' } }, onLoad(options){ + let _bid = options?.brand_id ?? ''; this.getGoodsInfo({ - brand_id: options?.brand_id ?? '', + brand_id: _bid, id: options?.id ?? '' - }) + }); + this.goodsCartList({ brand_id: _bid }); + this.goodsComment({ + brand_id: _bid, + proid: options?.id ?? '' + }); }, methods: { + specificationLineClick(){ + let { goodsInfo, getQueryForSpecificationModal } = this; + let _sModalRef = this.$refs.specificationModal; + _sModalRef.alert({ + ...getQueryForSpecificationModal(goodsInfo), + onlyGet: true, + success: async res => { + this.selectedSpecificationInfo = res; + _sModalRef.hide(); + } + }); + }, + // 加入购物车 + addShoppingCart(){ + let { goodsInfo, getQueryForSpecificationModal } = this; + let _sModalRef = this.$refs.specificationModal; + // 无规格 + if(goodsInfo?.product_spec_multi === 0)return this.addShoppingCartOperate({ + brand_id: goodsInfo?.brand_id, + id: goodsInfo?.id, + }); + // 规格弹窗 + _sModalRef.alert({ + ...getQueryForSpecificationModal(goodsInfo), + onlyGet: true, + success: async res => { + this.selectedSpecificationInfo = res; + this.addShoppingCartOperate({ + brand_id: goodsInfo?.brand_id ?? '', + id: goodsInfo?.id ?? '', + nums: res?.nums ?? '', + spec_arr: res?.spec_arr ?? [] + }) + } + }); + }, + async addShoppingCartOperate({ brand_id, id, nums = 1, spec_arr = [] }){ + let _sModalRef = this.$refs.specificationModal; + let _cartAddRes = await _sModalRef.goodsCartAdd({ brand_id, id, nums, spec_arr }); + if(_cartAddRes){ + _sModalRef.hide(); + this.goodsCartList({ brand_id }); + } + }, + // 立即购买 + buyImmediately(){ + let { goodsInfo, getQueryForSpecificationModal } = this; + let _sModalRef = this.$refs.specificationModal; + // 无规格 + if(goodsInfo?.product_spec_multi === 0)return this.buyOperate({ + brand_id: goodsInfo?.brand_id, + id: goodsInfo?.id, + }); + // 规格弹窗 + _sModalRef.alert({ + ...getQueryForSpecificationModal(goodsInfo), + onlyGet: true, + success: async res => { + this.selectedSpecificationInfo = res; + this.buyOperate({ + brand_id: goodsInfo?.brand_id ?? '', + id: goodsInfo?.id ?? '', + nums: res?.nums ?? '', + spec_arr: res?.spec_arr ?? [] + }); + } + }); + }, + async buyOperate({ brand_id, id, nums = 1, spec_arr = [] }){ + let hgbRes = await this.homeGoodsBuy({ brand_id, id, nums, spec_arr }); + console.log('hgbRes = ', hgbRes); + // 预购买成功 + if(hgbRes?.total&&hgbRes?.list.length){ + let _amount = hgbRes.list.reduce((total, item, idx)=>{ + let _unitPrice = 0; + if(item?.product_spec_multi === 0)_unitPrice = item?.product_spec_single_info?.price ?? 0; + if(item?.product_spec_multi === 1)_unitPrice = item?.product_spec_multi_info?.price ?? 0; + let _price = (item?.product_nums ?? 0) * _unitPrice; + return total + _price; + }, 0); + let _query = { + goodsList: hgbRes?.list, + product_ids: [ id ], + go_buy: 1, + price_amount: _amount + } + console.log(_query); + }else{ + showModal({content: '购买操作失败,请稍后重试!'}); + console.warn('homeGoodsBuy res =>', hgbRes); + } + }, + getQueryForSpecificationModal(goodsInfo){ + return { + id: goodsInfo?.id ?? '', + brand_id: goodsInfo?.brand_id ?? '', + poster: goodsInfo?.product_imgs?.[0] ?? '', + name: goodsInfo?.product_name ?? '', + price: goodsInfo?.product_price ?? '', + specArr: goodsInfo?.product_spec_multi_info?.spec_data ?? [], + } + }, + // 显示服务说明 + explainLineClick(){ + this.$refs?.serviceModal?.show?.(); + }, + // 显示配送说明 + deliveryLineClick(){ + this.$refs?.deliveryModal?.show?.(); + }, + // 获取商品详情信息 getGoodsInfo({ brand_id, id }){ showLoad(); return server.post({ @@ -215,6 +366,82 @@ export default { console.warn('subpackage mall pages goods_info getGoodsInfo err --->', err); }) }, + // 立即购买 + homeGoodsBuy({ brand_id, id, nums, spec_arr }){ + showLoad(); + return server.post({ + url: MALL_API.homeGoodsBuy, + data: { brand_id, id, nums, spec_arr }, + isDefaultGet: false, + }) + .then(res => { + hideLoad(); + let _data = res?.data || {}; + if(_data.code === 0){ + console.log('subpackage mall pages goods_info homeGoodsBuy res --->', _data); + return _data?.data; + }else{ + return Promise.reject(_data); + } + }) + .catch(err => { + hideLoad(); + showModal({ + title: '提示', + content: err.message || '操作失败!' + }) + console.warn('subpackage mall pages goods_info homeGoodsBuy err --->', err); + }) + }, + // 购物车商品列表 + goodsCartList({ brand_id }){ + return server.post({ + url: MALL_API.goodsCartList, + data: { brand_id }, + isDefaultGet: false, + }) + .then(res => { + let _data = res?.data || {}; + if(_data.code === 0){ + console.log('subpackage mall pages goods_info goodsCartList res --->', _data); + let _ls = _data?.data ?? []; + //product_invalid 商品状态 0-正常 1-已失效 + let validLs = _ls.filter(item => item.product_invalid === 0); + let _length = validLs?.length ?? 0; + this.goodsCartNum = _length > 100 ? 99 : _length; + return _ls; + }else{ + return Promise.reject(_data); + } + }) + .catch(err => { + console.warn('subpackage mall pages goods_info goodsCartList err --->', err); + }) + }, + /** + * 获取商品评价列表 + * @param {Number} proid 商品id + * */ + goodsComment({ brand_id, proid }){ + return server.post({ + url: MALL_API.goodsComment, + data: { brand_id, proid }, + isDefaultGet: false, + }) + .then(res => { + let _data = res?.data || {}; + if(_data.code === 0){ + console.log('subpackage mall pages goods_info goodsComment res --->', _data); + let _ls = _data?.data?.list ?? []; + return this.appraiseList = _ls; + }else{ + return Promise.reject(_data); + } + }) + .catch(err => { + console.warn('subpackage mall pages goods_info goodsComment err --->', err); + }) + }, } } @@ -382,6 +609,30 @@ export default { } } } + + .gi-appraise-info{ + margin-top: 20rpx; + padding: 40upx 0upx; + background: #fff; + .gai-title-bar{ + padding: 0 28upx; + @include ctf(space-between); + .gtb-tit{ + @include flcw(28upx, 40upx, #333); + @include tHide; + } + .gtb-link{ + flex-shrink: 0; + @include flcw(24upx, 34upx, $mColor); + .gl-icon{ + vertical-align: middle; + width: 28upx; + height: 28upx; + } + } + } + } + .gi-detail{ margin-top: 20rpx; background-color: #fff; @@ -462,6 +713,7 @@ export default { border-radius: 36rpx; background-color: #e60213; @include flcw(22rpx, 36rpx, #fff); + @include tHide; } } } diff --git a/src/subpackage/mall/pages/index.vue b/src/subpackage/mall/pages/index.vue index 6fb1ddb..3446f71 100644 --- a/src/subpackage/mall/pages/index.vue +++ b/src/subpackage/mall/pages/index.vue @@ -55,7 +55,8 @@ :poster="(e.product_imgs&&e.product_imgs[0]) || ''" :name="e.product_name" :price="e.product_price" - :id="e.id" + :product-id="e.id" + :brand-id="brand_id" :is-del-price="e.product_spec_multi === 0&&e.product_price_show != 0" :del-price="e.product_price_show || 0" @click:add="goodsItemAddBtn(e)" @@ -65,9 +66,7 @@ - + diff --git a/src/subpackage/mall/pages/modules/goods_info/delivery_modal.vue b/src/subpackage/mall/pages/modules/goods_info/delivery_modal.vue index 20c8c20..9bc8f9c 100644 --- a/src/subpackage/mall/pages/modules/goods_info/delivery_modal.vue +++ b/src/subpackage/mall/pages/modules/goods_info/delivery_modal.vue @@ -1,9 +1,7 @@ @@ -22,7 +20,8 @@ export default { explainArr(){ let { explianStr } = this; if(!explianStr)return []; - + let _eArr = explianStr.split(/[(\r\n)\r\n]+/); + return _eArr.filter(item => !!item); } }, data() { diff --git a/src/subpackage/mall/pages/modules/goods_info/service_modal.vue b/src/subpackage/mall/pages/modules/goods_info/service_modal.vue index 3b7514e..140f5b2 100644 --- a/src/subpackage/mall/pages/modules/goods_info/service_modal.vue +++ b/src/subpackage/mall/pages/modules/goods_info/service_modal.vue @@ -1,12 +1,12 @@