版本研发

- 打开小程序用户授权微信信息
- 对接后台接口:单商品选购下单支付的过程,完成部分
This commit is contained in:
donqi 2022-05-11 16:09:53 +08:00
parent fa22cdf2b3
commit 4a51a530a5
13 changed files with 393 additions and 111 deletions

View File

@ -3,9 +3,6 @@
export default { export default {
data() { data() {
return { return {
modalContent: '',
cancelMsg: '取消',
confirmMsg: '确定'
} }
}, },
onLaunch: function() { onLaunch: function() {

View File

@ -227,9 +227,13 @@ const productDetail = {
type: 'image', type: 'image',
url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big3002.jpg' url: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big3002.jpg'
}], }],
productInfo: { productInfo: {
name: '十五平米擦玻璃服务', id: 1,
desc: '15平米起擦玻璃服务超过15平米按照15/平米现场另收费', goodsImgUrl: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big20000.jpg',
goodsName: '十五平米擦玻璃服务',
comments: '15平米起擦玻璃服务超过15平米按照15/平米现场另收费',
type: '空调/清洗',
servArea: ['广州', '顺德', '南海', '大良', '南海', '大良', '南海', '大良', '南海'],
isGoldServ: true isGoldServ: true
}, },
guaranteeList: [{ guaranteeList: [{
@ -368,7 +372,7 @@ const productDetail = {
}], }],
shopInfo: { shopInfo: {
id: 1, id: 1,
name: '艺鑫到家(售后无忧)', shopName: '艺鑫到家(售后无忧)',
avatarUrl: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big17005.jpg', avatarUrl: 'https://ossweb-img.qq.com/images/lol/web201310/skin/big17005.jpg',
totalScore: 4.5 totalScore: 4.5
} }

5
common/js/globalData.js Normal file
View File

@ -0,0 +1,5 @@
export default {
deptId: 1,
initPageNum: 1,
initPageSize: 5
}

View File

@ -1,3 +1,5 @@
import globalData from '@/common/js/globalData.js';
export default { export default {
// 异步接口拦截 // 异步接口拦截
addInterceptor() { addInterceptor() {
@ -8,21 +10,115 @@ export default {
// console.log("停止触发"); // console.log("停止触发");
// return false; // return false;
}, },
success(args) { // success(args) {
console.log('interceptor-success', args); // console.log('interceptor-success', args);
}, // },
fail(err) { // fail(err) {
console.log('interceptor-fail', err) // console.log('interceptor-fail', err)
}, // },
complete(res) { // complete(res) {
console.log('interceptor-complete', res) // console.log('interceptor-complete', res)
// res = res.data;
// }
})
},
checkAndAuth() {
let _this = this;
// 通过 wx.getSetting 先查询一下用户是否授权了 "scope.userInfo" 这个 scope
wx.getSetting({
success(res) {
if (!res.authSetting['scope.userInfo']) {
// 用户授权
wx.authorize({
scope: 'scope.userInfo',
success() {
// 用户已经同意, 后续调用此接口不会弹窗询问
_this.login();
},
fail() {
// 用户已经拒绝过授权
wx.openSetting({
success(res) {
if (res['scope.userInfo']) {
_this.checkAndAuth();
}
}
})
}
})
} else {
_this.login();
}
} }
}) })
},
async login() {
// 从缓存中获取登录信息
let userInfo = uni.getStorageSync('userProfile');
if (userInfo) {
return true;
}
// 获取微信登录凭证
const wxLoginCode = wx.login();
// TODO:调用小程序服务端确认是否是授权登录过的用户
let loginRes = {
logined: false,
userInfo: {}
};
// 未登录过的获取微信用户信息
if (!loginRes || !loginRes.logined) {
userInfo = await wx.getUserProfile({
desc: '用于小程序登录'
});
// 再次请求小程序服务端存储用户,服务端添加附加用户信息后返回
loginRes = {
logined: true,
userInfo: {
userId: 1
}
};
}
userInfo = loginRes.userInfo;
if (!userInfo) {
uni.showToast({
icon: 'error',
title: '用户信息获取失败,请退出小程序重试'
})
return false;
}
// 页面存储用户登录有效信息,以便其他页面调用
uni.setStorageSync('userProfile', userInfo);
return true;
},
getCurUserInfo() {
let userProfile = uni.getStorageSync('userProfile');
console.log("curUser:" + userProfile)
return userProfile;
}, },
getProductCategories() { getProductCategories(params = {}) {
return uni.request({ return uni.request({
url: '/goods/category/list', url: '/goods/deptcategory/app/list',
method: 'POST' method: 'POST',
data: params
}) })
},
qryProductPage(params = {}) {
return uni.request({
url: '/goods/goods/list',
method: 'POST',
data: params,
header: {
pageNum: params.pageNum,
pageSize: params.pageSize
}
})
},
placeOrder(params = {}) {
return uni.request({
url: '/goods/goods/list',
method: 'POST',
data: params
})
} }
} }

