商品详情细节,商品订单,商品地址选择

msb_beta
ch 3 years ago
parent c347578bef
commit 60661dab23

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-29 17:38:17
* @LastEditors: ch
* @LastEditTime: 2022-04-07 09:58:52
* @LastEditTime: 2022-04-08 15:43:29
* @Description: file content
*/
import {ToAsyncAwait, MsbRequestTk} from '@/common/utils';
@ -16,11 +16,17 @@ const BASE_URL = '/mall/trade';
export const ApiGetOrderList = (params) =>
ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/app/tradeOrder/page`, params));
/**
* 获取预订单
* 获取立即购买预订单
* @param {*} data
*/
export const ApiGetBeforeOrder = (data) =>
ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/app/tradeOrder/buyAdvanceOrder`, data));
/**
* 获取购物车预订单
* @param {*} data
*/
export const ApiGetBeforeCartOrder = (data) =>
ToAsyncAwait(MsbRequestTk.get(`${BASE_URL}/app/tradeOrder/cartAdvanceOrder`, data));
/**
* 订单详情

@ -2,32 +2,40 @@
* @Author: ch
* @Date: 2022-03-22 18:28:52
* @LastEditors: ch
* @LastEditTime: 2022-04-06 20:22:21
* @LastEditTime: 2022-04-08 16:23:33
* @Description: file content
*/
import Vue from 'vue'
import Vuex from 'vuex';
Vue.use(Vuex)
Vue.use(Vuex);
const
// token
TOKEN = 'tk',
// 用户信息
USER_INFO = 'ui',
// 地址列表
ADDRESS = 'ads';
export default new Vuex.Store({
state : {
token : uni.getStorageSync('tk') || '',
userInfo : JSON.parse(uni.getStorageSync('ui') || '{}'),
address : JSON.parse(uni.getStorageSync('ads') || '[]')
token : uni.getStorageSync(TOKEN) || '',
userInfo : JSON.parse(uni.getStorageSync(USER_INFO) || '{}'),
address : JSON.parse(uni.getStorageSync(ADDRESS) || '[]')
},
mutations:{
SET_TOKEN (state, token = ''){
state.token = token;
uni.setStorageSync('tk', token);
uni.setStorageSync(TOKEN, token);
},
SET_USER_INFO (state, userInfo = {}){
state.userInfo = userInfo;
uni.setStorageSync('ui', JSON.stringify(userInfo));
uni.setStorageSync(USER_INFO, JSON.stringify(userInfo));
},
SET_ADDRESS (state, address = []){
state.address = address;
uni.setStorageSync('ads', JSON.stringify(address));
uni.setStorageSync(ADDRESS, JSON.stringify(address));
}
},
actions:{

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-17 17:42:32
* @LastEditors: ch
* @LastEditTime: 2022-04-07 16:10:37
* @LastEditTime: 2022-04-08 09:56:57
* @Description: 项目接口请求统一处理器返回一个需要token和不需要token的请求封装方法
*/
@ -31,7 +31,7 @@ const successIntercept = (response) =>{
return response;
}
const errorIntercept = (error) =>{
return Promise.reject({message:error.errMsg,code:error.statusCode})
return {message:error.errMsg,code:error.statusCode}
}
// 不需要token的接口封装
const MsbRequest = new MsbUniRequest();

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-20 16:45:27
* @LastEditors: ch
* @LastEditTime: 2022-04-07 18:24:25
* @LastEditTime: 2022-04-08 09:59:33
* @Description: file content
-->
<template>
@ -40,7 +40,7 @@ export default {
this.listData = this.listData.concat(result.records);
//
if(!result.records.length){
if(!result.records.length < this.params.length){
this.loadingStatus = 'nomore';
}
},

@ -1,204 +0,0 @@
<template>
<view class="container">
<view v-if="isLoading" class="loading">
<u-loading-icon mode="circle"></u-loading-icon>
</view>
<view v-else class="field-body" @click="handleSelect()">
<view class="field-value oneline-hide">{{ valueText ? valueText: placeholder }}</view>
</view>
<u-picker :show="show" keyName="label" :columns="options" @cancel="show = false" @change="changeRegion" @confirm="onConfirm"></u-picker>
</view>
</template>
<script>
import Emitter from 'uview-ui/libs/util/emitter'
import regionData from '@/mock/region.json';
// import RegionModel from '@/common/model/Region'
// valuekeys
//
const findOptionsKey = (data, searchValue, deep = 1, keys = []) => {
const index = data.findIndex(item => item.value === searchValue[deep - 1])
if (index > -1) {
keys.push(index)
if (data[index].children) {
findOptionsKey(data[index].children, searchValue, ++deep, keys)
}
}
return keys
}
export default {
name: 'SelectRegion',
mixins: [Emitter],
model: {
prop: 'value',
event: 'change'
},
props: {
// v-model
value: {
type: Array,
default: () => {
return []
}
},
//
placeholder: {
type: String,
default: '请选择省/市/区'
}
},
data() {
return {
//
isLoading: true,
//
show: false,
//
defaultValue: [],
// ()
valueText: '',
//
options: []
}
},
watch: {
// v-model
value(val) {
//
this.valueText = val.map(item => item.label).join('/')
this.setDefaultValue(val)
// u-form-item
this.dispatch('u-form-item', 'on-form-change', val)
},
},
created() {
//
this.getTreeData()
},
methods: {
//
handleSelect() {
this.show = true
},
//
getTreeData() {
const app = this
app.isLoading = true;
this.options = [[
{
label : '北京',
id : 11000000,
children : [
{
label : '东城',
id : 11100000
},
{
label : '西城',
id : 11200000
}
]
},
{
label : '湖南',
id : 43000000,
children : [
{
label : '长沙',
id : 11100000
},
{
label : '邵阳',
id : 11200000
}
]
}
],[{
label : '东城',
id : 11100000
},
{
label : '西城',
id : 11200000
}]];
app.isLoading = false;
// RegionModel.getTreeData()
// .then(regions => {
// //
// this.options = this.getOptions(regions)
// })
// .finally(() => app.isLoading = false)
},
changeRegion(val){
this.options = [this.options[0],val.value[0].children]
},
//
onConfirm(value) {
// v-model
this.$emit('input', value)
this.$emit('change', value)
},
/**
* 设置默认选中的值
* 该操作是为了每次打开选择器时聚焦到上次选择
* @param {Object} value
*/
setDefaultValue(value) {
const values = value.map(item => item.value)
const options = this.options
this.defaultValue = findOptionsKey(options, values)
},
/**
* 格式化级联选择器数据
* @param {*} regions 地区数据
*/
getOptions(regions) {
const { getOptions, getChildren } = this
const options = []
for (const index in regions) {
const item = regions[index]
const children = getChildren(item)
const optionItem = {
value: item.id,
label: item.name
}
if (children !== false) {
optionItem.children = getOptions(children)
}
options.push(optionItem)
}
return options
},
//
getChildren(item) {
if (item.city) {
return item.city
}
if (item.region) {
return item.region
}
return false
}
}
}
</script>
<style lang="scss" scoped>
.container {
width: 100%;
}
.loading {
padding-left: 10rpx;
// text-align: center;
}
</style>

@ -2,11 +2,11 @@
* @Author: ch
* @Date: 2022-03-26 10:06:38
* @LastEditors: ch
* @LastEditTime: 2022-03-31 21:16:11
* @LastEditTime: 2022-04-08 14:55:44
* @Description: file content
-->
<template>
<button :class="`btn btn__${type} btn__${size}${(disabed ? ' btn__disabed' : '')}`" @click="click"><slot></slot></button>
<button :class="`ui-btn ui-btn__${type} ui-btn__${size}${(disabed ? ' ui-btn__disabed' : '')}`" @click="click"><slot></slot></button>
</template>
<script>
export default {
@ -32,7 +32,7 @@ export default {
}
</script>
<style lang="scss" scoped>
.btn{
.ui-btn{
display: inline-block;
padding: 0 50rpx;
border-radius: 50rpx;

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-04-07 17:22:44
* @LastEditors: ch
* @LastEditTime: 2022-04-07 18:30:02
* @LastEditTime: 2022-04-07 19:33:22
* @Description: file content
-->
@ -54,8 +54,8 @@
export default {
data(){
return {
goodsLeftData : [],
goodsRightData : [],
// goodsLeftData : [],
// goodsRightData : [],
}
},
props: {
@ -64,8 +64,17 @@ export default {
defalut : []
}
},
computed:{
goodsLeftData (){
return this.listData.filter((item, index) => index % 2 === 0);
},
goodsRightData(){
return this.listData.filter((item, index) => index % 2 !== 0);
}
},
watch : {
listData (data){
lisatData (data){
console.log(data);
// const abs = this.goodsLeftData.length - this.goodsRightData.length;
const newLeftData = [];
const newRightData = [];

@ -26,6 +26,7 @@
},
{
"path": "pages/goods/category",
"aliasPath" : "/category",
"style": {
"navigationStyle" : "custom",
"navigationBarTitleText": "uni-app"

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-22 14:12:18
* @LastEditors: ch
* @LastEditTime: 2022-04-06 21:19:21
* @LastEditTime: 2022-04-08 17:04:51
* @Description: file content
-->
<template>
@ -39,7 +39,7 @@ import BsSelectCity from '../../../components/BsSelectCity.vue';
import UiButton from '../../../components/UiButton.vue';
import UiCell from '../../../components/UiCell.vue';
import {IsPhone} from '@/common/utils';
import {ApiPutAddress} from '@/common/api/base';
import {ApiPostAddress} from '@/common/api/base';
export default {
components: { UiCell, UiButton, BsSelectCity },
@ -77,7 +77,7 @@ export default {
const cityCode = this.city[1].code;
const provinceCode = this.city[0].code;
const province = this.city[0].name;
const {error} = await ApiPutAddress({
const {error} = await ApiPostAddress({
...this.address,
province,provinceCode,areaCode,area,city,cityCode
});

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-22 13:54:15
* @LastEditors: ch
* @LastEditTime: 2022-04-06 20:22:31
* @LastEditTime: 2022-04-08 17:21:04
* @Description: file content
-->
<template>
@ -14,6 +14,7 @@
<view class="addressItem" v-for="(item, index) in addresList" :key="item.id"
:class="{'addressItem__last' : index === addresList.length - 1,'addressItem__default':item.isDefault}">
<radio :checked="item.id === selectedId" @click="changeAds(item)"/>
<view>
<view class="addressItem--city">{{item.province}}{{item.city}}{{item.area}}</view>
<view class="addressItem--detail">{{item.detailAddress}}</view>
@ -39,24 +40,30 @@ import {ApiGetAddress} from '@/common/api/base';
export default {
components: { BsEmpty, UiButton },
data() {
const {query} = this.$Route;
return {
query:{
type : query.type,
id : query.id,
// submitOrder
source : query.source
},
addresList : [],
isLoading : true
};
},
computed:{
selectedId (){
const defaultAddress = this.addresList.find(i => i.isDefault);
return this.query.id || defaultAddress.id;
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
onLoad(options) {
this.getAddressList();
},
methods: {
async getAddressList(){
this.isLoading = true;
@ -68,6 +75,14 @@ export default {
}
this.addresList = result;
this.$store.commit('SET_ADDRESS', result);
},
/**
* 选择地址
*/
changeAds(item){
// 使VUEX
uni.$emit('changeAddress',item, this.query.source);
this.$Router.back();
}
},
};

@ -122,7 +122,6 @@ export default {
checkedIds: {
handler(val) {
//
console.log(val);
uni.setStorageSync(CartIdsIndex, val)
},
immediate: false
@ -181,10 +180,7 @@ export default {
* 清除checkedIds中无效的ID
*/
onClearInvalidId() {
// const app = this
// const listIds = app.list.map(item => item.id)
this.checkedIds = this.checkedIds.filter(i => this.list.findIndex(item => item.id === i));
// listIds.filter(val => checkedIds.indexOf(val) > -1)
this.checkedIds = this.checkedIds.filter(i => this.list.findIndex(item => item.id === i) > -1);
},
/**
@ -259,7 +255,13 @@ export default {
handleOrder() {
const ids = this.checkedIds;
if (ids.length) {
app.$Router.push('orderSubmit', { mode: 'cart', ids:ids.join(',') })
this.$Router.push({
path : '/orderSubmit',
query : {
mode: 'cart',
ids:ids.join(',')
}
})
}
},

@ -1,141 +0,0 @@
<template>
<!-- 商品图片 -->
<view class="images-swiper">
<swiper class="swiper-box" :autoplay="autoplay" :duration="duration" :indicator-dots="indicatorDots"
:interval="interval" :circular="true" @change="setCurrent">
<!-- 主图视频 -->
<swiper-item v-if="video">
<view class="slide-video">
<video id="myVideo" class="video" :poster="videoCover.preview_url" :src="video.external_url" controls
x5-playsinline playsinline webkit-playsinline webkit-playsinline x5-video-player-type="h5"
x5-video-player-fullscreen x5-video-orientation="portrait" :enable-progress-gesture="false"
@play="onVideoPlay"></video>
</view>
</swiper-item>
<!-- 轮播图片 -->
<swiper-item v-for="(item, index) in images" :key="index" @click="onPreviewImages(index)">
<view class="slide-image">
<image class="image" :draggable="false" :src="item.preview_url"></image>
</view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
props: {
//
video: {
type: Object,
default () {
return null
}
},
//
videoCover: {
type: Object,
default () {
return null
}
},
//
images: {
type: Array,
default: []
}
},
data() {
return {
indicatorDots: true, //
autoplay: true, //
interval: 4000, //
duration: 800, //
currentIndex: 1, //
}
},
methods: {
//
onVideoPlay(e) {
this.autoplay = false
},
//
setCurrent({ detail }) {
const app = this
app.currentIndex = detail.current + 1
},
//
onPreviewImages(index) {
const app = this
const imageUrls = []
app.images.forEach(item => {
imageUrls.push(item.preview_url);
});
uni.previewImage({
current: imageUrls[index],
urls: imageUrls
})
}
}
}
</script>
<style lang="scss" scoped>
// swiper
.images-swiper {
position: relative;
}
.swiper-box {
width: 100%;
height: 100vw;
/* #ifdef H5 */
max-width: 480px;
max-height: 480px;
margin: 0 auto;
/* #endif */
//
.slide-video {
width: 100%;
height: 100%;
.video {
display: block;
width: 100%;
height: 100%;
}
}
//
.slide-image {
position: relative;
width: 100%;
height: 100%;
.image {
display: block;
width: 100%;
height: 100%;
}
}
}
// swiper
.swiper-count {
position: absolute;
right: 36rpx;
bottom: 72rpx;
padding: 2rpx 18rpx;
background: rgba(0, 0, 0, 0.363);
border-radius: 50rpx;
color: #fff;
font-size: 26rpx;
}
</style>

@ -2,18 +2,18 @@
* @Author: ch
* @Date: 2022-03-24 11:30:55
* @LastEditors: ch
* @LastEditTime: 2022-04-06 14:24:05
* @LastEditTime: 2022-04-08 15:34:00
* @Description: file content
-->
<template>
<u-popup :show="visible" round="24rpx">
<u-popup :show="visible" round="24rpx" closeable @close="close">
<view class="sku-popup">
<view class="product-info">
<image class="product-img" src="https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/test/1.png"/>
<image class="product-info--img" src="https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/test/1.png"/>
<view>
<view>{{curSku.sellPrice}}</view>
<text>{{curSku.name}}</text>
<view>库存{{curSku.stock}}</view>
<view class="product-info--price">{{curSku.sellPrice}}</view>
<view class="product-info--sku">{{curSku.name}}</view>
<!-- <view>库存{{curSku.stock}}</view> -->
</view>
</view>
<view class="attr-group" v-for="(item, index) in attributeGroupList" :key="item.id">
@ -26,9 +26,11 @@
</view>
</view>
<view class="sku-num">
<view>
<text>数量</text>
<text>有货</text>
<view class="sku-num--single-box">
<template>
<text>数量</text>
<text class="sku-num--single">{{maxBuyNum}}</text>
</template>
</view>
<u-number-box :min="1" :max="maxBuyNum" button-size="40rpx" bgColor="#F5F6FA"
v-model="curBuyNum" >
@ -37,9 +39,11 @@
</u-number-box>
</view>
<view class="footer">
<UiButton @click="addCart"></UiButton>
<UiButton>立即购买</UiButton>
<UiButton>确认</UiButton>
<view class="btn-bg" v-if="mode == 1">
<UiButton class="btn" @click="addCart" size="max">加入购物车</UiButton>
<UiButton class="btn btn__buy" @click="buyNow" size="max">立即购买</UiButton>
</view>
<UiButton v-else class="btn__confirm" type="gradual" size="max" @click="confirm"></UiButton>
</view>
</view>
@ -47,7 +51,7 @@
</template>
<script>
import UiButton from '../../../components/UiButton.vue';
import UiButton from '@/components/UiButton.vue';
import {ApiPutAddCart} from '@/common/api/cart';
export default {
@ -134,7 +138,9 @@ export default {
break;
}
}
})
});
this.$emit('input',this.curSku);
},
/**
* 点击属性项设置选中和禁用项
@ -190,7 +196,26 @@ export default {
* 立即购买
*/
buyNow(){
console.log(this.curSku)
this.$Router.push({
path : '/orderSubmit',
query: {
mode : 'buyNow',
skuId : this.curSku.skuId,
num : this.curBuyNum
}
})
},
confirm(){
if(this.mode == 2){
this.addCart();
}
if(this.mode == 3){
this.buyNow();
}
},
close(){
this.$emit('update:visible', false)
}
}
};
@ -202,10 +227,20 @@ export default {
}
.product-info{
display: flex;
}
.product-img{
width: 200rpx;
height: 200rpx;
font-size: 28rpx;
color: #999;
line-height: 42rpx;
&--img{
width: 200rpx;
height: 200rpx;
margin-right: 40rpx;
}
&--price{
font-size: 40rpx;
color: #FF512B;
line-height: 48rpx;
margin-bottom: 20rpx;
}
}
.attr-group{
margin-top: 40rpx;
@ -244,9 +279,47 @@ export default {
display: flex;
justify-content: space-between;
margin: 40rpx 0;
line-height: 40rpx;
&--single-box{
display: flex;
align-items: center;
}
&--single{
color: #999;
margin-left: 10rpx;
font-size: 28rpx;
display: block;
height: 30rpx;
}
}
.footer{
display: flex;
justify-content: space-between;
.btn-bg{
background: #FFE6D9;
border-radius: 50rpx;
height: 80rpx;
}
.btn{
border: 0;
padding: 0;
border-radius: 0;
width: 340rpx;
font-size: 28rpx;
color: #FF875B;
&::after{
border: 0;
}
&__buy{
width: 350rpx;
background: url('@/static/goods/buy_max.png');
background-size: 350rpx;
color: #fff;
}
}
.btn__confirm{
margin: 0;
}
}
</style>

@ -0,0 +1,107 @@
<template>
<!-- 商品图片 -->
<view class="images-swiper">
<swiper class="swiper-box" :autoplay="autoplay" :duration="duration"
:indicator-dots="indicatorDots" :interval="interval" :circular="true"
@change="setCurrent">
<!-- 轮播图片 -->
<swiper-item v-for="(item, index) in images" :key="index"
@click="onPreviewImages(index)" >
<view class="slide-image">
<image class="image" :draggable="false" :src="item"></image>
</view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
props: {
//
images: {
type: Array,
default: [],
},
},
data() {
return {
indicatorDots: true, //
autoplay: true, //
interval: 4000, //
duration: 800, //
currentIndex: 1, //
};
},
methods: {
//
setCurrent({ detail }) {
this.currentIndex = detail.current + 1;
},
//
onPreviewImages(index) {
uni.previewImage({
current: index,
urls: this.images,
});
},
},
};
</script>
<style lang="scss" scoped>
// swiper
.images-swiper {
position: relative;
}
.swiper-box {
width: 100%;
height: 100vw;
/* #ifdef H5 */
max-width: 480px;
max-height: 480px;
margin: 0 auto;
/* #endif */
//
.slide-video {
width: 100%;
height: 100%;
.video {
display: block;
width: 100%;
height: 100%;
}
}
//
.slide-image {
position: relative;
width: 100%;
height: 100%;
.image {
display: block;
width: 100%;
height: 100%;
}
}
}
// swiper
.swiper-count {
position: absolute;
right: 36rpx;
bottom: 72rpx;
padding: 2rpx 18rpx;
background: rgba(0, 0, 0, 0.363);
border-radius: 50rpx;
color: #fff;
font-size: 26rpx;
}
</style>

@ -2,25 +2,29 @@
* @Author: ch
* @Date: 2022-03-23 17:27:21
* @LastEditors: ch
* @LastEditTime: 2022-04-06 09:47:06
* @LastEditTime: 2022-04-08 15:24:39
* @Description: file content
-->
<template>
<view>
<SlideImage :images="goods.images"></SlideImage>
<view class="back" @click="$Router.back()">
<image class="back--icon" src="@/static/goods/back.png"/>
</view>
<SlideImage :images="goods.pictureList"></SlideImage>
<view class="goods-info">
<view class="pirce">
<text></text>
<text>199.9</text>
<text class="pirce--max">{{goods.startingPrice}}</text>
<text></text>
</view>
<view class="goods-info--title">{{goods.name}}</view>
</view>
<view class="select">
<Service></Service>
<u-cell label="选择" :border="false" isLink @click="onShowSkuPopup()"></u-cell>
<SkuPopup v-model="selectedSkuInfo" :visible="showSkuPopup" :mode="skuMode" :goodsInfo="goods" :skuInfo="skuInfo" @addCart="onAddCart" ></SkuPopup>
<u-cell label="选择" :value="curSku.name" :border="false" isLink @click="onShowSkuPopup(1)"></u-cell>
<SkuPopup v-model="curSku" :visible.sync="showSkuPopup" :mode="skuMode"
:goodsInfo="goods" :skuInfo="skuInfoData">
</SkuPopup>
</view>
<view class="goods-desc">
<mp-html :content="goods.content"/>
@ -28,29 +32,32 @@
<view class="footer">
<view class="footer--left">
<view class="icon service">客服</view>
<view class="icon cart">购物</view>
<view class="icon cart" @click="$Router.push('/cart')"></view>
</view>
<view class="footer--btns">
<button class="btn" plain @click="onShowSkuPopup(2)"></button>
<button class="btn" plain @click="onShowSkuPopup(3)"></button>
<UiButton class="btn" @click="onShowSkuPopup(2)"></UiButton>
<UiButton class="btn btn--buy" @click="onShowSkuPopup(3)"></UiButton>
</view>
</view>
</view>
</template>
<script>
import {ApiGetGoodsDetail, ApiGetGoodsSkus} from '@/common/api/goods';
import SlideImage from '@/pages/goods/detail/SlideImage.vue';
import Service from './Service.vue';
import SlideImage from './components/SlideImage.vue';
import Service from './components/Service.vue';
import SkuPopup from './components/SkuPopup.vue';
import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html';
import SkuPopup from './SkuPopup.vue';
import UiButton from '../../../components/UiButton.vue';
export default {
components: { SlideImage, mpHtml, Service, SkuPopup},
components: { SlideImage, mpHtml, Service, SkuPopup, UiButton},
data(){
return {
goods : {},
skuInfo : [],
goods : {
pictureList : []
},
skuInfoData : [],
curSku : {},
showSkuPopup : false,
// sku 1: 2: 3:
skuMode : 1,
@ -69,14 +76,11 @@ export default {
const {query} = this.$Route;
const {error, result} = await ApiGetGoodsDetail({id : query.id});
if(error){
uin.$u.totast(error.message);
uni.$u.toast(error.message);
return false;
}
result.attributeGroupList[0].attributes = [...result.attributeGroupList[0].attributes, ...[
{name: "绿色", symbol: 6}
]]
this.goods = {...result,
images : result.otherPictureList || [result.mainPicture],
images : result.pictureList || [],
};
},
async getGoodsSkus(){
@ -86,7 +90,7 @@ export default {
uin.$u.totast(error.message);
return false;
}
this.skuInfo = result;
this.skuInfoData = result;
},
/**
* 显示/隐藏SKU弹窗
@ -105,6 +109,22 @@ page{
background: #f8f8f8;
padding-bottom: 138rpx;
}
.back{
position: absolute;
width: 50rpx;
height: 50rpx;
left: 40rpx;
top: 40rpx;
background: rgba($color: #000000, $alpha: .1);
z-index: 999;
border-radius: 50%;
&--icon{
width: 14rpx;
height: 28rpx;
margin: 10rpx 0 0 15rpx;
}
}
.goods-info{
margin: 20rpx 30rpx 0;
background: #fff;
@ -115,6 +135,14 @@ page{
line-height: 48rpx;
}
}
.pirce{
color: #FF875B;
font-size: 28rpx;
&--max{
font-size: 52rpx;
margin: 0 10rpx 24rpx 0;
}
}
.select{
margin: 20rpx 30rpx;
background: #fff;
@ -139,22 +167,25 @@ page{
border-top-left-radius: 24rpx;
border-top-right-radius: 24rpx;
background: #fff;
box-shadow: 0 8rpx 80rpx 1px rgba(0, 0, 0, 0.1);
&--left{
display: flex;
}
&--btns{
background: #FFF3EE;
border-radius: 40rpx;
height: 80rpx;
overflow: hidden;
}
.icon{
font-size: 22rpx;
padding-top: 60rpx;
background: url('@/static/tabbar/home.png') no-repeat center top;
background: url('@/static/goods/service_icon.png') no-repeat center top;
background-size: 48rpx;
color: #333;
&.cart{
margin-left: 40rpx;
background-image: url('@/static/goods/cart_icon.png');
}
}
.btn{
@ -166,6 +197,17 @@ page{
border: none;
font-size: 28rpx;
color: #FF875B;
border-bottom-left-radius: 0;
border-top-left-radius: 0;
padding: 0;
&::after{
display: none;
}
&--buy{
background: url('@/static/goods/buy.png');
background-size: 250rpx;
color: #fff;
}
}
}
</style>

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-21 10:31:54
* @LastEditors: ch
* @LastEditTime: 2022-04-07 19:12:18
* @LastEditTime: 2022-04-08 09:59:44
* @Description: file content
-->
<template>
@ -18,7 +18,7 @@
<Sort @change="sortChange"></Sort>
</view>
<UiGoodsGroup v-if="listData.length" class="goods-group" :listData="listData"></UiGoodsGroup>
<u-loadmore :status="loadingStatus" v-if="!listData.length && params.pageIndex > 1"/>
<u-loadmore :status="loadingStatus" v-if="!showEmpty"/>
<!-- 当前条件无数据时展示 -->
<template v-if="showEmpty">
@ -92,7 +92,7 @@ export default {
}
this.listData = this.listData.concat(result.records);
//
if(!result.records.length){
if(result.records.length < this.params.length){
this.loadingStatus = 'nomore';
}
},

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-03-22 15:36:46
* @LastEditors: ch
* @LastEditTime: 2022-04-07 14:41:24
* @LastEditTime: 2022-04-07 19:46:48
* @Description: file content
-->
<template>
@ -107,8 +107,15 @@ export default {
const pages = getCurrentPages();
const len = pages.length;
const prevPage = pages[len - 2];
if(len > 1 && prevPage.route !== 'pages/index/index'){
this.$Router.back();
const tabBar = ['pages/index/index','pages/goods/category'];
console.log(prevPage);
if(len > 1){
// tabBartabBar
if(tabBar.includes(prevPage.route)){
this.$Router.replaceAll(prevPage.__page__.path);
}else{
this.$Router.back();
}
}else{
this.$Router.replaceAll('/');
}

@ -1,876 +0,0 @@
<!--
* @Author: ch
* @Date: 2022-03-22 11:17:55
* @LastEditors: ch
* @LastEditTime: 2022-03-22 14:04:38
* @Description: file content
-->
<template>
<view v-if="!isLoading" class="container">
<view class="header">
<!-- 订单状态 -->
<view class="order-status">
<view class="status-icon">
<!-- 进行中的订单 -->
<block v-if="order.order_status == OrderStatusEnum.NORMAL.value">
<!-- 待支付 -->
<block v-if="order.pay_status == PayStatusEnum.PENDING.value">
<image class="image" src="/static/order/status/wait_pay.png" mode="aspectFit"></image>
</block>
<!-- 待发货 -->
<block v-else-if="order.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
<image class="image" src="/static/order/status/wait_deliver.png" mode="aspectFit"></image>
</block>
<!-- 待收货 -->
<block v-else-if="order.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
<image class="image" src="/static/order/status/wait_receipt.png" mode="aspectFit"></image>
</block>
</block>
<!-- 已完成 -->
<block v-if="order.order_status == OrderStatusEnum.COMPLETED.value">
<image class="image" src="/static/order/status/received.png" mode="aspectFit"></image>
</block>
<!-- 已取消/待取消 -->
<block
v-if="order.order_status == OrderStatusEnum.CANCELLED.value || order.order_status == OrderStatusEnum.APPLY_CANCEL.value">
<image class="image" src="/static/order/status/close.png" mode="aspectFit"></image>
</block>
</view>
<view class="status-text">
<text>{{ order.state_text }}</text>
</view>
</view>
<!-- 下一步操作 -->
<view class="next-action" v-if="order.order_status == OrderStatusEnum.NORMAL.value">
<view v-if="order.pay_status == PayStatusEnum.PENDING.value" class="action-btn" @click="onPay()"></view>
<view
v-if="order.delivery_status == DeliveryStatusEnum.DELIVERED.value && order.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value"
class="action-btn" @click="onReceipt(order.order_id)">确认收货</view>
</view>
</view>
<!-- 快递配送配送地址 -->
<view class="delivery-address i-card">
<view class="link-man">
<text class="name">{{ order.address.name }}</text>
<text class="phone">{{ order.address.phone }}</text>
</view>
<view class="address">
<text class="region" v-for="(region, idx) in order.address.region" :key="idx">{{ region }}</text>
<text class="detail">{{ order.address.detail }}</text>
</view>
</view>
<!-- 物流信息 -->
<view
v-if="order.delivery_type == DeliveryTypeEnum.EXPRESS.value && order.delivery_status == DeliveryStatusEnum.DELIVERED.value"
class="express i-card" @click="handleTargetExpress()">
<view class="main">
<view class="info-item">
<view class="item-lable">物流公司</view>
<view class="item-content">
<text>{{ order.express.express_name }}</text>
</view>
</view>
<view class="info-item">
<view class="item-lable">物流单号</view>
<view class="item-content">
<text>{{ order.express_no }}</text>
<view class="act-copy" @click.stop="handleCopy(order.express_no)">
<text>复制</text>
</view>
</view>
</view>
</view>
<view class="right-arrow">
<text class="iconfont icon-arrow-right"></text>
</view>
</view>
<!-- 商品列表 -->
<view class="goods-list i-card">
<view class="goods-item" v-for="(goods, idx) in order.goods" :key="idx">
<view class="goods-main" @click="handleTargetGoods(goods.goods_id)">
<!-- 商品图片 -->
<view class="goods-image">
<image class="image" :src="goods.goods_image" mode="scaleToFill"></image>
</view>
<!-- 商品信息 -->
<view class="goods-content">
<view class="goods-title twoline-hide"><text>{{ goods.goods_name }}</text></view>
<view class="goods-props clearfix">
<view class="goods-props-item" v-for="(props, idx) in goods.goods_props" :key="idx">
<text>{{ props.value.name }}</text>
</view>
</view>
</view>
<!-- 交易信息 -->
<view class="goods-trade">
<view class="goods-price">
<text class="unit"></text>
<text class="value">{{ goods.is_user_grade ? goods.grade_goods_price : goods.goods_price }}</text>
</view>
<view class="goods-num">
<text>×{{ goods.total_num }}</text>
</view>
</view>
</view>
<!-- 商品售后 -->
<view class="goods-refund">
<text v-if="goods.refund" class="stata-text"></text>
<view v-else-if="order.isAllowRefund" class="action-btn"
@click.stop="handleApplyRefund(goods.order_goods_id)">申请售后</view>
</view>
</view>
</view>
<!-- 订单信息 -->
<view class="order-info i-card">
<view class="info-item">
<view class="item-lable">订单编号</view>
<view class="item-content">
<text>{{ order.order_no }}</text>
<view class="act-copy" @click="handleCopy(order.order_no)">
<text>复制</text>
</view>
</view>
</view>
<view class="info-item">
<view class="item-lable">下单时间</view>
<view class="item-content">
<text>{{ order.create_time }}</text>
</view>
</view>
<view class="info-item">
<view class="item-lable">买家留言</view>
<view class="item-content">
<text>{{ order.buyer_remark ? order.buyer_remark : '--' }}</text>
</view>
</view>
</view>
<!-- 结算信息 -->
<view class="trade-info i-card">
<view class="info-item">
<view class="item-lable">订单金额</view>
<view class="item-content">
<text>{{ order.total_price }}</text>
</view>
</view>
<view v-if="order.coupon_money > 0" class="info-item">
<view class="item-lable">优惠券抵扣</view>
<view class="item-content">
<text>-{{ order.coupon_money }}</text>
</view>
</view>
<view v-if="order.points_money > 0" class="info-item">
<view class="item-lable">{{ setting.points_name }}抵扣</view>
<view class="item-content">
<text>-{{ order.points_money }}</text>
</view>
</view>
<view class="info-item">
<view class="item-lable">运费</view>
<view class="item-content">
<text>+{{ order.express_price }}</text>
</view>
</view>
<view v-if="order.update_price.value != '0.00'" class="info-item">
<view class="item-lable">后台改价</view>
<view class="item-content">
<text>{{ order.update_price.symbol }}</text>
<text>{{ order.update_price.value }}</text>
</view>
</view>
<view class="divider"></view>
<view class="trade-total">
<text class="lable">实付款</text>
<view class="goods-price">
<text class="unit"></text>
<text class="value">{{ order.pay_price }}</text>
</view>
</view>
</view>
<!-- 底部操作按钮 -->
<view v-if="order.order_status != OrderStatusEnum.CANCELLED.value" class="footer-fixed">
<view class="btn-wrapper">
<!-- 未支付取消订单 -->
<block v-if="order.pay_status == PayStatusEnum.PENDING.value">
<view class="btn-item" @click="onCancel(order.order_id)"></view>
</block>
<!-- 已支付进行中的订单 -->
<block v-if="order.order_status != OrderStatusEnum.APPLY_CANCEL.value">
<block
v-if="order.pay_status == PayStatusEnum.SUCCESS.value && order.delivery_status == DeliveryStatusEnum.NOT_DELIVERED.value">
<view class="btn-item" @click="onCancel(order.order_id)"></view>
</block>
</block>
<!-- 已申请取消 -->
<view v-else class="f-28 col-8">取消申请中</view>
<!-- 未支付的订单 -->
<block v-if="order.pay_status == PayStatusEnum.PENDING.value">
<view class="btn-item active" @click="onPay()"></view>
</block>
<!-- 确认收货 -->
<block
v-if="order.delivery_status == DeliveryStatusEnum.DELIVERED.value && order.receipt_status == ReceiptStatusEnum.NOT_RECEIVED.value">
<view class="btn-item active" @click="onReceipt(order.order_id)"></view>
</block>
<!-- 订单评价 -->
<block v-if="order.order_status == OrderStatusEnum.COMPLETED.value && order.is_comment == 0">
<view class="btn-item" @click="handleTargetComment(order.order_id)"></view>
</block>
</view>
</view>
<!-- 支付方式弹窗 -->
<u-popup v-model="showPayPopup" mode="bottom" border-radius="26" :closeable="true">
<view class="pay-popup">
<view class="title">请选择支付方式</view>
<view class="pop-content">
<!-- 微信支付 -->
<!-- #ifdef MP-WEIXIN -->
<view class="pay-item dis-flex flex-x-between" @click="onSelectPayType(PayTypeEnum.WECHAT.value)">
<view class="item-left dis-flex flex-y-center">
<view class="item-left_icon wechat">
<text class="iconfont icon-wxpay"></text>
</view>
<view class="item-left_text">
<text>{{ PayTypeEnum.WECHAT.name }}</text>
</view>
</view>
</view>
<!-- #endif -->
<!-- 余额支付 -->
<view class="pay-item dis-flex flex-x-between" @click="onSelectPayType(PayTypeEnum.BALANCE.value)">
<view class="item-left dis-flex flex-y-center">
<view class="item-left_icon balance">
<text class="iconfont icon-qiandai"></text>
</view>
<view class="item-left_text">
<text>{{ PayTypeEnum.BALANCE.name }}</text>
</view>
</view>
</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
DeliveryStatusEnum,
DeliveryTypeEnum,
OrderStatusEnum,
PayStatusEnum,
PayTypeEnum,
ReceiptStatusEnum
} from '@/common/enum/order'
// import * as OrderApi from '@/api/order'
// import { wxPayment } from '@/core/app'
export default {
data() {
return {
//
DeliveryStatusEnum,
DeliveryTypeEnum,
OrderStatusEnum,
PayStatusEnum,
PayTypeEnum,
ReceiptStatusEnum,
// ID
orderId: null,
//
isLoading: true,
//
order: {},
//
setting: {},
//
showPayPopup: false
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad({ orderId }) {
// ID
this.orderId = orderId
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
//
this.getOrderDetail()
},
methods: {
//
getOrderDetail() {
const app = this
app.isLoading = true
OrderApi.detail(app.orderId)
.then(result => {
app.order = result.data.order
app.setting = result.data.setting
app.isLoading = false
})
},
//
handleCopy(value) {
const app = this
uni.setClipboardData({
data: value,
success() {
app.$toast('复制成功')
}
})
},
//
handleTargetExpress() {
this.$navTo('pages/order/express/index', { orderId: this.orderId })
},
//
handleTargetGoods(goodsId) {
this.$navTo('pages/goods/detail', { goodsId })
},
//
handleApplyRefund(orderGoodsId) {
this.$navTo('pages/refund/apply', { orderGoodsId })
},
//
onCancel(orderId) {
const app = this
uni.showModal({
title: '友情提示',
content: '确认要取消该订单吗?',
success(o) {
if (o.confirm) {
OrderApi.cancel(orderId)
.then(result => {
//
app.$toast(result.message)
//
app.getOrderDetail()
})
}
}
});
},
//
onReceipt(orderId) {
const app = this
uni.showModal({
title: '友情提示',
content: '确认收到商品了吗?',
success(o) {
if (o.confirm) {
OrderApi.receipt(orderId)
.then(result => {
//
app.$success(result.message)
//
app.getOrderDetail()
})
}
}
});
},
//
onPay() {
//
this.showPayPopup = true
},
//
onSelectPayType(payType) {
const app = this
//
this.showPayPopup = false
//
OrderApi.pay(app.orderId, payType)
.then(result => app.onSubmitCallback(result))
.catch(err => err)
},
//
onSubmitCallback(result) {
const app = this
//
if (result.data.pay_type == PayTypeEnum.WECHAT.value) {
wxPayment(result.data.payment)
.then(() => {
app.$success('支付成功')
setTimeout(() => {
app.getOrderDetail()
}, 1500)
})
.catch(err => {
app.$error('订单未支付')
})
.finally(() => {
app.disabled = false
})
}
//
if (result.data.pay_type == PayTypeEnum.BALANCE.value) {
app.$success('支付成功')
app.disabled = false
setTimeout(() => {
//
app.getOrderDetail()
}, 1500)
}
},
//
handleTargetComment(orderId) {
this.$navTo('pages/order/comment/index', { orderId })
},
},
}
</script>
<style>
page {
background: #f4f4f4;
}
</style>
<style lang="scss" scoped>
.container {
padding-bottom: constant(env(safe-area-inset-bottom) + 106rpx + 6rpx);
padding-bottom: calc(env(safe-area-inset-bottom) + 106rpx + 6rpx);
}
//
.header {
display: flex;
justify-content: space-between;
background-color: #e8c269;
height: 280rpx;
padding: 56rpx 30rpx 0 30rpx;
.order-status {
display: flex;
align-items: center;
height: 128rpx;
.status-icon {
width: 128rpx;
height: 128rpx;
.image {
display: block;
width: 100%;
height: 100%;
}
}
.status-text {
padding-left: 20rpx;
color: #fff;
font-size: 38rpx;
font-weight: bold;
}
}
.next-action {
display: flex;
align-items: center;
height: 128rpx;
.action-btn {
min-width: 152rpx;
height: 56rpx;
padding: 0 30rpx;
line-height: 56rpx;
background-color: #fff;
text-align: center;
border-radius: 28rpx;
border-color: rgb(102, 102, 102);
cursor: pointer;
user-select: none;
color: #c7a157;
}
}
}
//
.i-card {
background: #fff;
padding: 24rpx 24rpx;
width: 94%;
box-shadow: 0 1rpx 5rpx 0px rgba(0, 0, 0, 0.05);
margin: 0 auto 20rpx auto;
border-radius: 20rpx;
}
//
.delivery-address {
margin-top: -50rpx;
.link-man {
line-height: 46rpx;
color: #333;
.name {
margin-right: 10rpx;
}
}
.address {
margin-top: 12rpx;
color: #999;
font-size: 24rpx;
.detail {
margin-left: 6rpx;
}
}
}
//
.express {
display: flex;
align-items: center;
.main {
flex: 1;
}
.info-item {
display: flex;
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
.item-lable {
display: flex;
align-items: center;
font-size: 24rpx;
color: #999;
margin-right: 30rpx;
}
.item-content {
flex: 1;
display: flex;
align-items: center;
font-size: 26rpx;
color: #333;
.act-copy {
margin-left: 20rpx;
padding: 2rpx 20rpx;
font-size: 22rpx;
color: #666;
border: 1rpx solid #c1c1c1;
border-radius: 16rpx;
}
}
}
//
.right-arrow {
margin-left: 16rpx;
// color: #777;
font-size: 26rpx;
}
}
//
.goods-list {
//
.goods-item {
margin-bottom: 40rpx;
&:last-child {
margin-bottom: 0;
}
//
.goods-main {
display: flex;
}
//
.goods-image {
width: 180rpx;
height: 180rpx;
.image {
display: block;
width: 100%;
height: 100%;
border-radius: 8rpx;
}
}
//
.goods-content {
flex: 1;
padding-left: 16rpx;
padding-top: 16rpx;
.goods-title {
font-size: 26rpx;
max-height: 76rpx;
}
.goods-props {
margin-top: 14rpx;
height: 40rpx;
color: #ababab;
font-size: 24rpx;
overflow: hidden;
.goods-props-item {
display: inline-block;
margin-right: 14rpx;
padding: 4rpx 16rpx;
border-radius: 12rpx;
background-color: #F5F5F5;
width: auto;
}
}
}
//
.goods-trade {
padding-top: 16rpx;
width: 150rpx;
text-align: right;
color: $uni-text-color-grey;
font-size: 26rpx;
.goods-price {
vertical-align: bottom;
margin-bottom: 16rpx;
.unit {
margin-right: -2rpx;
font-size: 24rpx;
}
}
}
//
.goods-refund {
display: flex;
justify-content: flex-end;
.stata-text {
font-size: 24rpx;
color: #999;
}
.action-btn {
border-radius: 28rpx;
padding: 8rpx 26rpx;
font-size: 24rpx;
color: #383838;
border: 1rpx solid #a8a8a8;
}
}
}
}
//
.order-info {
.info-item {
display: flex;
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
.item-lable {
display: flex;
align-items: center;
font-size: 24rpx;
color: #999;
margin-right: 30rpx;
}
.item-content {
flex: 1;
display: flex;
align-items: center;
font-size: 26rpx;
color: #333;
.act-copy {
margin-left: 20rpx;
padding: 2rpx 20rpx;
font-size: 22rpx;
color: #666;
border: 1rpx solid #c1c1c1;
border-radius: 16rpx;
}
}
}
}
//
.trade-info {
.info-item {
display: flex;
margin-bottom: 24rpx;
.item-lable {
font-size: 24rpx;
color: #999;
margin-right: 24rpx;
}
.item-content {
flex: 1;
font-size: 26rpx;
color: #333;
text-align: right;
}
}
.divider {
height: 1rpx;
background: #f1f1f1;
margin-bottom: 24rpx;
}
.trade-total {
display: flex;
justify-content: flex-end;
.goods-price {
margin-left: 12rpx;
vertical-align: bottom;
color: $uni-text-color-active;
.unit {
margin-right: -2rpx;
font-size: 24rpx;
}
}
}
}
/* 底部操作栏 */
.footer-fixed {
position: fixed;
bottom: var(--window-bottom);
left: 0;
right: 0;
z-index: 11;
box-shadow: 0 -4rpx 40rpx 0 rgba(151, 151, 151, 0.24);
background: #fff;
// ios线
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.btn-wrapper {
height: 106rpx;
display: flex;
align-items: center;
justify-content: flex-end;
padding: 0 30rpx;
}
.btn-item {
min-width: 164rpx;
border-radius: 28rpx;
padding: 10rpx 24rpx;
font-size: 28rpx;
color: #383838;
text-align: center;
border: 1rpx solid #a8a8a8;
margin-left: 24rpx;
&.active {
color: #fff;
border: none;
background: linear-gradient(to right, #f9211c, #ff6335);
}
}
}
// -
.pay-popup {
padding: 24rpx;
.title {
font-size: 30rpx;
margin-bottom: 50rpx;
font-weight: bold;
text-align: center;
}
.pop-content {
min-height: 260rpx;
padding: 0 10rpx;
.pay-item {
padding: 20rpx 35rpx;
font-size: 28rpx;
border-bottom: 1rpx solid #f1f1f1;
&:last-child {
border-bottom: none;
}
.item-left_icon {
margin-right: 20rpx;
font-size: 32rpx;
&.wechat {
color: #00c800;
}
&.balance {
color: #ff9700;
}
}
}
}
}
//
</style>

@ -1,446 +0,0 @@
.dis-flex{
display: flex;
}
//
.flow-delivery {
padding: 34rpx 30rpx;
background: #fff url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANYAAAANCAYAAADVGpDCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3Yjk4M2ExYy1jMDhkLTQ1OTktYTI0Ny1kZjNjYzdiYTQ5ZTgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDQwNkY3RkU5N0NGMTFFNUI3N0M4NTU4MzM2RjlFODIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDQwNkY3RkQ5N0NGMTFFNUI3N0M4NTU4MzM2RjlFODIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNzgwZWI1NS03OGFhLTQzOTUtODQ4OC1lOWI5YmVlYTY1ZDciIHN0UmVmOmRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo1OTRiYzUyMy1jMzc3LTExNzgtYTdkZS04NGY3YmM1ZGIxMDMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz556PLxAAACBElEQVR42tyaSyhEYRTHP48imlKibDQeSSlkSlEWLCRFsZNH5FE2FqQ8ErIRC9lIkTwXSpMkWWChhEJCSnlkoUZGSsr78f98n43CMFPu/Z/6NZuZ2zn33/+cb869XkmLx8IDEQaGQJbgiytQDSY3MyL+LYnL/HxPXSoHDIJQQq2WQQk4Dbbb/yUB29LJ+6e3B66VB3ZITbUIEqSpCGoJBP1ghtBUD6ARpEtTGSEhXzd+awE9oJzQUPegWdf3QlBPMhgDMYRa7YNisGWkpP5qrBQtVBShUHugUE9hs4fUtwG0utlEjRivoA/Ug1sj3vjffr8FNJEK1auPFHcE9UTq5pdK2PwcoAzMG7mjuRrRYEIfK9jiDJSCBZJ6ynSTsBBqNQ0qgdPISbq6vJCFbJOaagrEk5gqWNczRGiqG1Ah1LLMafRkf5pYIUKtZnMJDXUNasAIST2ZYFioRx9ssQaKwJFZEv5uYmWDXVJTrYBEElP562PfPKGpnkAbSDOTqb6aWAGgW6iHol5kQj2CdtAJngnqkc1hHMQRNr9DPaXWzZj8Z2PZtFCxhEIdaKE2CGqRJ4060AH8CLUaALX6f5VpBZLhI9SaeZXQVHKNLt84SCIxVbhQi5YuQlNd6OVElZlN9TGxrGBUn2PZ4lyoTdIsST0FQj0UDSLUak6ot3gcBLVY3wQYAJoVXxmNERajAAAAAElFTkSuQmCC') bottom left repeat-x;
background-size: 120rpx auto;
.detail-location {
font-size: 36rpx;
}
.detail-content {
padding: 0 20rpx;
.detail-content__title-phone {
margin-left: 10rpx;
}
.detail-content__describe {
font-size: 28rpx;
color: #777;
}
}
.detail-content__title {
margin-bottom: 6rpx;
}
}
//
.flow-all-money {
.ipt-wrapper {
input {
font-size: 28rpx;
width: 100%;
height: 75rpx;
}
}
}
//
.checkout_list {
padding: 20rpx 30rpx 4rpx 30rpx;
background: #fff;
border-bottom: 1rpx solid rgb(248, 248, 248);
.flow-shopList {
padding: 5rpx 0 10rpx;
border-bottom: 1rpx solid rgb(248, 248, 248);
&:last-child {
border-bottom: 0;
}
}
}
.flow-header-left {
padding-left: 90rpx;
}
/* 会员价 */
.flow-shopList {
.flow-list-right {
.flow-cont {
&.price-delete {
font-size: 26rpx;
color: #777;
text-decoration: line-through;
}
}
}
.grade-price {
padding-top: 8rpx;
font-size: 28rpx;
color: #ff495e;
text-align: right;
}
.goods-name{
font-size: 28rpx;
color: #333;
}
}
/* 优惠券选择 */
.popup__coupon {
width: 750rpx;
background: #fff;
box-sizing: border-box;
padding: 30rpx;
.coupon__do_not {
.control {
width: 90%;
height: 72rpx;
margin-bottom: 24rpx;
color: #888;
border: 1rpx solid #e3e3e3;
border-radius: 10rpx;
/* #ifdef H5 */
max-width: 1120rpx;
/* #endif */
}
}
.coupon__title {
text-align: center;
margin-bottom: 30rpx;
}
.coupon-list {
/* #ifdef H5 */
max-width: 1120rpx;
margin: 0 auto;
/* #endif */
}
.coupon-item {
overflow: hidden;
margin-bottom: 22rpx;
}
.item-wrapper {
width: 100%;
display: flex;
background: #fff;
border-radius: 8rpx;
color: #fff;
height: 180rpx;
.coupon-type {
position: absolute;
top: 0;
right: 0;
z-index: 10;
width: 128rpx;
padding: 6rpx 0;
background: #a771ff;
font-size: 20rpx;
text-align: center;
color: #ffffff;
transform: rotate(45deg);
transform-origin: 64rpx 64rpx;
}
&.color-blue {
background: linear-gradient(-125deg, #57bdbf, #2f9de2);
}
&.color-red {
background: linear-gradient(-128deg, #ff6d6d, #ff3636);
}
&.color-violet {
background: linear-gradient(-113deg, #ef86ff, #b66ff5);
.coupon-type {
background: #55b5ff;
}
}
&.color-yellow {
background: linear-gradient(-141deg, #f7d059, #fdb054);
}
&.color-gray {
background: linear-gradient(-113deg, #bdbdbd, #a2a1a2);
.coupon-type {
background: #9e9e9e;
}
}
.content {
flex: 1;
padding: 30rpx 20rpx;
border-radius: 16rpx 0 0 16rpx;
.title {
font-size: 32rpx;
}
.bottom {
.time {
font-size: 24rpx;
}
.receive {
height: 46rpx;
width: 122rpx;
line-height: 46rpx;
text-align: center;
border: 1rpx solid #fff;
border-radius: 30rpx;
color: #fff;
font-size: 24rpx;
&.state {
border: none;
}
}
}
}
.tip {
position: relative;
flex: 0 0 32%;
text-align: center;
border-radius: 0 16rpx 16rpx 0;
.money {
font-weight: bold;
font-size: 52rpx;
}
.pay-line {
font-size: 22rpx;
}
}
.split-line {
position: relative;
flex: 0 0 0;
border-left: 4rpx solid #fff;
margin: 0 10rpx 0 6rpx;
background: #fff;
&:before,
{
border-radius: 0 0 16rpx 16rpx;
top: 0;
}
&:after {
border-radius: 16rpx 16rpx 0 0;
bottom: 0;
}
&:before,
&:after {
content: '';
position: absolute;
width: 24rpx;
height: 12rpx;
background: #f7f7f7;
left: -14rpx;
z-index: 1;
}
}
}
}
/* 积分抵扣 */
.points {
.title {
margin-right: 5rpx;
}
.icon-help {
font-size: 28rpx;
}
.points-money {
margin-right: 20rpx;
}
}
/* 支付方式 */
.pay-method {
.pay-item {
padding: 20rpx 0;
font-size: 28rpx;
border-bottom: 1rpx solid rgb(248, 248, 248);
.item-left_icon {
margin-right: 20rpx;
font-size: 32rpx;
&.wechat {
color: #00c800;
}
&.balance {
color: #ff9700;
}
}
}
.user-balance {
margin-left: 20rpx;
font-size: 26rpx;
// color: #464646;
}
}
//
.goods-props {
padding-top: 10rpx;
font-size: 24rpx;
color: #999;
.goods-props-item {
float: left;
.group-name {
margin-right: 6rpx;
}
}
}
//
.right-arrow {
margin-left: 16rpx;
// color: #777;
font-size: 26rpx;
}
//
.flow-fixed-footer {
position: fixed;
bottom: var(--window-bottom);
left: var(--window-left);
right: var(--window-right);
// width: 100%;
background: #fff;
border-top: 1px solid #eee;
z-index: 11;
.chackout-left {
font-size: 28rpx;
line-height: 92rpx;
color: #777;
flex: 4;
padding-left: 12px;
}
.chackout-right {
font-size: 34rpx;
flex: 2;
}
//
.flow-btn {
background: linear-gradient(to right, #f9211c, #ff6335);
color: #fff;
text-align: center;
line-height: 92rpx;
display: block;
font-size: 28rpx;
//
&.disabled {
background: #ff9779;
}
}
}
//
.points-content {
padding: 30rpx 48rpx;
font-size: 28rpx;
line-height: 50rpx;
text-align: left;
color: #606266;
height: 620rpx;
box-sizing: border-box;
}
/* 共几件商品 */
.flow-num-box {
font-size: 28rpx;
color: #777;
padding: 16rpx 24rpx;
text-align: right;
}
/* app.scss */
.flow-shopList {
padding: 18rpx 0;
.flow-list-left {
margin-right: 20rpx;
image {
width: 180rpx;
height: 180rpx;
border: 1rpx solid #eee;
background: #fff;
}
}
.flow-list-right {
.flow-cont {
font-size: 28rpx;
color: #fa2209;
}
.small {
font-size: 26rpx;
color: #777;
}
.flow-list-cont {
padding-top: 10rpx;
}
}
}
.flow-all-money {
padding: 0 24rpx;
color: #444;
.flow-all-list {
font-size: 28rpx;
padding: 20rpx 0;
border-bottom: 1rpx solid rgb(248, 248, 248);
}
.flow-all-list:last-child {
border-bottom: none;
}
.flow-all-list-cont {
font-size: 28rpx;
padding: 10rpx 0;
}
.flow-arrow {
justify-content: flex-end;
align-items: center;
}
}

@ -2,14 +2,14 @@
* @Author: ch
* @Date: 2022-03-20 14:14:53
* @LastEditors: ch
* @LastEditTime: 2022-03-31 14:21:15
* @LastEditTime: 2022-04-08 17:33:27
* @Description: file content
-->
<template>
<view>
<u-cell class="address" :title="addres.title" :label="addres.label"
<u-cell class="address" :title="address.province + address.city + address.area" :label="address.name + address.phone"
:border="false" isLink @click="$Router.push('/addressList')">
<image class="address--icon" slot="icon" src="@/static/common/dz.png" />
<image class="address--icon" slot="icon" src="@/static/order/dw.png" />
</u-cell>
<view class="goods-group">
@ -35,7 +35,6 @@
maxlength="50" placeholder="填写您想要备注的信息50字以内" />
</UiCell>
</view>
<view class="play">
<text class="play--title">支付方式</text>
<radio-group>
@ -71,22 +70,28 @@
<script>
import UiCell from '@/components/UiCell';
import {ApiPostSubmitOrder, ApiPostWxPay, ApiGetBeforeOrder} from '@/common/api/order';
import {ApiPostSubmitOrder, ApiPostWxPay, ApiGetBeforeOrder, ApiGetBeforeCartOrder} from '@/common/api/order';
import UiButton from '@/components/UiButton.vue';
export default {
components : {UiCell, UiButton },
data(){
return {
addres : {
title : '选择收货地址',
label : '陈先生 189****6782'
},
address : {},
userMessage : '',
orderInfo : {}
}
},
onLoad(){
this.getBeforeOrder();
//
uni.$on('changeAddress',(item, type)=>{
if(type == 'submitOrder'){
this.address = item;
}
});
//
this.address = this.$store.state.address.find(i => i.isDefault);
},
methods:{
/**
@ -94,22 +99,23 @@ export default {
*/
async getBeforeOrder(){
const query = this.$Route.query;
let apiParams = {};
let res = {};
//
if(query.mode === 'cart'){
apiParams.productIds = query.ids;
res = await ApiGetBeforeCartOrder({cartIds: query.ids})
}
//
if(query.mode === 'buyNow'){
apiParams.productSkuId = parseInt(query.skuId);
apiParams.quantity = query.num;
res = await ApiGetBeforeOrder({
productSkuId : query.skuId,
quantity : query.num
});
}
const {error, result} = await ApiGetBeforeOrder(apiParams);
if(error){
uni.$u.toast(error.message);
if(res.error){
uni.$u.toast(res.error.message);
return false;
}
this.orderInfo = result;
this.orderInfo = res.result;
},
@ -119,8 +125,8 @@ export default {
async submit(){
const {error, result} = await ApiPostSubmitOrder({
orderSource : 2,
recipientAddressId : 1,
products : this.goodsData.map(i => ({
recipientAddressId : this.address.id,
products : this.orderInfo.products.map(i => ({
productId : i.productId,
productSkuId : i.productSkuId,
quantity : i.quantity

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Loading…
Cancel
Save