提交 5728bdc6 authored 作者: 刘旭's avatar 刘旭

完成下单收尾

上级 123cd46e
...@@ -10,4 +10,4 @@ export const cartChecked = (data: any) => request('/wx/cart/checked', 'POST', da ...@@ -10,4 +10,4 @@ export const cartChecked = (data: any) => request('/wx/cart/checked', 'POST', da
export const cartDelete = (data: any) => request('/wx/cart/delete', 'POST', data) export const cartDelete = (data: any) => request('/wx/cart/delete', 'POST', data)
// 更新商品 // 更新商品
export const cartUpdate= (data: any) => request('/wx/cart/update', 'POST', data) export const cartUpdate= (data: any) => request('/wx/cart/update', 'POST', data)
\ No newline at end of file
...@@ -7,4 +7,22 @@ export const homeIndex = () => request('/wx/home/index', 'GET'); ...@@ -7,4 +7,22 @@ export const homeIndex = () => request('/wx/home/index', 'GET');
export const indexDetails = (data: any) => request('/wx/goods/detail', 'GET', data); export const indexDetails = (data: any) => request('/wx/goods/detail', 'GET', data);
// 加入购物车 // 加入购物车
export const addCart = (data: any) => request('/wx/cart/add', 'POST', data) export const addCart = (data: any) => request('/wx/cart/add', 'POST', data)
\ No newline at end of file
// 立即购买
export const fastaddCart = (data: any) => request('/wx/cart/fastadd', 'POST', data)
// 获取购买页面信息,地址,规格
export const checkoutCart = (data: any) => request('/wx/cart/checkout', 'GET', data)
// 地址
export const addressList = () => request('/wx/address/list', 'GET')
// 设置地址
export const cartCheckout = (data: any) => request('/wx/cart/checkout', 'GET', data)
// 提交订单
export const orderSubmit = (data: any) => request('/wx/order/submit', 'POST', data)
// 提交订单详细信息
export const orderDetail = (data: any) => request('/wx/order/detail', 'POST', data)
\ No newline at end of file
import { request } from '@/utils/request' import { request } from '@/utils/request'
// 登录 // 登录
export const login = (data: any) => request('/wx/auth/login', 'POST', data) export const login = (data: any) => request('/wx/auth/login_by_mobile', 'POST', data)
\ No newline at end of file \ No newline at end of file
...@@ -65,6 +65,24 @@ ...@@ -65,6 +65,24 @@
"navigationBarBackgroundColor": "#fff", "navigationBarBackgroundColor": "#fff",
"onReachBottomDistance": 55 "onReachBottomDistance": 55
} }
}, {
"path": "pages/order/checkout",
"style": {
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#fff"
}
}, {
"path": "pages/profile/address",
"style": {
"navigationBarTitleText": "用户地址",
"navigationBarBackgroundColor": "#fff"
}
}, {
"path": "pages/profile/addSite",
"style": {
"navigationBarTitleText": "添加用户地址",
"navigationBarBackgroundColor": "#fff"
}
} }
], ],
"tabBar": { "tabBar": {
......
...@@ -236,6 +236,7 @@ const valChange = (e: any, item: any) => { ...@@ -236,6 +236,7 @@ const valChange = (e: any, item: any) => {
const initCartIndex = () => { const initCartIndex = () => {
toLogin(); toLogin();
getCartIndex().then((res: any) => { getCartIndex().then((res: any) => {
console.log(res);
cartList.value = res.data.data.cartList; cartList.value = res.data.data.cartList;
totalPrice.value = res.data.data.cartTotal.checkedGoodsAmount.toFixed(2); totalPrice.value = res.data.data.cartTotal.checkedGoodsAmount.toFixed(2);
allGoods.value = getAllList(); allGoods.value = getAllList();
......
<template> <template>
<view class="goods-detail"> <view class="goods-detail">
<!-- 轮播图 --> <!-- 轮播图 -->
<view class="wrap"><u-swiper :list="detailData?.info.gallery" img-mode="scaleToFill" height="700"></u-swiper></view> <view class="wrap">
<u-swiper :list="detailData?.info.gallery" img-mode="scaleToFill" height="700"></u-swiper>
</view>
<!-- 商品详情 --> <!-- 商品详情 -->
<view class="goods-info"> <view class="goods-info">
...@@ -32,8 +34,10 @@ ...@@ -32,8 +34,10 @@
</view> </view>
<u-cell-group style="margin-top: 20rpx;"> <u-cell-group style="margin-top: 20rpx;">
<u-cell-item v-if="!selectedGoodsItem.specName" icon="" title="规格" value="请选择" :index="0" @tap="clickGroup"></u-cell-item> <u-cell-item v-if="!selectedGoodsItem.specName" icon="" title="规格" value="请选择" :index="0" @tap="clickGroup">
<u-cell-item v-else icon="" :title="'已选:' + selectedGoodsItem.specName + '*' + selectedGoodsItem.num" :arrow="false" :index="0" @click="clickGroup"></u-cell-item> </u-cell-item>
<u-cell-item v-else icon="" :title="'已选:' + selectedGoodsItem.specName + '*' + selectedGoodsItem.num"
:arrow="false" :index="0" @click="clickGroup"></u-cell-item>
<u-cell-item icon="" title="属性" :index="1" @tap="clickGroup"></u-cell-item> <u-cell-item icon="" title="属性" :index="1" @tap="clickGroup"></u-cell-item>
<u-cell-item icon="" title="运费" value="满88免邮费" :arrow="false" :border-bottom="false"></u-cell-item> <u-cell-item icon="" title="运费" value="满88免邮费" :arrow="false" :border-bottom="false"></u-cell-item>
</u-cell-group> </u-cell-group>
...@@ -53,20 +57,28 @@ ...@@ -53,20 +57,28 @@
</text> </text>
<text class="goods-selected"> <text class="goods-selected">
<text>已选:</text> <text>已选:</text>
<text v-if="selectedGoodsItem.specName">{{ selectedGoodsItem.specName }} * {{ selectedGoodsItem.num }}</text> <text v-if="selectedGoodsItem.specName">{{ selectedGoodsItem.specName }} *
{{ selectedGoodsItem.num }}</text>
</text> </text>
</view> </view>
</view> </view>
<uni-section v-for="item in detailData?.specificationList" :key="item.id" class="mb-10" :title="item.name"> <uni-section v-for="item in detailData?.specificationList" :key="item.id" class="mb-10"
<view class="goods-spec"><uni-data-checkbox mode="tag" :value="radioValue" :localdata="item.valueList" @change="changeColor" /></view> :title="item.name">
<view class="goods-spec">
<uni-data-checkbox mode="tag" :value="item.id" :localdata="item.valueList"
@change="changeColor" />
</view>
</uni-section> </uni-section>
<uni-section class="mb-10" title="数量"> <uni-section class="mb-10" title="数量">
<view class="goods-spec"><uni-number-box :min="1" :max="99" @change="changeBuyNum" /></view> <view class="goods-spec">
<uni-number-box :min="1" :max="99" @change="changeBuyNum" />
</view>
</uni-section> </uni-section>
</view> </view>
<view class="popup-bottom-button"> <view class="popup-bottom-button">
<view v-if="showPopupButton === 0" class="add-to-cart" @click="addToCart"><text>确定</text></view> <view v-if="showPopupButton === 0" class="add-to-cart" @click="addToCart"><text>确定</text>
</view>
<view v-else class="buy-now" @click="buyNow"><text>购买</text></view> <view v-else class="buy-now" @click="buyNow"><text>购买</text></view>
</view> </view>
</uni-popup> </uni-popup>
...@@ -83,17 +95,22 @@ ...@@ -83,17 +95,22 @@
</view> --> </view> -->
<view class="goods-intro"> <view class="goods-intro">
<uni-segmented-control :current="current" :values="tabButtons" @clickItem="onClickItem" styleType="text" activeColor="#e43d33"></uni-segmented-control> <uni-segmented-control :current="current" :values="tabButtons" @clickItem="onClickItem" styleType="text"
activeColor="#e43d33"></uni-segmented-control>
<view class="content"> <view class="content">
<view v-show="current === 0"> <view v-show="current === 0">
<u-parse v-if="detailData?.info.detail" :html="detailData?.info.detail" :show-with-animation="true" lazy-load style="font-size: 0" /> <u-parse v-if="detailData?.info.detail" :html="detailData?.info.detail" :show-with-animation="true"
lazy-load style="font-size: 0" />
<u-empty v-else text="暂无数据" mode="data" /> <u-empty v-else text="暂无数据" mode="data" />
</view> </view>
<view v-show="current === 1">选项卡2的内容</view> <view v-show="current === 1">选项卡2的内容</view>
</view> </view>
</view> </view>
<!-- 提交订单栏 --> <!-- 提交订单栏 -->
<view class="bottom-bar"><uni-goods-nav :fill="true" :options="options" :button-group="buttonGroup" @click="onClick" @buttonClick="buttonClick" /></view> <view class="bottom-bar">
<uni-goods-nav :fill="true" :options="options" :button-group="buttonGroup" @click="onClick"
@buttonClick="buttonClick" />
</view>
<!-- 属性弹窗 --> <!-- 属性弹窗 -->
<u-popup v-model="attrPopup" mode="bottom" height="50%" closeable> <u-popup v-model="attrPopup" mode="bottom" height="50%" closeable>
...@@ -106,487 +123,574 @@ ...@@ -106,487 +123,574 @@
<u-line v-show="detailData?.attribute.length - 1 !== index" /> <u-line v-show="detailData?.attribute.length - 1 !== index" />
</view> </view>
</view> </view>
<view v-else><u-empty text="暂无属性" mode="data" /></view> <view v-else>
<u-empty text="暂无属性" mode="data" />
</view>
</view> </view>
</u-popup> </u-popup>
</view> </view>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import {
import { onLoad } from '@dcloudio/uni-app'; ref
import { indexDetails, addCart } from '@/api/index'; } from 'vue';
import {
const attrPopup = ref(false); onLoad
const detailData = ref(); } from '@dcloudio/uni-app';
const popup = ref(); import {
const tabButtons = ref(['商品详情']); indexDetails,
let current = ref(0); addCart,
fastaddCart
const goodsInfo = ref({ } from '@/api/index';
id: 1, import _ from 'lodash';
title: 'Iphone 13 Pro Max 256G 全网通 国行正品',
price: '5000.00',
star: true, const attrPopup = ref(false);
detail: '<img style="max-width: 100%; height: auto" src="https://bytelibs-dev.oss-cn-beijing.aliyuncs.com/image/goods/detail.png" mode="widthFix"/>', const detailData = ref();
imgList: [ const popup = ref();
{ const tabButtons = ref(['商品详情']);
id: 1, let current = ref(0);
img: `https://bytelibs-dev.oss-cn-beijing.aliyuncs.com/image/goods/goods_1.jpg`
const goodsInfo = ref({
id: 1,
star: true,
});
const selectedGoodsItem = ref({
id: '',
specName: '',
img: '',
price: '',
num: 1
});
const radioValue = ref(selectedGoodsItem.value.id);
const options = ref([{
icon: 'chat',
text: '客服'
}, },
{ {
id: 2, icon: 'shop',
img: 'https://bytelibs-dev.oss-cn-beijing.aliyuncs.com/image/goods/goods_2.jpg' text: '店铺'
}, },
{ {
id: 3, icon: goodsInfo.value.star ? 'star-filled' : 'star',
img: 'https://bytelibs-dev.oss-cn-beijing.aliyuncs.com/image/goods/goods_3.jpg' text: '收藏'
} }
], ]);
spec: [
{ const buttonGroup = ref([{
value: 1, text: '加入购物车',
img: 'https://bytelibs-dev.oss-cn-beijing.aliyuncs.com/image/goods/goods_1.jpg', backgroundColor: 'linear-gradient(90deg, #FFCD1E, #FF8A18)',
text: '石墨色', color: '#fff'
price: '5000.00'
},
{
value: 2,
img: 'https://bytelibs-dev.oss-cn-beijing.aliyuncs.com/image/goods/goods_2.jpg',
text: '远峰蓝',
price: '5100.00'
}, },
{ {
value: 3, text: '立即购买',
img: 'https://bytelibs-dev.oss-cn-beijing.aliyuncs.com/image/goods/goods_3.jpg', backgroundColor: 'linear-gradient(90deg, #FE6035, #EF1224)',
text: '银色', color: '#fff'
price: '5099.00'
} }
] ]);
});
const detailId = ref()
const selectedGoodsItem = ref({
id: '', onLoad((options: any) => {
specName: '', console.log(options);
img: '', detailId.value = options.id
price: '', initDetails(options.id)
num: 1 });
});
// 点击分组
const radioValue = ref(selectedGoodsItem.value.id); const clickGroup = (index: number) => {
switch (index) {
const options = ref([ case 0:
{ popup.value.open('bottom');
icon: 'chat', resetSelected();
text: '客服' break;
}, case 1:
{ attrPopup.value = true;
icon: 'shop', }
text: '店铺' };
},
{ // 添加checkoutbox属性
icon: goodsInfo.value.star ? 'star-filled' : 'star', const specificationList = () => {
text: '收藏' detailData.value?.specificationList.map((item: any, i: number) => {
} item.valueList.map((key: any, k: number) => {
]); if (key.value !== key.id) {
detailData.value!.specificationList[i].valueList[k]['text'] = key.value
const buttonGroup = ref([ detailData.value!.specificationList[i].valueList[k]['value'] = key.id
{ }
text: '加入购物车', })
backgroundColor: 'linear-gradient(90deg, #FFCD1E, #FF8A18)', })
color: '#fff' // detailData.value?.productList.map((item: any, i: number) => {
}, // detailData.value!.productList[i]['text'] = item.specifications[0]
{ // detailData.value!.productList[i]['value'] = item.id
text: '立即购买', // })
backgroundColor: 'linear-gradient(90deg, #FE6035, #EF1224)', // console.log(detailData.value?.productList, '456');
color: '#fff'
}
]);
const detailId = ref()
onLoad((options: any) => {
console.log(options);
detailId.value = options.id
initDetails(options.id)
});
// 点击分组
const clickGroup = (index: number) => {
switch (index) {
case 0:
popup.value.open('bottom');
resetSelected();
break;
case 1:
attrPopup.value = true;
} }
};
const onClick = (e: any) => {
// 添加checkoutbox属性 if (e.index === 0) {
const specificationList = () => { console.log('客服');
detailData.value?.specificationList.map((item: any, i: number) => { }
item.valueList.map((key: any, k: number) => { if (e.index === 1) {
if(key.value !== key.id) { console.log('店铺');
detailData.value!.specificationList[i].valueList[k]['text'] = key.value }
detailData.value!.specificationList[i].valueList[k]['value'] = key.id if (e.index === 2) {
console.log('收藏');
goodsInfo.value.star = !goodsInfo.value.star;
e.content.icon = goodsInfo.value.star ? 'star-filled' : 'star';
let text = '';
text = goodsInfo.value.star ? '已收藏' : '已取消收藏';
uni.showToast({
title: text,
icon: 'none'
});
}
};
/**
* popup中按钮展示状态
*/
const showPopupButton = ref(0);
const buttonClick = (e: any) => {
if (e.index === 0)
showPopupButton.value = 0;
if (e.index === 1)
showPopupButton.value = 1;
openPopup();
};
// 打开规格选择
const openPopup = () => {
popup.value.open('bottom');
resetSelected();
};
// 添加购物车
const addToCart = () => {
if (!selectedGoodsItem.value.specName) return uni.showToast({
title: '请先选择' + detailData.value?.specificationList[0].name,
icon: 'none'
})
let productId: any = getProductIdByOne(selectedGoodsItem.value.id)
console.log(productId, productId);
addCart({
goodsId: detailId.value,
number: selectedGoodsItem.value.num,
productId: productId
}).then((res: any) => {
if (res.data.errno !== 711) {
initDetails(detailId.value)
popup.value.close();
uni.showToast({
title: '已添加至购物车',
icon: 'none'
});
} else {
uni.showToast({
title: res.data.errmsg,
icon: 'none'
});
} }
}) })
}) };
}
const onClick = (e: any) => { // 立即购买
if (e.index === 0) { const buyNow = () => {
console.log('客服'); if (!selectedGoodsItem.value.specName) return uni.showToast({
} title: '请先选择' + detailData.value?.specificationList[0].name,
if (e.index === 1) {
console.log('店铺');
}
if (e.index === 2) {
console.log('收藏');
goodsInfo.value.star = !goodsInfo.value.star;
e.content.icon = goodsInfo.value.star ? 'star-filled' : 'star';
let text = '';
text = goodsInfo.value.star ? '已收藏' : '已取消收藏';
uni.showToast({
title: text,
icon: 'none' icon: 'none'
})
let productId: any = getProductIdByOne(selectedGoodsItem.value.id)
let data: object = {
goodsId: Number(detailId.value),
number: selectedGoodsItem.value.num,
productId: productId
}
fastaddCart(data).then((res: any) => {
if (res.data.errno !== 711) {
uni.navigateTo({
url: `../order/checkout`,
success() {
uni.setStorage({
data: res.data.data,
key: 'buyNowId'
})
if(!uni.getStorageSync('addressId')) {
uni.setStorage({
key: 'addressId',
data: 0
})
}
let storage: any = {
cartId: 0,
couponId: 0,
userCouponId: 0,
grouponRulesId: 0
}
Object.keys(storage).forEach((prop: any) => {
const el: any = storage[prop];
uni.setStorage({
key: prop,
data: el
})
});
popup.value.close();
}
})
} else {
uni.showToast({
title: res.data.errmsg,
icon: 'none'
});
}
console.log(res);
})
};
// 初始产品规格数据
const resetSelected = () => {
specificationList()
selectedGoodsItem.value.id = detailData.value?.id;
selectedGoodsItem.value.img = detailData.value?.productList[0].url;
selectedGoodsItem.value.price = detailData.value?.productList[0].price;
selectedGoodsItem.value.specName = '';
selectedGoodsItem.value.num = 1;
radioValue.value = detailData.value?.specificationList[0].valueList[0].value;
};
// 修改商品规格
const changeColor = (e: any) => {
const selected = e.detail.data;
console.log('选择产品规格', selected);
selectedGoodsItem.value.id = selected.id;
selectedGoodsItem.value.img = selected.picUrl;
selectedGoodsItem.value.price = detailData.value?.productList[0].price;
selectedGoodsItem.value.specName = selected.text;
};
// 购买数量
const changeBuyNum = (value: number) => {
selectedGoodsItem.value.num = value;
};
// 选择选项卡
const onClickItem = (e: any) => {
if (current.value != e.currentIndex) {
current.value = e.currentIndex;
}
};
// 初始化商品详情数据
const initDetails = (id: number) => {
indexDetails({
id
}).then((res: any) => {
if (res.data.code === 200) {}
// 去除数据 换行符
for (let s in res.data.data?.attribute) {
const value = res.data.data?.attribute[s].value.split('\n')
if (value.length > 1) {
let str: string = ''
value.forEach((item: string) => {
str += ' ' + item
})
res.data.data!.attribute[s].value = str
}
}
detailData.value = res.data.data;
console.log(detailData.value, '商品详情数据');
}); });
} }
};
/** const getProductIdByOne = (s1: any) => {
* popup中按钮展示状态 console.log(s1);
*/ let productId;
const showPopupButton = ref(0); let s1Name: string;
_.each(detailData.value?.specificationList, (specification: any) => {
const buttonClick = (e: any) => { _.each(specification.valueList, (specValue: any) => {
if (e.index === 0) { if (specValue.id === s1) {
console.log('加入购物车'); s1Name = specValue.text;
showPopupButton.value = 0; return;
} }
if (e.index === 1) { });
console.log('立即购买'); });
showPopupButton.value = 1;
}
openPopup();
};
// 打开规格选择
const openPopup = () => {
popup.value.open('bottom');
resetSelected();
};
// 添加购物车
const addToCart = () => {
console.log('添加至购物车', selectedGoodsItem.value);
initDetails(detailId.value)
popup.value.close();
uni.showToast({
title: '已添加至购物车',
icon: 'success'
});
};
// 立即购买
const buyNow = () => {
console.log('立即购买', selectedGoodsItem.value);
popup.value.close();
};
// 初始产品规格数据
const resetSelected = () => {
specificationList()
selectedGoodsItem.value.id = detailData.value?.id;
selectedGoodsItem.value.img = detailData.value?.productList[0].url;
selectedGoodsItem.value.price = detailData.value?.productList[0].price;
selectedGoodsItem.value.specName = '';
selectedGoodsItem.value.num = 1;
radioValue.value = detailData.value?.specificationList[0].valueList[0].value;
};
// 修改商品规格
const changeColor = (e: any) => {
const selected = e.detail.data;
console.log('选择产品规格', selected);
selectedGoodsItem.value.id = selected.id;
selectedGoodsItem.value.img = selected.picUrl;
selectedGoodsItem.value.price = detailData.value?.productList[0].price;
selectedGoodsItem.value.specName = selected.text;
};
// 购买数量
const changeBuyNum = (value: number) => {
selectedGoodsItem.value.num = value;
};
// 选择选项卡
const onClickItem = (e: any) => {
if (current.value != e.currentIndex) {
current.value = e.currentIndex;
}
};
// 初始化商品详情数据 _.each(detailData.value?.productList, (v: any) => {
const initDetails = (id: number) => { let result = _.without(v.specifications, s1Name);
indexDetails({ id }).then((res: any) => { if (result.length === 0) {
if (res.data.code === 200) { productId = v.id;
}
// 去除数据 换行符
for (let s in res.data.data?.attribute) {
const value = res.data.data?.attribute[s].value.split('\n')
if(value.length > 1) {
let str: string = ''
value.forEach((item: string) => {
str += ' ' + item
})
res.data.data!.attribute[s].value = str
} }
} });
detailData.value = res.data.data; return productId;
console.log(detailData.value, '商品详情数据'); }
});
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.goods-detail { .goods-detail {
//height: 800rpx; //height: 800rpx;
//background-color: #FFFFFF; //background-color: #FFFFFF;
.goods-img {
.swiper {
height: 600rpx;
.swiper-item { .goods-img {
display: block; .swiper {
height: 100%; height: 600rpx;
line-height: 600rpx;
text-align: center;
.banner { .swiper-item {
width: 100%; display: block;
height: 100%; height: 100%;
line-height: 600rpx;
text-align: center;
.banner {
width: 100%;
height: 100%;
}
} }
} }
} }
}
.goods-info { .goods-info {
//height: 200rpx; //height: 200rpx;
background-color: #ffffff; background-color: #ffffff;
padding: 20rpx 30rpx; padding: 20rpx 30rpx;
font-family: arial, sans-serif; font-family: arial, sans-serif;
border-bottom-left-radius: 30rpx; border-bottom-left-radius: 30rpx;
border-bottom-right-radius: 30rpx; border-bottom-right-radius: 30rpx;
.goods-title {
font-size: 16px;
font-weight: bold;
display: -webkit-box;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.goods-sub {
font-size: 12px;
color: #ccc;
display: -webkit-box;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.goods-price {
color: #dd524d;
//position: absolute;
font-size: 40rpx;
display: flex;
.unit { .goods-title {
// font-size: 10px; font-size: 16px;
font-weight: bold;
display: -webkit-box;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
} }
.price { .goods-sub {
// font-size: 16px; font-size: 12px;
font-weight: bold; color: #ccc;
display: -webkit-box;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
} }
}
.goods-cost-price { .goods-price {
color: #ccc; color: #dd524d;
text-decoration: line-through;
font-size: 24rpx;
margin-left: 10rpx;
}
}
.cell-group {
margin-top: 20rpx;
border-radius: 30rpx;
}
.goods-detail-item {
margin-top: 20rpx;
background-color: #ffffff;
// padding: 20rpx 30rpx;
font-size: 30rpx;
font-family: arial, sans-serif;
color: rgb(192, 192, 192);
// border-radius: 30rpx;
.popup-selected-spec {
height: 800rpx;
//background-color: #FFFFFF;
.goods-item {
padding: 40rpx;
display: flex;
border-bottom: 1px solid #ebeef5;
//position: absolute; //position: absolute;
.goods-mini-img { font-size: 40rpx;
width: 100rpx; display: flex;
height: 100rpx;
border-radius: 10rpx; .unit {
//border: 2rpx soild black; // font-size: 10px;
}
.price {
// font-size: 16px;
font-weight: bold;
} }
}
.goods-text { .goods-cost-price {
margin-top: 10rpx; color: #ccc;
margin-left: 50rpx; text-decoration: line-through;
.goods-price { font-size: 24rpx;
color: #dd524d; margin-left: 10rpx;
display: flex; }
.unit { }
font-size: 10px;
.cell-group {
margin-top: 20rpx;
border-radius: 30rpx;
}
.goods-detail-item {
margin-top: 20rpx;
background-color: #ffffff;
// padding: 20rpx 30rpx;
font-size: 30rpx;
font-family: arial, sans-serif;
color: rgb(192, 192, 192);
// border-radius: 30rpx;
.popup-selected-spec {
height: 800rpx;
//background-color: #FFFFFF;
.goods-item {
padding: 40rpx;
display: flex;
border-bottom: 1px solid #ebeef5;
//position: absolute;
.goods-mini-img {
width: 100rpx;
height: 100rpx;
border-radius: 10rpx;
//border: 2rpx soild black;
}
.goods-text {
margin-top: 10rpx;
margin-left: 50rpx;
.goods-price {
color: #dd524d;
display: flex;
.unit {
font-size: 10px;
}
.price {
font-size: 16px;
font-weight: bold;
}
} }
.price {
font-size: 16px; .goods-selected {
font-weight: bold; margin-top: 20rpx;
display: flex;
} }
} }
.goods-selected { }
margin-top: 20rpx;
display: flex; .goods-spec {
} margin-left: 30rpx;
} }
} }
.goods-spec {
margin-left: 30rpx; .popup-bottom-button {
height: 80rpx;
display: flex;
flex: 1;
color: rgb(255, 255, 255);
.add-to-cart {
display: flex;
flex: 1;
margin: 0 30rpx 0 50rpx;
justify-content: center;
align-items: center;
overflow: hidden;
border-radius: 50rpx;
background: linear-gradient(90deg, rgb(255, 205, 30), rgb(255, 138, 24));
}
.buy-now {
display: flex;
flex: 1;
margin: 0 50rpx 0 30rpx;
justify-content: center;
align-items: center;
overflow: hidden;
border-radius: 50rpx;
background: linear-gradient(90deg, rgb(254, 96, 53), rgb(239, 18, 36));
}
} }
} }
.popup-bottom-button {
height: 80rpx; .shop-info {
height: 160rpx;
background-color: #ffffff;
margin-top: 20rpx;
border-radius: 30rpx;
display: flex; display: flex;
flex: 1;
color: rgb(255, 255, 255); .shop-logo-box {
.add-to-cart { padding: 30rpx;
display: flex; height: 100rpx;
flex: 1; width: 100rpx;
margin: 0 30rpx 0 50rpx; border-radius: 10rpx;
justify-content: center;
align-items: center;
overflow: hidden; overflow: hidden;
border-radius: 50rpx;
background: linear-gradient(90deg, rgb(255, 205, 30), rgb(255, 138, 24)); .shop-logo {
width: 100%;
height: 100%;
object-fit: cover;
}
} }
.buy-now {
display: flex; .shop-desc {
flex: 1; flex: 1;
margin: 0 50rpx 0 30rpx;
justify-content: center;
align-items: center;
overflow: hidden;
border-radius: 50rpx;
background: linear-gradient(90deg, rgb(254, 96, 53), rgb(239, 18, 36));
}
}
}
.shop-info { .shop-name {
height: 160rpx; font-weight: bold;
background-color: #ffffff; font-family: 'Helvetica Neue', Helvetica, sans-serif;
margin-top: 20rpx; line-height: 160rpx;
border-radius: 30rpx; }
display: flex;
.shop-logo-box {
padding: 30rpx;
height: 100rpx;
width: 100rpx;
border-radius: 10rpx;
overflow: hidden;
.shop-logo {
width: 100%;
height: 100%;
object-fit: cover;
} }
}
.shop-desc { .shop-enter-button {
flex: 1;
.shop-name {
font-weight: bold;
font-family: 'Helvetica Neue', Helvetica, sans-serif;
line-height: 160rpx; line-height: 160rpx;
padding-right: 30rpx;
text {
color: rgb(255, 138, 24);
font-size: 24rpx;
padding: 5rpx 15rpx;
border: 1rpx solid rgb(254, 96, 53);
border-radius: 10rpx;
}
} }
} }
.shop-enter-button {
line-height: 160rpx; .goods-intro {
padding-right: 30rpx; //height: 160rpx;
text { background-color: #ffffff;
color: rgb(255, 138, 24); margin-top: 20rpx;
font-size: 24rpx; border-radius: 30rpx;
padding: 5rpx 15rpx;
border: 1rpx solid rgb(254, 96, 53); .content {
border-radius: 10rpx; width: 100%;
margin-top: 30rpx;
margin-bottom: calc(100rpx + env(safe-area-inset-bottom));
display: inline-block;
} }
} }
}
.goods-intro {
//height: 160rpx;
background-color: #ffffff;
margin-top: 20rpx;
border-radius: 30rpx;
.content { .bottom-bar {
width: 100%; display: flex;
margin-top: 30rpx; flex-direction: column;
margin-bottom: calc(100rpx + env(safe-area-inset-bottom)); position: fixed;
display: inline-block; left: var(--window-left);
right: var(--window-right);
bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
background-color: #ffffff;
padding-bottom: env(safe-area-inset-bottom);
} }
} }
.bottom-bar { .attr-content {
display: flex; padding: 32rpx 40rpx;
flex-direction: column;
position: fixed;
left: var(--window-left);
right: var(--window-right);
bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
background-color: #ffffff;
padding-bottom: env(safe-area-inset-bottom);
}
}
.attr-content { .title {
padding: 32rpx 40rpx; text-align: center;
.title { margin-bottom: 100rpx;
text-align: center;
margin-bottom: 100rpx;
}
.details {
width: 100%;
font-size: 14px;
.left {
display: inline-block;
width: 40%;
padding: 20rpx 0;
} }
.right {
padding: 20rpx 0; .details {
width: 100%;
font-size: 14px;
.left {
display: inline-block;
width: 40%;
padding: 20rpx 0;
}
.right {
padding: 20rpx 0;
}
} }
} }
}
</style> </style>
...@@ -20,7 +20,7 @@ import { reactive } from 'vue'; ...@@ -20,7 +20,7 @@ import { reactive } from 'vue';
import { login } from '@/api/login'; import { login } from '@/api/login';
import inputLogin from '@/components/inputLogin.vue'; import inputLogin from '@/components/inputLogin.vue';
let inputData = reactive({ let inputData = reactive({
inputValue: 'user123' as any, inputValue: '15616168157' as any,
iconfont: 'icon-a-ziyuan16', iconfont: 'icon-a-ziyuan16',
placeholder: '手机号码', placeholder: '手机号码',
type: 'text', type: 'text',
...@@ -63,8 +63,8 @@ let clickNextStep = () => { ...@@ -63,8 +63,8 @@ let clickNextStep = () => {
}; };
// user123 // user123
let initLogin = async (username: number, password: string) => { let initLogin = async (mobile: number, password: string) => {
let res: any = await login({ username, password }); let res: any = await login({ mobile, password });
if (res.data.errno == 0) { if (res.data.errno == 0) {
uni.setStorage({ uni.setStorage({
key: 'token', key: 'token',
...@@ -74,7 +74,7 @@ let initLogin = async (username: number, password: string) => { ...@@ -74,7 +74,7 @@ let initLogin = async (username: number, password: string) => {
url: '../profile/index', url: '../profile/index',
success() { success() {
uni.setStorage({ uni.setStorage({
key: 'username', key: 'mobile',
data: inputData.inputValue, data: inputData.inputValue,
success() { success() {
uni.showToast({ uni.showToast({
......
<template>
<view class="container">
<!-- 收货地址 -->
<view class="address" @tap="tapAddresss">
<view class="top">
<text>收货地址</text>
<u-icon name="arrow-right"></u-icon>
</view>
<view class="bottom">
<view class="">
<text style="margin-right: 10rpx;">{{ buyNowData?.checkedAddress.name }}</text>
<text>{{ buyNowData?.checkedAddress.tel }}</text>
</view>
<text>{{ buyNowData?.checkedAddress.addressDetail }}</text>
</view>
</view>
<!-- 商品详情 -->
<view v-for="(item, index) in buyNowData?.checkedGoodsList" class="details">
<u-image width="140rpx" height="200rpx" :src="item.picUrl" class="img"></u-image>
<view class="right">
<view class="name">
{{ item.goodsName }}
</view>
<view class="tag" v-for="(item1, index1) in item.specifications.length" :key="index1">
<u-tag :text="item.specifications[index1]" type="info" size="mini" style="margin-right: 2rpx;" />
</view>
<view class="sum-price">
<text>{{ item.price.toFixed(2) }}</text>
<text style="color: #969799; font-size: 12px;">x{{ item.number }}</text>
</view>
</view>
</view>
<!-- list -->
<view class="list">
<view class="item-list">
<view class="label">商品金额</view>
<view class="item-price">{{ buyNowData?.goodsTotalPrice.toFixed(2) }}</view>
</view>
<view class="item-list">
<view class="label">邮费</view>
<view class="item-price">{{ buyNowData?.freightPrice.toFixed(2) }}</view>
</view>
<!-- <view class="item-list">
<view class="label">优惠券</view>
<view class="item-price">¥12</view>
</view> -->
<view class="item-list-end">
<view class="label">订单备注</view>
<u-input v-model="remarks" />
</view>
</view>
<!-- 提交订单 -->
<view class="footer">
<view>
<text style="font-size: 30rpx;">总计</text>
<text
style="margin-right: 24rpx; color: #ee0a24; font-size: 30rpx; font-weight: 600;">{{ buyNowData?.orderTotalPrice.toFixed(2) }}</text>
<u-button type="error" size="medium" shape="circle" @tap="onsubmit">结算</u-button>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import {
onLoad,
onShow
} from '@dcloudio/uni-app';
import {
ref
} from 'vue'
import {
checkoutCart,
orderDetail,
orderSubmit
} from '@/api/index'
const buyNowId = ref(uni.getStorageSync('buyNowId'))
const buyNowData = ref()
const remarks = ref() // 订单备注
// onLoad(() => {
// initCheckoutCart(buyNowId.value)
// })
// 设置地址
const tapAddresss = () => {
uni.navigateTo({
url: `../profile/address?cartId=${buyNowId.value}`
})
}
// 结算
const onsubmit = () => {
let data: object = {
addressId: uni.getStorageSync('addressId'),
cartId: uni.getStorageSync('cartId'),
couponId: uni.getStorageSync('couponId'),
grouponLinkId: 0,
grouponRulesId: uni.getStorageSync('grouponRulesId'),
message: remarks.value,
userCouponId: 0
}
// 提交订单
orderSubmit(data).then((res: any) => {
console.log(res);
orderDetail({
orderId: res.data.data.orderId
}).then((res1: any) => {
console.log(res1, '订单详情信息');
uni.switchTab({
url: '../profile/index'
})
})
})
}
// 初始化数据
const initCheckoutCart = (cartId: number) => {
let couponId = uni.getStorageSync('couponId')
let userCouponId = uni.getStorageSync('userCouponId')
let grouponRulesId = uni.getStorageSync('grouponRulesId')
let addressId = uni.getStorageSync('addressId')
checkoutCart({
cartId,
couponId,
userCouponId,
grouponRulesId,
addressId
}).then((res: any) => {
buyNowData.value = res.data.data
let storage: any = {
addressId: res.data.data.addressId,
cartId: res.data.data.cartId,
couponId: res.data.data.couponId,
userCouponId: res.data.data.userCouponId,
grouponRulesId: res.data.data.grouponRulesId
}
Object.keys(storage).forEach((prop: any) => {
const el: any = storage[prop];
uni.setStorage({
key: prop,
data: el
})
});
console.log(buyNowData.value, '购买数据');
})
}
onShow(() => {
initCheckoutCart(buyNowId.value)
})
</script>
<style lang="scss" scoped>
.container {
.address {
width: 100%;
padding: 20rpx 32rpx;
border-top: 2rpx solid #e8e8e8;
background-color: #fff;
margin-bottom: 20rpx;
.top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
}
.bottom {
font-size: 24rpx;
color: #969799;
line-height: 36rpx;
}
}
.details {
width: 100%;
padding: 16rpx 32rpx;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
background-color: #fff;
.img {
margin-right: 20rpx;
}
.tag {
margin-top: 1%;
margin-bottom: 13%;
}
.right {
width: 80%;
.sum-price {
display: flex;
justify-content: space-between;
}
}
}
.list {
width: 100%;
display: flex;
background-color: #fff;
flex-direction: column;
.item-list {
width: 100%;
padding: 20rpx 32rpx;
display: flex;
justify-content: space-between;
.label {
width: 30%;
}
.item-price {
color: #db3d3c;
}
}
.item-list-end {
padding: 20rpx 32rpx;
display: flex;
justify-content: flex-start;
flex-direction: row;
align-items: center;
.label {
width: 30%;
}
}
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
height: 100rpx;
background-color: #fff;
display: flex;
justify-content: flex-end;
align-items: center;
padding: 0 32rpx;
}
}
</style>
<template>
<view class="wrap">
<view class="top">
<view class="item">
<view class="left">收货人</view>
<input type="text" placeholder-class="line" placeholder="请填写收货人姓名" />
</view>
<view class="item">
<view class="left">手机号码</view>
<input type="text" placeholder-class="line" placeholder="请填写收货人手机号" />
</view>
<view class="item" @tap="showRegionPicker">
<view class="left">所在地区</view>
<input disabled type="text" placeholder-class="line" placeholder="省市区县、乡镇等" />
</view>
<view class="item address">
<view class="left">详细地址</view>
<textarea type="text" placeholder-class="line" placeholder="街道、楼牌等" />
</view>
<!-- <view class="site-clipboard">
<textarea placeholder-class="line" value="" placeholder="粘贴文本,可自动识别姓名和地址等" />
<view class="clipboard">
地址粘贴板
<u-icon name="arrow-down" class="icon" :size="20"></u-icon>
</view>
</view> -->
</view>
<view class="bottom">
<view class="tag">
<view class="left">标签</view>
<view class="right">
<text class="tags"></text>
<text class="tags">公司</text>
<text class="tags">学校</text>
<view class="tags plus">
<u-icon size="22" name="plus"></u-icon>
</view>
</view>
</view>
<view class="default">
<view class="left">
<view class="set">设置默认地址</view>
<view class="tips">提醒:每次下单会默认推荐该地址</view>
</view>
<view class="right">
<switch color="red" @change="setDefault" />
</view>
</view>
</view>
<u-picker mode="region" ref="uPicker" v-model="show" />
</view>
</template>
<script setup lang="ts">
import {
ref
} from 'vue'
import { cartCheckout } from '@/api/index'
const show = ref(false)
const setDefault = () => {}
const showRegionPicker = () => {
show.value = true;
}
</script>
<style lang="scss" scoped>
::v-deep .line {
color: $u-light-color;
font-size: 28rpx;
}
.wrap {
background-color: #f2f2f2;
.top {
background-color: #ffffff;
border-top: solid 2rpx $u-border-color;
padding: 22rpx;
.item {
display: flex;
font-size: 32rpx;
line-height: 100rpx;
align-items: center;
border-bottom: solid 2rpx $u-border-color;
.left {
width: 180rpx;
}
input {
text-align: left;
}
}
.address {
padding: 20rpx 0;
textarea {
// width: 100%;
height: 150rpx;
background-color: #f7f7f7;
line-height: 60rpx;
margin: 40rpx auto;
padding: 20rpx;
}
}
.site-clipboard {
padding-right: 40rpx;
textarea {
// width: 100%;
height: 150rpx;
background-color: #f7f7f7;
line-height: 60rpx;
margin: 40rpx auto;
padding: 20rpx;
}
.clipboard {
display: flex;
justify-content: center;
align-items: center;
font-size: 26rpx;
color: $u-tips-color;
height: 80rpx;
.icon {
margin-top: 6rpx;
margin-left: 10rpx;
}
}
}
}
.bottom {
margin-top: 20rpx;
padding: 40rpx;
padding-right: 0;
background-color: #ffffff;
font-size: 28rpx;
.tag {
display: flex;
.left {
width: 160rpx;
}
.right {
display: flex;
flex-wrap: wrap;
.tags {
width: 140rpx;
padding: 16rpx 8rpx;
border: solid 2rpx $u-border-color;
text-align: center;
border-radius: 50rpx;
margin: 0 10rpx 20rpx;
display: flex;
font-size: 28rpx;
align-items: center;
justify-content: center;
color: $u-content-color;
line-height: 1;
}
.plus {
//padding: 10rpx 0;
}
}
}
.default {
margin-top: 50rpx;
display: flex;
justify-content: space-between;
border-bottom: solid 2rpx $u-border-color;
line-height: 64rpx;
.tips {
font-size: 24rpx;
}
.right {}
}
}
}
</style>
<template> <template>
<view>
<view class="item" v-for="(res, index) in siteList" :key="res.id" @tap="setAddress(res.id)">
<view class="top">
<view class="name">{{ res.name }}</view>
<view class="phone">{{ res.tel }}</view>
<!-- <view class="tag">
<text v-for="(item, index) in res.tag" :key="index" :class="{red:item.tagText=='默认'}">{{ item.tagText }}</text>
</view> -->
</view>
<view class="bottom">
{{ res.province + res.city + res.county + res.addressDetail }}
<!-- <u-icon name="edit-pen" :size="40" color="#999999"></u-icon> -->
</view>
</view>
<view class="addSite" @tap="toAddSite">
<view class="add">
<u-icon name="plus" color="#ffffff" class="icon" :size="30"></u-icon>新建收货地址
</view>
</view>
</view>
</template> </template>
<script> <script setup lang="ts">
import {
onLoad
} from '@dcloudio/uni-app';
import {
ref
} from 'vue'
import {
addressList,
cartCheckout
} from '@/api/index'
const siteList = ref([] as any)
const cartId = ref()
onLoad((options: any) => {
cartId.value = JSON.parse(options.cartId)
console.log(cartId.value);
})
// 新增地址
const toAddSite = () => {
uni.navigateTo({
url: './addSite'
});
}
// 设置地址
const setAddress = (id: any) => {
if(uni.getStorageSync('123')) {
console.log('有');
} else {
console.log('无');
}
setTimeout(() => {
uni.setStorage({
key: 'addressId',
data: id
})
uni.navigateBack({
delta: 1
})
}, 50);
}
const getData = () => {
siteList.value = [{
id: 1,
tag: [{
tagText: '默认'
},
{
tagText: '家'
}
],
site: '广东省深圳市宝安区 自由路66号'
}];
}
const initAddressLit = () => {
addressList().then((res: any) => {
siteList.value = res.data.data.list
})
}
initAddressLit()
</script> </script>
<style>
</style> <style lang="scss" scoped>
\ No newline at end of file page {
background-color: #fff;
padding: 0 20rpx;
}
.item {
padding: 40rpx 20rpx;
.top {
display: flex;
font-weight: bold;
font-size: 34rpx;
.phone {
margin-left: 60rpx;
}
.tag {
display: flex;
font-weight: normal;
align-items: center;
text {
display: block;
width: 60rpx;
height: 34rpx;
line-height: 34rpx;
color: #ffffff;
font-size: 20rpx;
border-radius: 6rpx;
text-align: center;
margin-left: 30rpx;
background-color: rgb(49, 145, 253);
}
.red {
background-color: red
}
}
}
.bottom {
display: flex;
margin-top: 20rpx;
font-size: 28rpx;
justify-content: space-between;
color: #999999;
}
}
.addSite {
position: fixed;
bottom: 30rpx;
left: 80rpx;
display: flex;
justify-content: space-around;
width: 600rpx;
line-height: 100rpx;
// position: absolute;
background-color: red;
border-radius: 60rpx;
font-size: 30rpx;
.add {
display: flex;
align-items: center;
color: #ffffff;
.icon {
margin-right: 10rpx;
}
}
}
</style>
...@@ -2,10 +2,10 @@ const CONFIG: any = { ...@@ -2,10 +2,10 @@ const CONFIG: any = {
// 开发环境配置 // 开发环境配置
development: { development: {
assetsPath: 'http://192.168.2.210:8080', // 静态资源路径 assetsPath: 'http://192.168.2.210:8080', // 静态资源路径
baseUrl: 'http://193.112.67.73:81', // 后台接口请求地址 baseUrl: 'http://192.168.0.23:80', // 后台接口请求地址
hostUrl: 'http://192.168.2.210:8080', // H5地址(前端运行地址) hostUrl: 'http://192.168.2.210:8080', // H5地址(前端运行地址)
websocketUrl: '', // websocket服务端地址 websocketUrl: '', // websocket服务端地址
}, },
// 生产环境配置 // 生产环境配置
production: { production: {
assetsPath: 'https://m.siccat.com/public/static/images/', // 静态资源路径 assetsPath: 'https://m.siccat.com/public/static/images/', // 静态资源路径
......
import config from './config'; import config from './config';
import { nextTick } from 'vue';
const baseUrl = config.baseUrl; const baseUrl = config.baseUrl;
// 封装公共申请办法 // 封装公共申请办法
...@@ -8,10 +9,10 @@ function request(url: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', data?: ...@@ -8,10 +9,10 @@ function request(url: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', data?:
if (uni.getStorageSync('token') !== undefined && uni.getStorageSync('token') !== '') { if (uni.getStorageSync('token') !== undefined && uni.getStorageSync('token') !== '') {
header = { header = {
'content-type': 'application/json', 'content-type': 'application/json',
'X-Litemall-Token': uni.getStorageSync('token') 'X-Litemall-Token': uni.getStorageSync('token'),
}; };
} else { } else {
let pages = getCurrentPages(); let pages = getCurrentPages();
let curRoute = pages[pages.length - 1].route; let curRoute = pages[pages.length - 1].route;
// if (curRoute != 'pages/login/login') { // if (curRoute != 'pages/login/login') {
// uni.showToast({ // uni.showToast({
...@@ -32,13 +33,30 @@ function request(url: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', data?: ...@@ -32,13 +33,30 @@ function request(url: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', data?:
header: header, header: header,
success(res: any) { success(res: any) {
uni.hideLoading(); uni.hideLoading();
if (res.statusCode == 200) { if (res.data.code == 200) {
resolve(res); resolve(res);
} else if (res.data.code == 501) {
console.log(res);
nextTick(() => {
uni.reLaunch({
url: '/pages/login/login',
success() {
uni.showToast({
title: res.data.msg,
icon: 'none',
});
},
fail(err) {
console.log(err);
}
});
});
} else { } else {
console.log(res);
//其余异样 //其余异样
uni.showToast({ uni.showToast({
title: res.data.errmsg, title: res.data.error,
icon: 'none' icon: 'none',
}); });
reject(res); reject(res);
} }
...@@ -48,10 +66,10 @@ function request(url: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', data?: ...@@ -48,10 +66,10 @@ function request(url: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', data?:
//申请失败 //申请失败
uni.showToast({ uni.showToast({
title: '连接服务器失败', title: '连接服务器失败',
icon: 'none' icon: 'none',
}); });
reject(err); reject(err);
} },
}); });
}); });
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论