View File

@ -1,16 +1,16 @@
<template> <template>
<view class="flex justify-start"> <view class="flex justify-start">
<view class="cu-avatar xxl-view" :style="'background-image:url(' + product.picUrl + ');'"> <view class="cu-avatar xxl-view" :style="'background-image:url(' + product.goodsImgUrl + ');'">
</view> </view>
<view class="margin-left-sm product-content"> <view class="margin-left-sm product-content">
<view> <view>
<view class="text-black">{{product.name}}</view> <view class="text-black">{{product.goodsName}}</view>
<view class="text-sm" v-if="ifShowComments">{{product.comments}}</view> <view class="text-sm" v-if="ifShowComments">{{product.comments}}</view>
</view> </view>
<view class="flex justify-between align-center"> <view class="flex justify-between align-center">
<view class="flex justify-start align-center"> <view class="flex justify-start align-center">
<text class="text-price text-red text-bold text-xl">{{product.salePrice}}</text> <text class="text-price text-red text-bold text-xl">{{product.discountsPrice}}</text>
<text class="text-del">¥{{product.price}}</text> <text class="text-del" v-if="product.goodsPrice">¥{{product.goodsPrice}}</text>
</view> </view>
<view class="padding-xs"> <view class="padding-xs">
<view class='cu-tag light bg-blue'>{{product.type}}</view> <view class='cu-tag light bg-blue'>{{product.type}}</view>

View File

@ -10,25 +10,25 @@
</view> </view>
<view class="VerticalBox" :style="'height:calc(' + containerHeight + ' - 100rpx)'"> <view class="VerticalBox" :style="'height:calc(' + containerHeight + ' - 100rpx)'">
<scroll-view class="VerticalNav nav" scroll-y scroll-with-animation :scroll-top="verticalNavTop"> <scroll-view class="VerticalNav nav" scroll-y scroll-with-animation :scroll-top="verticalNavTop">
<view class="cu-item" :class="item.id==tabCur?'text-main-color cur':''" v-for="(item,index) in list" <view class="cu-item" :class="item.goodsCategoryId==tabCur?'text-main-color cur':''" v-for="(item,index) in list"
:key="index" @tap="tabSelect" :data-index="index" :data-id="item.id" :key="index" @tap="tabSelect" :data-index="index" :data-id="item.goodsCategoryId"
:data-main-cur="item.children && item.children.length > 0 ? item.children[0].id : -1"> :data-main-cur="item.child && item.child.length > 0 ? item.child[0].goodsCategoryId : -1">
{{item.name}} {{item.goodsCategoryName}}
</view> </view>
</scroll-view> </scroll-view>
<scroll-view class="VerticalMain" scroll-y scroll-with-animation :scroll-into-view="'main-'+mainCur" <scroll-view class="VerticalMain" scroll-y scroll-with-animation :scroll-into-view="'main-'+mainCur"
@scroll="verticalMain"> @scroll="verticalMain">
<view class="padding-top padding-lr" v-for="(type, index1) in childrenList" :key="index1" <view class="padding-top padding-lr" v-for="(type, index1) in childrenList" :key="index1"
:id="'main-'+type.id"> :id="'main-'+type.goodsCategoryId">
<view class="cu-bar bg-white bottom-border"> <view class="cu-bar bg-white bottom-border">
<view class="action"> <view class="action">
<text class="cuIcon-title text-main-color"></text>{{type.name}} <text class="cuIcon-title text-main-color"></text>{{type.goodsCategoryName}}
</view> </view>
</view> </view>
<view class="cu-list menu"> <view class="cu-list menu">
<view class="cu-item" :class="curNavItem.id === subType.id ? 'bg-main-color light' : ''" v-for="(subType,index2) in type.children" :key="index2" @click="chooseNavItem(subType)"> <view class="cu-item" :class="curNavItem.goodsCategoryId === subType.goodsCategoryId ? 'bg-main-color light' : ''" v-for="(subType,index2) in type.child" :key="index2" @click="chooseNavItem(subType)">
<view class="content"> <view class="content">
<text>{{subType.name}}</text> <text>{{subType.goodsCategoryName}}</text>
</view> </view>
</view> </view>
</view> </view>
@ -57,8 +57,7 @@
}, },
data() { data() {
return { return {
// list: [], // list: [],
childrenList: [], childrenList: [],
tabCur: 0, tabCur: 0,
mainCur: 0, mainCur: 0,
@ -74,16 +73,15 @@
// this.loadData(); // this.loadData();
// }, // },
methods: { methods: {
async loadData() { loadData() {
// this.list = await this.$api.data('categoryList'); // this.list = await this.$api.data('categoryList');
this.tabCur = this.list[0].goodsCategoryId;
this.tabCur = this.list[0].id;
for (let i = 0; i < this.list.length; i++) { for (let i = 0; i < this.list.length; i++) {
let children = this.list[i].children; let children = this.list[i].child;
if (children && children.length > 0) { if (children && children.length > 0) {
for (let j = 0; j < children.length; j++) { for (let j = 0; j < children.length; j++) {
children[j].pIndex = i; children[j].pIndex = i;
children[j].pId = this.list[i].id; // children[j].pId = this.list[i].id;
} }
this.childrenList = this.childrenList.concat(children); this.childrenList = this.childrenList.concat(children);
} }
@ -102,7 +100,7 @@
let tabHeight = 0; let tabHeight = 0;
if (this.load) { if (this.load) {
for (let i = 0; i < this.childrenList.length; i++) { for (let i = 0; i < this.childrenList.length; i++) {
let view = uni.createSelectorQuery().select("#main-" + this.childrenList[i].id); let view = uni.createSelectorQuery().select("#main-" + this.childrenList[i].goodsCategoryId);
view.fields({ view.fields({
size: true size: true
}, data => { }, data => {
@ -117,7 +115,7 @@
for (let i = 0; i < this.childrenList.length; i++) { for (let i = 0; i < this.childrenList.length; i++) {
if (scrollTop > this.childrenList[i].top && scrollTop < this.childrenList[i].bottom) { if (scrollTop > this.childrenList[i].top && scrollTop < this.childrenList[i].bottom) {
this.verticalNavTop = (this.childrenList[i].pIndex - 1) * 50 this.verticalNavTop = (this.childrenList[i].pIndex - 1) * 50
this.tabCur = this.childrenList[i].pId; this.tabCur = this.childrenList[i].parentCategoryId;
console.log(scrollTop + ";tabCur=" + this.tabCur) console.log(scrollTop + ";tabCur=" + this.tabCur)
return false return false
} }

View File

@ -6,7 +6,8 @@ import ConfirmModal from '@/components/modal/confirm-modal.vue';
import Data from './common/js/data.js'; import Data from './common/js/data.js';
import globalFun from './common/js/glogalFun.js'; import globalFun from './common/js/glogalFun.js';
import validate from './common/js/validate.js'; import validate from './common/js/validate.js';
import request from './common/js/request.js'; import request from './common/js/request.js';
import globalData from './common/js/globalData.js';
Vue.component('cu-custom', CuCustom) Vue.component('cu-custom', CuCustom)
Vue.component('confirm-modal', ConfirmModal); Vue.component('confirm-modal', ConfirmModal);
@ -24,7 +25,8 @@ Vue.prototype.$api = {
} }
Vue.prototype.$globalFun = globalFun; Vue.prototype.$globalFun = globalFun;
Vue.prototype.$validate = validate; Vue.prototype.$validate = validate;
Vue.prototype.$request = request; Vue.prototype.$request = request;
Vue.prototype.$globalData = globalData;
Vue.config.productionTip = false Vue.config.productionTip = false

View File

@ -69,6 +69,17 @@
<!-- 热门服务 --> <!-- 热门服务 -->
<vertical-goods-card ref="hotGoodsCard" :goodsInfos="hotGoods.goodsInfos" <vertical-goods-card ref="hotGoodsCard" :goodsInfos="hotGoods.goodsInfos"
:title="hotGoods.title"></vertical-goods-card> :title="hotGoods.title"></vertical-goods-card>
</view>
<!-- 强制要求用户授权登录的弹窗 -->
<view class="cu-modal" :class="isAuthWxLoginModal?'show':''">
<view class="cu-dialog">
<view class="padding-xl">
需先授权微信登录才可正常使用功能
</view>
<view class="cu-bar bg-white">
<view class="action margin-0 flex-sub text-main-color solid-left" @tap="authWxLogin">确认授权</view>
</view>
</view>
</view> </view>
</view> </view>
</template> </template>
@ -90,7 +101,8 @@
subCategories: [], subCategories: [],
hotGoods: {}, hotGoods: {},
discountGoods: {}, discountGoods: {},
InputBottom: 0 InputBottom: 0,
isAuthWxLoginModal: false
} }
}, },
mounted() { mounted() {
@ -103,7 +115,12 @@
this.loadData(); this.loadData();
}, },
methods: { methods: {
async loadData() { async loadData() {
let curUserInfo = uni.getStorageSync('userProfile');
this.isAuthWxLoginModal = curUserInfo ? false : true;
if (this.isAuthWxLoginModal) {
return;
}
this.swiperList = await this.$api.data('swiperList'); this.swiperList = await this.$api.data('swiperList');
this.categories = await this.$api.data('categories'); this.categories = await this.$api.data('categories');
this.subCategories = await this.$api.data('subCategories'); this.subCategories = await this.$api.data('subCategories');
@ -138,6 +155,13 @@
uni.navigateTo({ uni.navigateTo({
url: '/pages/product/product-category' url: '/pages/product/product-category'
}) })
},
authWxLogin() {
this.$request.login().then(res => {
if (res) {
this.loadData();
}
})
} }
} }
} }

View File

@ -6,18 +6,18 @@
<block slot="content">订单确认</block> <block slot="content">订单确认</block>
</cu-custom> </cu-custom>
<!-- 服务地址 --> <!-- 服务地址 -->
<view v-if="defaultAddress" class="bg-white"> <view v-if="formInfo.defaultAddress" class="bg-white">
<view class="padding flex justify-between align-center" @click="showAddress2Choose"> <view class="padding flex justify-between align-center" @click="showAddress2Choose">
<view> <view>
<view class="flex justify-start align-center"> <view class="flex justify-start align-center">
<view class="text-gray margin-right-xs" v-for="(areaObj, index) in defaultAddress.area"> <view class="text-gray margin-right-xs" v-for="(areaObj, index) in formInfo.defaultAddress.area">
{{areaObj.name}} {{areaObj.name}}
</view> </view>
</view> </view>
<view class="text-lg margin-tb-sm">{{defaultAddress.address}}</view> <view class="text-lg margin-tb-sm">{{formInfo.defaultAddress.address}}</view>
<view class="text-gray"> <view class="text-gray">
<text class="margin-right">{{defaultAddress.person2Contact}}</text> <text class="margin-right">{{formInfo.defaultAddress.person2Contact}}</text>
<text>{{defaultAddress.phone}}</text> <text>{{formInfo.defaultAddress.phone}}</text>
</view> </view>
</view> </view>
<view class="text-lg"><text class="text-bold text-gray cuIcon-right"></text></view> <view class="text-lg"><text class="text-bold text-gray cuIcon-right"></text></view>
@ -42,8 +42,8 @@
<view class="margin-lr-sm margin-top-sm bg-white padding"> <view class="margin-lr-sm margin-top-sm bg-white padding">
<view class="flex justify-between align-center"> <view class="flex justify-between align-center">
<text class="text-black">预约时间</text> <text class="text-black">预约时间</text>
<uni-datetime-picker v-model="doorTime" @change="changeDoorTime"> <uni-datetime-picker @change="changeDoorTime">
<view v-if="doorTime" class="text-sm">{{doorTime}}<text class="text-bold cuIcon-right"></text> <view v-if="formInfo.doorTime" class="text-sm">{{formInfo.doorTime}}<text class="text-bold cuIcon-right"></text>
</view> </view>
<view v-else class="text-red text-sm">请选择上门时间<text class="text-bold cuIcon-right"></text></view> <view v-else class="text-red text-sm">请选择上门时间<text class="text-bold cuIcon-right"></text></view>
</uni-datetime-picker> </uni-datetime-picker>
@ -80,11 +80,11 @@
<text class="text-black">支付方式</text> <text class="text-black">支付方式</text>
<radio-group @change="changePayWay"> <radio-group @change="changePayWay">
<label class="radio"> <label class="radio">
<radio class="main-color" value="online" :checked="payWay=='online'" /> <radio class="main-color" value="0" :checked="formInfo.payWay=='0'" />
<text class="margin-left-xs">在线支付</text> <text class="margin-left-xs">在线支付</text>
</label> </label>
<label class="radio margin-left"> <label class="radio margin-left">
<radio class="main-color" value="offline" :checked="payWay=='offline'" /> <radio class="main-color" value="1" :checked="formInfo.payWay=='1'" />
<text class="margin-left-xs">上门到付</text> <text class="margin-left-xs">上门到付</text>
</label> </label>
</radio-group> </radio-group>
@ -93,8 +93,19 @@
<!-- 发票信息 --> <!-- 发票信息 -->
<view class="margin-lr-sm margin-top-sm bg-white padding"> <view class="margin-lr-sm margin-top-sm bg-white padding">
<view class="flex justify-between align-center"> <view class="flex justify-between align-center">
<text class="text-black">发票信息</text> <!-- <text class="text-black">发票信息</text>
<text class="text-sm text-bold cuIcon-right"></text> <text class="text-sm text-bold cuIcon-right"></text> -->
<text class="text-black">是否需要发票</text>
<radio-group @change="changeIsNeedBill">
<label class="radio">
<radio class="main-color" value="0" :checked="formInfo.isNeedBill=='0'" />
<text class="margin-left-xs">不需要</text>
</label>
<label class="radio margin-left">
<radio class="main-color" value="1" :checked="formInfo.isNeedBill=='1'" />
<text class="margin-left-xs">需要</text>
</label>
</radio-group>
</view> </view>
</view> </view>
<!-- 备注留言 --> <!-- 备注留言 -->
@ -113,9 +124,9 @@
<view class="cu-bar bg-white tabbar border shop fixed-bottom-bar"> <view class="cu-bar bg-white tabbar border shop fixed-bottom-bar">
<view class="action text-df left-grid"> <view class="action text-df left-grid">
<text class="margin-left-lg">共计</text> <text class="margin-left-lg">共计</text>
<text class="margin-left-xs text-red text-price text-xl">{{formInfo.totalPrice}}</text> <text class="margin-left-xs text-red text-price text-xl">{{totalPrice}}</text>
</view> </view>
<view class="bg-main-color submit">确定</view> <view class="bg-main-color submit" @click="submit">确定</view>
</view> </view>
</view> </view>
</template> </template>
@ -132,25 +143,35 @@
columnTitleArr: ['购买型号', '购买数量'], columnTitleArr: ['购买型号', '购买数量'],
pickedProductList: [], pickedProductList: [],
formInfo: { formInfo: {
payWay: 'online', payWay: '0',
comments: '', isNeedBill: '0',
totalPrice: 0 comments: '',
}, doorTime: null,
defaultAddress: null, defaultAddress: null
doorTime: null },
totalPrice: 0
} }
}, },
onLoad() { onLoad(options) {
this.loadData(); let params = JSON.parse(decodeURIComponent(options.params));
this.loadData(params);
this.bindEvent(); this.bindEvent();
}, },
onUnload() { onUnload() {
this.offBindEvent(); this.offBindEvent();
}, },
methods: { methods: {
async loadData() { async loadData(params) {
this.pickedProductList = await this.$api.data('pickedProductList'); // this.pickedProductList = await this.$api.data('pickedProductList');
this.defaultAddress = await this.$api.data('defaultAddress'); this.pickedProductList = params.pickedProductList;
// TODO: product
for (let i = 0; i < this.pickedProductList.length; i++) {
for (let j = 0; j < this.pickedProductList[i].product.length; j++) {
this.pickedProductList[i].product[j].discountsPrice = 100;
this.pickedProductList[i].product[j].goodsPrice = 200;
}
}
this.formInfo.defaultAddress = await this.$api.data('defaultAddress');
}, },
bindEvent() { bindEvent() {
uni.$on(this.$globalFun.CHOOSE_ADDRESS, this.chooseAddress); uni.$on(this.$globalFun.CHOOSE_ADDRESS, this.chooseAddress);
@ -160,9 +181,12 @@
}, },
changePayWay(e) { changePayWay(e) {
this.formInfo.payWay = e.detail.value; this.formInfo.payWay = e.detail.value;
},
changeIsNeedBill(e) {
this.formInfo.isNeedBill = e.detail.value;
}, },
inputComments(e) { inputComments(e) {
this.comments = e.detail.value this.formInfo.comments = e.detail.value
}, },
showAddress2Choose() { showAddress2Choose() {
uni.navigateTo({ uni.navigateTo({
@ -170,10 +194,62 @@
}) })
}, },
chooseAddress(addressInfo) { chooseAddress(addressInfo) {
this.defaultAddress = addressInfo; this.formInfo.defaultAddress = addressInfo;
}, },
changeDoorTime(value) { changeDoorTime(value) {
this.doorTime = value; this.formInfo.doorTime = value;
},
parseGoodsList() {
let goodsList = [];
this.pickedProductList.forEach((shopInfo) => {
shopInfo.product.forEach((productInfo) => {
productInfo.pickedList.forEach((pickedSpecs) => {
goodsList.push({
goodsId: pickedSpecs.id,
num: pickedSpecs.pickedNum,
})
})
})
})
return goodsList;
},
validForm() {
if (!this.formInfo.defaultAddress) {
uni.showToast({
title: '请选择服务地址',
icon: 'none'
})
return false;
}
if (!this.formInfo.doorTime) {
uni.showToast({
title: '请选择上门时间',
icon: 'none'
})
return false;
}
return true;
},
async submit() {
let valid = this.validForm();
if (!valid) {
return;
}
let curUserInfo = this.$request.getCurUserInfo();
let params = {
customerId: curUserInfo.userId,
serverTime: this.formInfo.doorTime,
addressId: this.formInfo.defaultAddress.id,
payType: this.formInfo.payWay,
remark: this.formInfo.comments,
isNeedBill: this.formInfo.isNeedBill,
goodsList: this.parseGoodsList()
}
console.log(params);
//
let res = await this.$request.placeOrder(params);
// ,
// wx.requestPayment(res);
} }
}, },
} }

View File

@ -43,11 +43,18 @@
</scroll-view> </scroll-view>
</view> </view>
<!-- 产品列表 --> <!-- 产品列表 -->
<view class="padding bg-white solid-top"> <view class="padding-lr padding-top bg-white solid-top">
<view class="solid-bottom margin-bottom-sm padding-bottom-sm" @click="showDetails(item)" <view class="solid-bottom margin-bottom-sm padding-bottom-sm" @click="showDetails(item)"
v-for="(item, index) in productList"> v-for="(item, index) in productList">
<horizontal-goods-card :ifShowServArea="true" :product="item"></horizontal-goods-card> <horizontal-goods-card :ifShowServArea="true" :product="item"></horizontal-goods-card>
</view> </view>
</view>
<view class="margin-bottom-lg">
<view v-if="hasMoreData" class="text-center bg-main-color light padding-tb-sm" @click="loadData">
<text class="margin-right-xs">查看更多</text>
<text class="text-bold cuIcon-unfold"></text>
</view>
<view class="cu-load" :class="loadMoreStatus"></view>
</view> </view>
</view> </view>
</template> </template>
@ -61,7 +68,11 @@
}, },
data() { data() {
return { return {
productList: [], productList: [],
loadMoreStatus: '',
hasMoreData: false,
pageNum: this.$globalData.initPageNum,
pageSize: this.$globalData.initPageSize,
stickyTop: this.CustomBar, stickyTop: this.CustomBar,
// type: 0=1=order: 0=1= // type: 0=1=order: 0=1=
tabCur: 0, tabCur: 0,
@ -94,13 +105,38 @@
} }
}, },
onLoad(options) { onLoad(options) {
let params = JSON.parse(decodeURIComponent(options.params)); let params = JSON.parse(decodeURIComponent(options.params));
if (typeof params.pageNum === 'number' && typeof params.pageSize === 'number') {
this.pageNum = params.pageNum;
this.pageSize = params.pageSize;
}
this.loadData(params); this.loadData(params);
}, },
methods: { methods: {
async loadData(params) { async loadProductPage(params) {
let shopInfo = await this.$api.data('shopInfo'); // let shopInfo = await this.$api.data('shopInfo');
this.productList = shopInfo.productList; // this.productList = shopInfo.productList;
let res = await this.$request.qryProductPage(params);
let rowsLength = res[1].data.rows.length;
if (rowsLength == 0) {
return;
} else if (rowsLength === this.pageSize) {
this.hasMoreData = true;
}
this.productList = this.productList.concat(res[1].data.rows);
this.pageNum++;
},
async loadData(params) {
params.pageNum = this.pageNum;
params.pageSize = this.pageSize;
this.loadMoreStatus = 'loading bg-main-color light';
this.hasMoreData = false;
try {
await this.loadProductPage(params);
this.loadMoreStatus = this.hasMoreData ? '' : 'over bg-grey';
} catch (e) {
this.loadMoreStatus = 'erro bg-red'
}
}, },
searchGoods(e) { searchGoods(e) {
console.log("搜索" + e.detail.value) console.log("搜索" + e.detail.value)
@ -116,9 +152,12 @@
this.taskConditions[this.tabCur].value = orderVal === 0 ? 1 : 0; this.taskConditions[this.tabCur].value = orderVal === 0 ? 1 : 0;
} }
}, },
showDetails(productItem) { showDetails(productItem) {
let params = {
id: productItem.goodsId
}
uni.navigateTo({ uni.navigateTo({
url: '../product/product-detail?productId=' + productItem.id url: '/pages/product/product-detail?params=' + encodeURIComponent(JSON.stringify(params))
}); });
}, },
regionChange(e) { regionChange(e) {

View File

@ -5,7 +5,7 @@
<block slot="backText">返回</block> <block slot="backText">返回</block>
<block slot="content">产品分类</block> <block slot="content">产品分类</block>
</cu-custom> </cu-custom>
<vertical-nav :containerHeight="containerHeight" :list="categoryList" :isClick2ShowProducts="true"></vertical-nav> <vertical-nav v-if="categoryList" :containerHeight="containerHeight" :list="categoryList" :isClick2ShowProducts="true"></vertical-nav>
</view> </view>
</template> </template>
@ -19,7 +19,7 @@
data() { data() {
return { return {
containerHeight: '100vh - ' + this.CustomBar + 'px', containerHeight: '100vh - ' + this.CustomBar + 'px',
categoryList: [] categoryList: null
} }
}, },
onLoad() { onLoad() {
@ -32,7 +32,8 @@
methods: { methods: {
async loadData() { async loadData() {
// this.categoryList = await this.$api.data('categoryList'); // this.categoryList = await this.$api.data('categoryList');
this.categoryList = await this.$request.getProductCategories(); let res = await this.$request.getProductCategories({deptId: this.$globalData.deptId});
this.categoryList = res[1].data.data;
}, },
bindEvent() { bindEvent() {
uni.$on(this.$globalFun.VERTICAL_NAV_GET_ITEM, this.chooseSubType); uni.$on(this.$globalFun.VERTICAL_NAV_GET_ITEM, this.chooseSubType);
@ -44,7 +45,7 @@
}, },
chooseSubType(item) { chooseSubType(item) {
let params = { let params = {
type: 1 goodsCategoryId: item.goodsCategoryId
} }
uni.navigateTo({ uni.navigateTo({
url: '/pages/product/filtered-products?params=' + encodeURIComponent(JSON.stringify(params)) url: '/pages/product/filtered-products?params=' + encodeURIComponent(JSON.stringify(params))

View File

@ -59,9 +59,9 @@
<view class='cu-tag round bg-orange light' v-if="productInfo.isGoldServ"> <view class='cu-tag round bg-orange light' v-if="productInfo.isGoldServ">
<text class="cuIcon-medal">金牌服务</text> <text class="cuIcon-medal">金牌服务</text>
</view> </view>
{{productInfo.name}} {{productInfo.goodsName}}
</view> </view>
<view class="text-sm text-gray margin-top-xs">{{productInfo.desc}}</view> <view class="text-sm text-gray margin-top-xs">{{productInfo.comments}}</view>
</view> </view>
<view class="text-xl text-right padding-lr"> <view class="text-xl text-right padding-lr">
<!-- <view class="margin-tb-xs"><text class="cuIcon-share"></text></view> --> <!-- <view class="margin-tb-xs"><text class="cuIcon-share"></text></view> -->
@ -110,7 +110,7 @@
<view class="flex justify-start align-center"> <view class="flex justify-start align-center">
<view class="cu-avatar round" :style="'background-image:url(' + shopInfo.avatarUrl + ');'"></view> <view class="cu-avatar round" :style="'background-image:url(' + shopInfo.avatarUrl + ');'"></view>
<view class="content flex-sub margin-lr-sm"> <view class="content flex-sub margin-lr-sm">
<view class="text-black">{{shopInfo.name}}</view> <view class="text-black">{{shopInfo.shopName}}</view>
<uni-rate :size="15" :readonly="true" allow-half :value="shopInfo.totalScore" /> <uni-rate :size="15" :readonly="true" allow-half :value="shopInfo.totalScore" />
</view> </view>
</view> </view>
@ -146,7 +146,7 @@
<uni-popup ref="productPickPopup" type="bottom" @change="changePopupState"> <uni-popup ref="productPickPopup" type="bottom" @change="changePopupState">
<view class="text-bold text-gray text-lg text-center left-top-sm-bar" @click="toggleProductPickModal"><text <view class="text-bold text-gray text-lg text-center left-top-sm-bar" @click="toggleProductPickModal"><text
class="cuIcon-close"></text></view> class="cuIcon-close"></text></view>
<product-pick :specsList="specsList" :orderNow="orderNow"></product-pick> <product-pick :shopInfo="shopInfo" :productInfo="productInfo" :specsList="specsList" :orderNow="orderNow"></product-pick>
</uni-popup> </uni-popup>
</view> </view>
</template> </template>
@ -181,8 +181,9 @@
swiperPicUrls: [] swiperPicUrls: []
} }
}, },
onLoad() { onLoad(options) {
this.loadData(); let params = JSON.parse(decodeURIComponent(options.params));
this.loadData(params);
this.bindEvent(); this.bindEvent();
}, },
onUnload() { onUnload() {
@ -195,7 +196,7 @@
this.showTopNav = e.scrollTop > 250 ? true : false this.showTopNav = e.scrollTop > 250 ? true : false
}, },
methods: { methods: {
async loadData() { async loadData(params) {
let productDetail = await this.$api.data('productDetail'); let productDetail = await this.$api.data('productDetail');
this.swiperList = productDetail.swiperList; this.swiperList = productDetail.swiperList;
this.productInfo = productDetail.productInfo; this.productInfo = productDetail.productInfo;

View File

@ -46,14 +46,22 @@
<script> <script>
export default { export default {
name: "product-pick", name: "product-pick",
props: { props: {
shopInfo: {
type: Object,
default: {}
},
productInfo: {
type: Object,
default: {}
},
specsList: { specsList: {
type: Array, type: Array,
default: [] default: []
}, },
orderNow: { orderNow: {
type: Boolean, type: Boolean,
default: false default: false
} }
}, },
data() { data() {
@ -88,16 +96,47 @@
chooseSpecs(item) { chooseSpecs(item) {
this.curSpec = item; this.curSpec = item;
}, },
submit() { getPickedSpecsList() {
if (this.orderNow) { let pickedList = [];
// for (let i = 0; i < this.pickList.length; i++) {
uni.navigateTo({ if (this.pickList[i].pickCount > 0) {
url: '../order/order-detail' pickedList.push({
}) id: this.specsList[i].id,
} else { name: this.specsList[i].name,
// pickedNum: this.pickList[i].pickCount,
uni.$emit('product-detail_add2Cart', this.totalPickCount) maxPieces: this.specsList[i].maxPieces,
})
}
} }
return pickedList;
},
submit() {
if (this.orderNow) {
//
let pickedList = this.getPickedSpecsList();
if (pickedList.length === 0) {
uni.showToast({
icon: 'none',
title: '请选择型号'
})
return;
}
let params = {
pickedProductList: [{
...this.shopInfo,
product: [{
...this.productInfo,
pickedList: pickedList
}]
}]
}
uni.navigateTo({
url: '../order/order-detail?params=' + encodeURIComponent(JSON.stringify(params))
})
} else {
//
uni.$emit('product-detail_add2Cart', this.totalPickCount)
}
} }
}, },
} }
@ -118,12 +157,12 @@
} }
.certern-height-with-scroll { .certern-height-with-scroll {
height: 600rpx; height: 600rpx;
margin-bottom: calc(100rpx - constant(safe-area-inset-bottom)/2); margin-bottom: calc(100rpx - constant(safe-area-inset-bottom)/2);
margin-bottom: calc(100rpx - env(safe-area-inset-bottom)/2); margin-bottom: calc(100rpx - env(safe-area-inset-bottom)/2);
} }
.main-container { .main-container {
padding-top: 45rpx; padding-top: 45rpx;
} }
</style> </style>