接入购物车/确认订单/地址管理等api

This commit is contained in:
邝军华 2025-04-07 17:42:17 +08:00
parent 933e20c695
commit 61e58411db
56 changed files with 2045 additions and 715 deletions

View File

@ -9,7 +9,7 @@
</view>
<view class="shop_comment_cont">
<view class="shop_comment_cont_ul">
<view class="shop_comment_cont_l">
<view class="shop_comment_cont_l" v-if="productReply.nickname">
<image class="shop_comment_cont_userimg" :src="productReply.avatar" mode="widthFix"></image>
<view class="shop_comment_cont_username">{{productReply.nickname}}</view>
<view class="shop_comment_cont_amount">

View File

@ -0,0 +1,134 @@
<template>
<view class="location_view" v-if="locationShow" :style="{'top':headerHeight+38+'px'}">
<view class="location_arrows"></view>
<view class="location_content">
<view class="location_close" @click="close()">
<image class="location_close_img" src="../../static/close.png" mode="widthFix"></image>
</view>
<view class="location_text">为了更准确定位附近门店建议您</view>
<view class="location_btn" @click="handleGetLocation()">开启定位</view>
</view>
</view>
</template>
<script setup>
import { computed,ref,onMounted } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { frontstorelist } from '@/server/api';
const counterStore = useCounterStore(); // 使 Store
//使piniastoreToRefs(使)
const { headerHeight,locationShow,storeName,storeId,latitude,longitude,locationName } = storeToRefs(counterStore);
const close = () => {
locationShow.value = false
}
const handleGetLocation = () => {
// 1.
uni.getSetting({
success: (res) => {
if (res.authSetting['scope.userLocation']) {
//
getLocation();
} else {
//
uni.authorize({
scope: 'scope.userLocation',
success: () => getLocation(),
fail: () => showAuthGuide()
});
}
}
});
};
//
const getLocation = () => {
uni.getLocation({
type: 'gcj02', // gcj02
success: (res) => {
if(!storeName.value){
locationShow.value = false;
const params = {latitude:res.latitude,longitude:res.longitude,page:1,limit:1}
return frontstorelist(params).then(({data}) => {
storeName.value = data.list[0].name;
storeId.value = data.list[0].id;
latitude.value = res.latitude;
longitude.value = res.longitude;
})
}
},
fail: (err) => {
storeName.value = '';
storeId.value = '';
latitude.value = '';
longitude.value = '';
locationName.value = "未获取到定位"
locationShow.value = true
}
});
};
//
const showAuthGuide = () => {
uni.showModal({
title: '提示',
content: '需要位置权限才能使用该功能,是否去设置?',
success: (res) => {
if (res.confirm) {
uni.openSetting(); //
}
}
});
};
//
onMounted(() => {});
onShow(() => {
getLocation();
});
</script>
<style lang="scss">
.location_view{
position: fixed;
left: 10px;
z-index: 99;
.location_arrows{
margin-left: 40rpx;
width: 0;
height: 0;
border-left: 18rpx solid transparent;
border-right: 18rpx solid transparent;
border-bottom: 18rpx solid rgba(0, 0, 0, 0.70);
}
.location_content{
background-color: rgba(0, 0, 0, 0.70);
border-radius: 20rpx;
padding: 15rpx;
display: flex;
align-items: center;
justify-content:space-around;
.location_close{
width: 50rpx;
height: 50rpx;
display: flex;
align-items: center;
justify-content: center;
.location_close_img{
width: 35rpx;
height: 35rpx;
}
}
.location_text{
font-size: 24rpx;
color: #FFFFFF;
margin-right: 20rpx;
}
.location_btn{
background-color: #D9D9D9;
border-radius: 30rpx;
font-size: 24rpx;
color: #000000;
padding: 8rpx 20rpx 8rpx 20rpx;
}
}
}
</style>

View File

@ -19,7 +19,7 @@
</view>
<view class="shop_view_li" v-if="item.type == 0" @click="JumpType(item.id,1)">
<view class="shop_view_img">
<view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view>
<!-- <view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view> -->
<view class="shop_view_img_u">
<image class="shop_view_img_url" :src="item.image" mode="widthFix" lazy-load="true"></image>
</view>
@ -54,7 +54,7 @@
</view>
<view class="shop_view_li" v-if="item.type == 0" @click="JumpType(item.id,1)">
<view class="shop_view_img">
<view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view>
<!-- <view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view> -->
<view class="shop_view_img_u">
<image class="shop_view_img_url" :src="item.image" mode="widthFix" lazy-load="true"></image>
</view>
@ -83,11 +83,13 @@
</template>
<script setup>
import { loads } from '@/utils/index.js'
import { frontproduct } from '@/server/api';
import { computed,ref,onMounted } from 'vue';
import { computed,ref,onMounted,defineEmits } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { skudetail,cartsave } from '@/server/api.js'
const counterStore = useCounterStore(); // 使 Store
//使piniastoreToRefs(使)
const { token } = storeToRefs(counterStore);
@ -96,6 +98,8 @@
const decs = ref('');
const pages = ref(0);
const limits = ref(10);
// 1.
const emit = defineEmits(['updatecart']);
const props = defineProps({
apiType:{
type:Number,
@ -148,22 +152,64 @@
}
}
}
//
const addCart=(i,type)=>{
const { jumpIds,productInfo,specType } = i;
const { jumpIds,productInfo,specType,id } = i;
let specTypes = false;
if(type){
specTypes = specType;
}else{
specTypes = productInfo.specType;
}
if(specTypes){
console.log('多规格弹窗选类加购');
}else{
console.log('单规格直接加购')
api_skudetail(specTypes,id);
}
// specTypes truefalse
const api_skudetail=(specTypes,id)=>{
loads('', true)
return skudetail(id).then(({data}) => {
if(specTypes){
}else{
const { id,productId } = data.productValue.默认;
api_cartsave(productId,id);
}
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
const api_cartsave = (productId,productAttrUnique) =>{
const params = {
cartNum:1,
productId,
productAttrUnique
}
return cartsave(params).then(({message})=>{
uni.hideLoading()
uni.showToast({
title:'添加购物车成功',
icon:'none'
})
emit('updatecart',true);
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
//
onMounted(() => {
api_product();
@ -218,7 +264,7 @@
}
//
.shop_view{
margin-top: 10rpx;
// margin-top: 10rpx;
padding: 13rpx 20rpx 0rpx 20rpx;
display: flex;
justify-content: space-between;

View File

@ -60,7 +60,7 @@
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
"desc" : "需要获取您的位置信息用于展示附近门店"
}
},
"requiredPrivateInfos" : [ "getLocation" ]

View File

@ -25,44 +25,32 @@
<view class="shop_view" @click="OpenShop()">
<view class="cart_scroll">
<scroll-view class="cart_scroll_ul" :scroll-with-animation="true" :enhanced="true" :show-scrollbar="false" scroll-x="true">
<view class="cart_scroll_li">
<view class="cart_scroll_li" v-for="(item,index) in orderList" :key="index">
<view class="cart_scroll_img">
<image class="cart_scroll_img_url" src="../../static/Mask.png" mode="widthFix"></image>
</view>
</view>
<view class="cart_scroll_li">
<view class="cart_scroll_img">
<image class="cart_scroll_img_url" src="../../static/Mask.png" mode="widthFix"></image>
</view>
</view>
<view class="cart_scroll_li">
<view class="cart_scroll_img">
<image class="cart_scroll_img_url" src="../../static/Mask.png" mode="widthFix"></image>
</view>
</view>
<view class="cart_scroll_li">
<view class="cart_scroll_img">
<image class="cart_scroll_img_url" src="../../static/Mask.png" mode="widthFix"></image>
<image class="cart_scroll_img_url" :src="item.image" mode="widthFix"></image>
</view>
</view>
</scroll-view>
</view>
<view class="shop_numer" >45</view>
<view class="shop_numer" >{{orderInfoVo.orderProNum}}</view>
</view>
<view class="cont_m">
<view class="cont_m_l">商品金额</view>
<view class="cont_m_r price">400.50</view>
<view class="cont_m_r price">{{orderInfoVo.proTotalFee}}</view>
</view>
<view class="cont_m">
<view class="cont_m_l">配送费<text class="cont_m_ps">满30免基础配送费</text></view>
<view class="cont_m_r price">20</view>
<view class="cont_m_l">配送费<text class="cont_m_ps" v-if="orderInfoVo.freightFee > 0">满30免基础配送费</text></view>
<view class="cont_m_r price" v-if="orderInfoVo.freightFee > 0">{{orderInfoVo.freightFee}}</view>
<view class="cont_m_r" v-else>免配送费</view>
</view>
<view class="cont_m" @click="OpenCoupon()">
<view class="cont_m_l"><image class="cont_m_x_img" src="../../static/order/coupon.png"></image>优惠券<text class="cont_m_ps cont_m_x_v">最佳优惠</text></view>
<view class="cont_m_r cont_m_color">-<text class="couponprice">45.08</text></view>
</view>
<view class="cont_bottom"><text class="cont_text">小计:</text><text class="cont_price">488.50</text></view>
<view class="cont_bottom"><text class="cont_text">小计:</text><text class="cont_price">{{orderInfoVo.payFee}}</text></view>
</view>
<!-- 支付方式 -->
<view class="cont conttop">
@ -81,10 +69,10 @@
<image class="cont_balance" src="../../static/order/balance.png" mode="widthFix"></image>
<view class="cont_balance_ul">
<view class="cont_tx">余额抵扣<text class="cont_txx">?</text></view>
<view class="cont_desc">暂无可用</view>
<view class="cont_desc">{{orderInfoVo.userBalance > 0 ? orderInfoVo.userBalance:'暂无可用'}}</view>
</view>
</view>
<switch :checked="isDefault == 1 ? true:false" color="#e61817" @change="switchChange" />
<switch :checked="isDefault == 1 ? true:false" color="#e61817" :disabled="orderInfoVo.userBalance > 0 ?false:true" @change="switchChange" />
</view>
</view>
<!-- 订单备注 -->
@ -98,7 +86,7 @@
<view class="footer">
<view class="footer_li">
<text class="footer_name">应付:</text>
<text class="footer_price">488.58</text>
<text class="footer_price">{{orderInfoVo.payFee}}</text>
<view class="footer_coupon">共优惠<text class="footer_coupon_price">3.00</text></view>
</view>
<view class="footer_btn">去支付</view>
@ -107,32 +95,22 @@
<view class="shop_open">
<view class="shop_open_title">商品信息<view class="shop_open_close" @click="OpenShop()"><image src="../../static/order/close.png" mode="widthFix"></image></view></view>
<view class="shop_open_cont">
<view class="shop_open_item">
<view class="shop_open_item" v-for="(item,index) in orderList" :key="index">
<view class="shop_open_cont_l">
<view class="shop_border">
<image class="shop_img" src="../../static/Mask.png" mode="widthFix"></image>
<image class="shop_img" :src="item.image" mode="widthFix"></image>
</view>
<view class="shop_script">
<view class="shop_title">糖醋排骨</view>
<view class="shop_desc_price">小计:<text class="shop_desc_f">19.50</text></view>
<view class="shop_desc_amount">数量:1</view>
<view class="shop_title"><text>{{item.productName}}</text></view>
<view class="shop_desc_price">小计<text class="shop_desc_f">{{item.subtotal}}</text></view>
<view class="shop_desc_amount">数量:{{item.payNum}}</view>
</view>
</view>
<view class="shop_open_cont_price">45.08</view>
</view>
<view class="shop_open_item">
<view class="shop_open_cont_l">
<view class="shop_border">
<image class="shop_img" src="../../static/Mask.png" mode="widthFix"></image>
</view>
<view class="shop_script">
<view class="shop_title">糖醋排骨</view>
<view class="shop_desc_price">小计:<text class="shop_desc_f">19.50</text></view>
<view class="shop_desc_amount">数量:1</view>
</view>
</view>
<view class="shop_open_cont_price">45.08</view>
<view class="shop_open_cont_price">{{item.price}}</view>
</view>
</view>
</view>
</uni-popup>
@ -175,10 +153,13 @@
</template>
<script setup>
import NP from 'number-precision';
import { loads } from '@/utils/index.js'
import { computed,ref } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onReachBottom } from "@dcloudio/uni-app"
import { orderloadpre,deliverytimes } from "@/server/api.js"
const counterStore = useCounterStore(); // 使 Store
const isDefault = ref(0);
const shopPopup = ref(null);
@ -189,6 +170,10 @@ const timePopup = ref(null);
const timeShow = ref(false);
const show = ref(false);
const timList = ref([]);
const orderDetailList = ref({});
const orderInfoVo = ref({});
const orderList = ref([]);
const preOrderNos = ref('');
//使piniastoreToRefs(使)
//const { count,doubleCount } = storeToRefs(counterStore);
const isIos = ref(false);
@ -250,13 +235,50 @@ const timeFun = (e)=>{
timList.value = time;
}
const onAddress=()=>{
const params = {page:1,limit:10}
return addresslist(params).then(({data}) => {
if(data.list.length){
uni.navigateTo({
url:`/userserve/addressList/addressList`
url:`/userserve/addressList/addressList?address_isDefaults=true`
})
}else{
uni.navigateTo({
url:`/userserve/addressList/addressList?address_isDefaults=true`
})
}
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
};
//
const api_orderloadpre = () => {
loads('', true)
return orderloadpre(preOrderNos.value).then(({data})=>{
uni.hideLoading();
orderDetailList.value = data;
data.orderInfoVo.orderDetailList.forEach(item => {
item.subtotal = NP.times(item.price,item.payNum);
})
orderList.value = data.orderInfoVo.orderDetailList;
orderInfoVo.value = data.orderInfoVo;
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
onLoad((options) => {
const { preOrderNo } = options;
preOrderNos.value = preOrderNo;
System();
timeFun();
api_orderloadpre();
});
onShow(() => {

View File

@ -28,9 +28,9 @@ page{
color: #000000;
.cont_default{
font-size: 20rpx;
background-color: rgba(249, 212, 72, 0.2);
background-color:#FDEDEE;
border-radius: 10rpx;
color: #F9D448;
color: #FF0000;
margin-right: 10rpx;
padding: 2rpx 10rpx 2rpx 10rpx;
vertical-align: middle;
@ -216,7 +216,7 @@ page{
z-index: 2;
font-size: 28rpx;
color: #666666;
height: 138rpx;
height: 142rpx;
align-items: center;
display: flex;
justify-content: flex-end;
@ -438,12 +438,21 @@ page{
}
.shop_script{
margin-left: 20rpx;
width: 365rpx;
.shop_title{
font-size: 28rpx;
color: #333333;
min-height: 45rpx;
font-weight: 500;
}
.shop_title text{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
word-break: break-all;
}
.shop_desc_price{
font-size: 24rpx;
color: #999999;

View File

@ -175,8 +175,9 @@
"pages": [{
"path": "location/location",
"style": {
"navigationBarTitleText": "选择收货地址",
"navigationBarBackgroundColor": "#FFFFFF"
"navigationBarTitleText": "门店列表",
"navigationBarBackgroundColor": "#FFFFFF",
"enablePullDownRefresh": true
}
},
{
@ -204,7 +205,7 @@
},{
"path": "addressEdit/addressEdit",
"style": {
"navigationBarTitleText": "新增地址",
"navigationBarTitleText": "编辑收货地址",
"navigationBarBackgroundColor": "#FFFFFF"
}
},{
@ -251,12 +252,6 @@
"navigationBarTitleText": "意见反馈",
"navigationBarBackgroundColor": "#FFFFFF"
}
},{
"path": "editaddress/editaddress",
"style": {
"navigationBarTitleText": "新增收货地址",
"navigationBarBackgroundColor": "#FFFFFF"
}
}]
}
],

View File

@ -3,7 +3,7 @@
<view class="main">
<!-- 头部区域 -->
<view class="head" :style="{'padding-top':headerHeight+'px'}" >
<view class="head_location head_location_active" @click="location()"><text class="location_title">人间都汇·汤泉养生</text></view>
<view class="head_location" :class="storeName?'head_location_active':''" @click="location()"><text class="location_title">{{storeName||'正在获取定位'}}</text></view>
<view class="head_ul">
<view class="head_l">
<view class="head_q">购物车</view>
@ -19,22 +19,23 @@
<view class="head_fixed" :style="{'height':75+headerHeight+'px'}">下拉刷新...</view>
<view class="cart">
<view style="height: 10rpx;"></view>
<template v-if="cartList.length">
<uni-swipe-action>
<uni-swipe-action-item v-for="(item,index) in cartList" :key="index" :right-options="options" @click="removeCart(1,item)">
<view class="cart_item" v-if="item.type == 1">
<view class="cart_item">
<view class="cart_selected" @click="checkedShop(item)">
<view :class="item.isSelected === '1'?'cart_selected_true':'cart_selected_false'">
<image v-if="item.isSelected" src="../../static/selected.png"></image>
<view :class="item.isSelect === 1?'cart_selected_true':'cart_selected_false'">
<image v-if="item.isSelect" src="../../static/selected.png"></image>
</view>
</view>
<view class="cart_shop">
<image class="cart_shop_img" :src="item.imgUrl" mode="widthFix"></image>
<image class="cart_shop_img" :src="item.image" mode="widthFix"></image>
</view>
<view class="cart_shop_cont">
<view class="cart_title"><text class="cart_text">{{item.title}}</text></view>
<view class="cart_title"><text class="cart_text">{{item.storeName}}</text></view>
<view class="cart_desc">{{item.desc}}</view>
<view class="cart_bottom">
<view class="cart_price price">{{item.price}}<text class="market_name prices">59.9</text></view>
<view class="cart_price price">{{item.price}}<!--<text class="market_name prices">59.9</text>--></view>
<view class="cart_counter" v-if="showEdit" @click="removeCart(1,item)">
<view class="cart_remove">删除</view>
</view>
@ -42,7 +43,7 @@
<view class="cart_counter_btn border_l" @click="editAmount(1,item)">
<image class="cart_counter_btn_img" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/minus.png" mode="widthFix"></image>
</view>
<view class="cart_counter_center">{{item.amount}}</view>
<view class="cart_counter_center">{{item.cartNum}}</view>
<view class="cart_counter_btn border_r" @click="editAmount(2,item)">
<image class="cart_counter_btn_img" src="https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/add.png" mode="widthFix"></image>
</view>
@ -50,11 +51,11 @@
</view>
</view>
</view>
<view class="cart_items" v-if="item.type == 2">
<!-- <view class="cart_items" v-if="item.type == 2">
<view class="cart_t">
<view class="cart_selected">
<view :class="item.isSelected?'cart_selected_true':'cart_selected_false'">
<image v-if="item.isSelected" src="../../static/selected.png"></image>
<view :class="item.isSelect?'cart_selected_true':'cart_selected_false'">
<image v-if="item.isSelect" src="../../static/selected.png"></image>
</view>
</view>
<view class="cart_view_scroll">
@ -87,48 +88,44 @@
</view>
</view>
</view>
</view>
</view> -->
</uni-swipe-action-item>
</uni-swipe-action>
</template>
<!-- 失效商品 -->
<!-- <view class="cart_lose">
<view class="cart_lose" v-if="cartList_invalid.length">
<view class="cart_lose_top">
<view class="cart_lose_top_l">5款失效商品</view>
<view class="cart_lose_top_l">{{cartList_invalid.length}}款失效商品</view>
<view class="cart_lose_top_r">一键清空</view>
</view>
<view class="cart_lose_bottom">
<view class="cart_lose_bottom" v-for="(item,index) in cartList_invalid" :key="index">
<view class="cart_lose_img">
<view class="cart_lose_bcg">
<view class="cart_lose_text">商品已下架</view>
</view>
<image class="cart_lose_img_url" src="../../static/Mask.png" mode="widthFix"></image>
<image class="cart_lose_img_url" :src="item.image" mode="widthFix"></image>
</view>
<view class="cart_lose_ly">
<view class="cart_lose_title">糖醋排骨</view>
<view class="cart_lose_title">{{item.storeName}}</view>
<view class="cart_lose_desc">商品下架了</view>
</view>
</view>
<view class="cart_lose_bottom">
<view class="cart_lose_img">
<view class="cart_lose_bcg">
<view class="cart_lose_text">商品已下架</view>
</view>
<image class="cart_lose_img_url" src="../../static/Mask.png" mode="widthFix"></image>
</view>
<view class="cart_lose_ly">
<view class="cart_lose_title">糖醋排骨</view>
<view class="cart_lose_desc">商品下架了</view>
<view class="empty" v-if="iscartShow && !cartList.length && !cartList_invalid.length">
<view class="empty_cont">
<image class="empty_cont_img" src="../../static/Empty/cart.png" mode="widthFix"></image>
<view class="empty_cont_title">购物车还是空的快去加购吧</view>
<view class="empty_cont_btn">去逛逛</view>
</view>
</view>
</view> -->
</view>
</view>
<template v-if="!showEdit">
<recomGoods v-if="token" :apiType="5"></recomGoods>
<template>
<recomGoods v-if="iscartListLoaded" :apiType="5" @updatecart="cartType"></recomGoods>
</template>
<view style="height: 200rpx;"></view>
<view class="footer">
<view class="footer" v-if="cartList.length">
<view class="footer_l">
<view class="footer_selected" @click="allChecked">
<view :class="allCheckedShow?'footer_selected_true':'footer_selected_false'">
@ -147,7 +144,7 @@
<view class="footer_text">合计:</view>
<view class="footer_price">{{totalPrice}}</view>
</view>
<view class="footer_btn" :class="!totalPrice?'opy':''" @click="orderConfirm">下单</view>
<view class="footer_btn" :class="!totalPrice?'opy':''" @click="orderConfirm">结算</view>
</block>
</view>
</view>
@ -194,24 +191,35 @@
</view>
</view>
</uni-popup>
<!-- 获取定位失败小组件提示 -->
<locationOpen></locationOpen>
</view>
</template>
<script setup>
import NP from 'number-precision';
import { loads } from '@/utils/index.js'
import recomGoods from '@/components/recomGoods/recomGoods.vue';
import { ref,computed } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onReachBottom } from "@dcloudio/uni-app"
import { cartlist,cartnum,cartdelete,preorder,optForCart } from "@/server/api.js"
const counterStore = useCounterStore(); // 使 Store
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,token } = storeToRefs(counterStore);
const {statusHeight,headerHeight,token,storeName,storeId,latitude,longitude,locationShow } = storeToRefs(counterStore);
const couponPopup = ref(null);
const couponShow = ref(false);
const show = ref(false);
const showEdit = ref(false);
const cartList = ref([]);
const cartList_invalid = ref([]);
const allCheckedShow = ref(false)
const cartpages = ref(0);
const cartdecs = ref("");
const iscartListLoaded = ref(false)
const iscartShow = ref(false);
const carttotal = ref(0)
const options = ref([
{
text: '删除',
@ -230,109 +238,161 @@ const changeCoupon = (e)=>{
const edit = (e)=>{
showEdit.value ? showEdit.value = false:showEdit.value = true;
};
const onClick = (e) => {
console.log('点击删除', e);
};
const cartType = (type)=>{
api_cartlist(true);
}
const goDetail= ()=>{
uni.navigateTo({
url:`/shopProDetail/detail/detail`
})
}
const orderConfirm = ()=>{
uni.navigateTo({
url:`/order/orderConfirm/orderConfirm`
})
}
const cartData =()=>{
let data = [{
id:'001',
imgUrl:'../../static/Mask.png',
title:'新疆大盘鸡',
desc:'比加入时下降1.1元',
amount:1,
price:'1',
type:'1',
isSelected:'1'
},{
id:'002',
imgUrl:'../../static/Mask.png',
title:'萝卜片炒腊肉',
desc:'比加入时下降4.5元',
amount:1,
price:'1',
type:'1',
isSelected:'1'
},{
id:'003',
imgUrl:'../../static/Mask.png',
title:'盘龙鳝',
desc:'比加入时下降1.5元',
amount:5,
price:'68',
type:'1',
isSelected:'0'
}]
cartList.value = data;
//
const api_cartlist = (e) =>{
if(e){
// cartList.value = [];
// cartdecs.value = '';
// cartpages.value = 0;
iscartShow.value = false;
}
cartdecs.value = "—— 加载中... ——";
// cartpages.value = cartpages.value + 1;
loads('', true)
const params = {isValid:"1",page:'1',limit:'100'}
return cartlist(params).then(({data})=>{
uni.hideLoading()
cartdecs.value = '—— 上拉加载更多 ——'
if(data.list.length < 10){
cartdecs.value = '—— 嗷呜,已经到底啦 ——';
}
//
const allSelected = cartList.value.every(item => item.isSelected !== undefined && item.isSelected === '1');
const allSelected = data.list.every(item => item.isSelect === 1);
if(allSelected){
allCheckedShow.value = true;
}else{
allCheckedShow.value = false;
}
};
cartList.value = data.list;
carttotal.value = data.total;
})
.then(()=>{
if(e){api_cartlist_invalid(true)}
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
//
const api_cartlist_invalid = (empty) =>{
// if(empty){
// cartList_invalid.value = [];
// }
const params = {isValid:"0",page:'1',limit:'50'}
return cartlist(params).then(({data})=>{
uni.hideLoading()
cartList_invalid.value = data.list;
iscartListLoaded.value = true
iscartShow.value = true
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
//
const editAmount=(type,data)=>{
//
if(data.amount == 1 && type == 1) return false;
console.log('data',data);
let { id,cartNum } = data;
///
if(cartNum == 1 && type == 1) return false;
let number = type == 1 ? cartNum - 1 : cartNum + 1;
loads('', true)
return cartnum(id,number).then(({message})=>{
uni.hideLoading()
cartList.value.forEach(item=>{
if(data.id == item.id){
item.amount = type == 1 ? item.amount - 1 : item.amount + 1;
if(id == item.id){
item.cartNum = type == 1 ? item.cartNum - 1 : item.cartNum + 1;
}
})
}).catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
};
//
const allChecked=()=>{
let cartType = "";
if(allCheckedShow.value){
allCheckedShow.value = false;
cartList.value.forEach((item,index)=>{
item.isSelected = '0'
})
cartType = "no"
}else{
allCheckedShow.value = true;
cartList.value.forEach((item,index)=>{
item.isSelected = '1'
})
cartType = "yes"
}
api_optForCart(2,0,cartType);
};
//
const checkedShop=(e)=>{
let cartType = ""
if(e.isSelect){
cartType = "no"
}else{
cartType = "yes"
}
api_optForCart(1,e.id,cartType);
};
const api_optForCart=(type,cartIds,cartType)=>{
const params = {cartType}
if(type == 1){
params.cartIds = cartIds
}
loads('', true)
return optForCart(params).then(({data})=>{
uni.hideLoading()
if(type == 1){
//
cartList.value.forEach((item,index)=>{
if(e.id == item.id){
item.isSelected = item.isSelected === '1' ? '0' : '1'
if(cartIds == item.id){
item.isSelect = item.isSelect === 1 ? 0 : 1
}
})
//
const allSelected = cartList.value.every(item => item.isSelected !== undefined && item.isSelected === '1');
if(allSelected){
allCheckedShow.value = true;
const allSelected = cartList.value.every(item => item.isSelect === 1);
allCheckedShow.value =allSelected ? true : false;
}else{
allCheckedShow.value = false;
allCheckedShow.value = cartType == "yes" ? true : false;
cartList.value.forEach((item,index)=>{
item.isSelect = cartType == "yes" ? 1 : 0;
})
}
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
};
//
const totalPrice = computed(() => {
//
const selectedItems = cartList.value.filter(item => item.isSelected === '1');
const selectedItems = cartList.value.filter(item => item.isSelect === 1);
//
return selectedItems.reduce((sum, item) => sum + item.price * item.amount, 0);
return selectedItems.reduce((sum, item) => NP.round(NP.plus(sum,NP.times(item.price,item.cartNum)),2), 0);
});
//
const selectedAmount = computed(() => {
//
const selectedItems = cartList.value.filter(item => item.isSelected === '1');
const selectedItems = cartList.value.filter(item => item.isSelect === 1);
return selectedItems.length
});
const removeCart=(type,item)=>{
@ -351,34 +411,86 @@ const removeCart=(type,item)=>{
success: ({confirm}) => {
if (confirm) {
if(type == 1){
console.log('单商品删除!');
api_cartdelete(type,item.id);
}else if(type == 2){
console.log('清空购物车!');
cartList.value = []
const ids = cartList.value.map(item => item.id);
api_cartdelete(type,ids)
}else{
console.log('选中商品删除!');
//
const ids = cartList.value.filter(item => item.isSelect === 1).map(item => item.id);
api_cartdelete(type,ids)
}
}
}
})
};
const api_cartdelete = (type,ids) => {
loads('', true)
return cartdelete(ids).then(({message})=>{
uni.hideLoading()
if(type == 1){
cartList.value = cartList.value.filter(item => item.id !== ids);
}else{
cartList.value = cartList.value.filter(item => !ids.includes(item.id));
}
if(showEdit.value){ showEdit.value = false }
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
//
const orderConfirm = () => {
const orderDetails = cartList.value.filter(item => item.isSelect === 1).map(item => ({shoppingCartId:item.id}));
if(!orderDetails.length){
uni.showToast({
title:'请选中商品后,在结算',
icon:'none'
})
return false
}
loads('', true)
let params = {
merId:storeId.value,
orderDetails,
preOrderType:'shoppingCart'
};
return preorder(params).then(({data})=>{
uni.hideLoading();
uni.navigateTo({
url:`/order/orderConfirm/orderConfirm?preOrderNo=${data.preOrderNo}`
})
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
const location=()=>{
if(locationShow.value) return false;
uni.navigateTo({
url:`/userserve/location/location`
})
}
//使 uni.onLoad
onLoad((options) => {
cartData();
});
onLoad((options) => {});
onShow(() => {
api_cartlist(true);
});
onPullDownRefresh(()=>{
api_cartlist(true);
uni.stopPullDownRefresh();
})
onReachBottom(()=>{
// api_cartlist(false);
})
</script>

View File

@ -109,6 +109,41 @@ page{
.cart{
background: linear-gradient(180deg, #FCEEEF 0%, #f6f6f6 100%);
background-repeat: no-repeat;
.empty{
height:480rpx;
background: linear-gradient( 180deg, #FBF1F1 0%, #FFFFFF 50%);
margin:0rpx 20rpx 0rpx 20rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
.empty_cont{
.empty_cont_img{
margin: 0 auto;
width: 265rpx;
height: 280rpx;
display: flex;
}
.empty_cont_title{
font-size: 26rpx;
color: #999999;
text-align: center;
}
.empty_cont_btn{
margin: 0 auto;
width: 154rpx;
height: 46rpx;
border-radius: 30rpx;
border: 1rpx solid #FF0000;
color: #FF0000;
line-height: 30rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 40rpx;
}
}
}
.cart_item{
// margin: 0rpx 20rpx 0rpx 20rpx;
// border-radius: 25rpx;
@ -162,12 +197,13 @@ page{
}
}
.cart_shop_cont{
width: 390rpx;
width: 415rpx;
padding-right: 20rpx;
.cart_title{
font-size: 27rpx;
color: #333333;
font-weight: 500;
min-height: 110rpx;
.cart_text{
min-height: 65rpx;
overflow: hidden;

View File

@ -1,56 +1,34 @@
<template>
<page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>
<view class="mian">
<!-- 头部区域 -->
<view class="head" :style="{'padding-top':headerHeight+4+'px'}">
<view class="head_search" :style="{'width':searchWidth+'px','height':statusHeight+4+'px'}">
<view class="head_search" :style="{'width':searchWidth+'px','height':statusHeight+4+'px'}" @click="onSearch">
<image class="head_search_img" src="../../static/search_img.png" mode="widthFix"></image>
<input class="head_search_input" type="text" placeholder="请输入搜索内容" v-model="searchtext"/>
<input class="head_search_input" disabled="true" type="text" placeholder="请输入搜索内容" />
</view>
<view class="head_class">
<view class="head_class" v-if="navList.length">
<scroll-view
:enhanced="true"
:show-scrollbar="false"
scroll-x="true"
:scroll-with-animation="true"
:scroll-left="ScrollLeft"
:scroll-left="scrollLefter"
class="head_class_scroll">
<view class="head_class_item head_class_item_active">
<view class="head_class_title">为您推荐</view>
<view class="head_class_active head_class_active_img"></view>
</view>
<view class="head_class_item">
<view class="head_class_title">特惠专区</view>
<view class="head_class_active"></view>
</view>
<view class="head_class_item">
<view class="head_class_title">时令春菜</view>
<view class="head_class_active"></view>
</view>
<view class="head_class_item">
<view class="head_class_title">鸭货卤味</view>
<view class="head_class_active"></view>
</view>
<view class="head_class_item">
<view class="head_class_title">/鹅肉类</view>
<view class="head_class_active"></view>
</view>
<view class="head_class_item">
<view class="head_class_title">轻食萨拉</view>
<view class="head_class_active"></view>
</view>
<view class="head_class_item">
<view class="head_class_title">猪肉类</view>
<view class="head_class_active"></view>
</view>
<view class="head_class_item">
<view class="head_class_title">羊肉肉类</view>
<view class="head_class_active"></view>
<view
v-for="(item,index) in navList"
:key="index"
class="head_class_item"
:class="currentTab == index ? 'head_class_item_active' : '' "
@click="swichNav(item,index)"
>
<view class="head_class_title">{{ item.name }}</view>
<view class="head_class_active" :class="currentTab == index ? 'head_class_active_img':''"></view>
</view>
</scroll-view>
<view class="head_class_btn">
<view class="head_class_btn" @click="openCategory()">
<view class="head_class_arrow_box">
<image class="head_class_arrow_box_img" src="../../static/down_arrow.png"></image>
<!-- <image class="head_class_arrow_box_img" src="../../static/up_arrow.png"></image> -->
</view>
</view>
</view>
@ -58,139 +36,257 @@
<!-- 商品区域 -->
<view class="cont_view">
<view class="head_fixed" :style="{'height':statusHeight+headerHeight+48+'px'}">下拉刷新...</view>
<view class="head_fixed" :style="{'height':statusHeight+headerHeight+48+'px'}">
{{productList.length?'下拉刷新...':''}}
</view>
<view class="shop_view">
<view class="shop_view_ul">
<view class="shop_view_li" @click="goDetail()">
<block v-for="(item,index) in productList" :key="item.id">
<block v-if="item.isEven">
<view class="shop_view_li shop_view_bcg" v-if="item.type == 1">
<swiper class="shop_view_li_swiper" indicator-dots interval="3000" autoplay indicator-active-color="#FFFFFF" indicator-color="rgba(246, 246, 246, .6)" circular >
<swiper-item class="shop_view_li_swiper_item" v-for="(swiperitem,swiperkey) in item.homeVos[0].items" :key="swiperkey" >
<image class="shop_view_li_swiper_img_url" :src="swiperitem.imgUrl" mode="widthFix" @load="imageLoad" lazy-load @click="JumpType(swiperitem)"></image>
</swiper-item>
</swiper>
</view>
<view class="shop_view_li" v-if="item.type == 0" @click="JumpType(item.id,1)">
<view class="shop_view_img">
<view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view>
<!-- <view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view> -->
<view class="shop_view_img_u">
<image class="shop_view_img_url" src="../../static/Mask.png"></image>
<image class="shop_view_img_url" :src="item.image" mode="widthFix" lazy-load="true"></image>
</view>
</view>
<view class="shop_view_cont">
<view class="shop_view_cont_title">糖醋排骨</view>
<view class="shop_view_cont_desc">乡下土猪</view>
<view class="shop_view_cont_title"><text>{{item.storeName}}</text></view>
<view class="shop_view_cont_desc"><text>{{item.storeInfo}}</text></view>
<view class="shop_view_cont_tag">
<view class="shop_view_cont_tag_text">仅剩3</view>
<view class="shop_view_cont_tag_text">劲辣胃浓</view>
<view class="shop_view_cont_tag_text" v-if="item.stock <= 10">仅剩{{item.stock}}</view>
<view class="shop_view_cont_tag_text" v-for="(t,g) in item.tagList" :key="g">{{t}}</view>
</view>
<view class="shop_view_cont_bottom">
<view class="shop_view_cont_price price">43.9<text class="market_name prices">59.9</text></view>
<view class="shop_view_cont_cart">
<image class="shop_view_cont_cart_img" src="../../static/oncatr02.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
<view class="shop_view_li" @click="goDetail()">
<view class="shop_view_img">
<view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view>
<view class="shop_view_img_u">
<image class="shop_view_img_url" src="../../static/Mask.png"></image>
</view>
</view>
<view class="shop_view_cont">
<view class="shop_view_cont_title">糖醋排骨</view>
<view class="shop_view_cont_desc">乡下土猪</view>
<view class="shop_view_cont_tag">
<view class="shop_view_cont_tag_text">仅剩3份</view>
<view class="shop_view_cont_tag_text">劲辣胃浓</view>
</view>
<view class="shop_view_cont_bottom">
<view class="shop_view_cont_price price">43.9<text class="market_name prices">59.9</text></view>
<view class="shop_view_cont_cart">
<image class="shop_view_cont_cart_img" src="../../static/oncatr02.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
<view class="shop_view_li" @click="goDetail()">
<view class="shop_view_img">
<view class="shop_view_tag"><text class="shop_view_tag_text">香甜</text></view>
<view class="shop_view_img_u">
<image class="shop_view_img_url" src="../../static/Mask.png"></image>
</view>
</view>
<view class="shop_view_cont">
<view class="shop_view_cont_title">泡椒田鸡</view>
<view class="shop_view_cont_desc">超大只田鸡</view>
<view class="shop_view_cont_tag">
<view class="shop_view_cont_tag_text">仅剩3份</view>
<view class="shop_view_cont_tag_text">劲辣胃浓</view>
<view class="shop_view_cont_tag_text">劲辣胃浓</view>
</view>
<view class="shop_view_cont_bottom">
<view class="shop_view_cont_price price">43.9<text class="market_name prices">59.9</text></view>
<view class="shop_view_cont_cart">
<view class="shop_view_cont_price price">{{item.price}}<text class="market_name prices">{{item.otPrice}}</text></view>
<view class="shop_view_cont_cart" @click.stop="addCart(item,1)">
<image class="shop_view_cont_cart_img" src="../../static/oncatr02.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</block>
</block>
</view>
<view class="shop_view_ul">
<view class="shop_view_li" @click="goDetail()">
<block v-for="(item,index) in productList" :key="item.id">
<block v-if="!item.isEven">
<view class="shop_view_li shop_view_bcg" v-if="item.type == 1">
<swiper class="shop_view_li_swiper" indicator-dots interval="3000" autoplay indicator-active-color="#FFFFFF" indicator-color="rgba(246, 246, 246, .6)" circular >
<swiper-item class="shop_view_li_swiper_item" v-for="(swiperitem,swiperkey) in item.homeVos[0].items" :key="swiperkey" >
<image class="shop_view_li_swiper_img_url" :src="swiperitem.imgUrl" mode="widthFix" lazy-load @load="imageLoad" @click="JumpType(swiperitem)"></image>
</swiper-item>
</swiper>
</view>
<view class="shop_view_li" v-if="item.type == 0" @click="JumpType(item.id,1)">
<view class="shop_view_img">
<view class="shop_view_tag"><text class="shop_view_tag_text">热销</text></view>
<!-- <view class="shop_view_tag"><text class="shop_view_tag_text">够辣</text></view> -->
<view class="shop_view_img_u">
<image class="shop_view_img_url" src="../../static/Mask.png"></image>
<image class="shop_view_img_url" :src="item.image" mode="widthFix" lazy-load="true"></image>
</view>
</view>
<view class="shop_view_cont">
<view class="shop_view_cont_title">泡椒田鸡</view>
<view class="shop_view_cont_desc">超大只田鸡</view>
<view class="shop_view_cont_title"><text>{{item.storeName}}</text></view>
<view class="shop_view_cont_desc"><text>{{item.storeInfo}}</text></view>
<view class="shop_view_cont_tag">
<view class="shop_view_cont_tag_text">仅剩3</view>
<view class="shop_view_cont_tag_text">劲辣胃浓</view>
<view class="shop_view_cont_tag_text" v-if="item.stock <= 10">仅剩{{item.stock}}</view>
<view class="shop_view_cont_tag_text" v-for="(t,g) in item.tagList" :key="g">{{t}}</view>
</view>
<view class="shop_view_cont_bottom">
<view class="shop_view_cont_price price">43.9<text class="market_name prices">59.9</text></view>
<view class="shop_view_cont_cart">
<image class="shop_view_cont_cart_img" src="../../static/oncatr02.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
<view class="shop_view_li" @click="goDetail()">
<view class="shop_view_img">
<view class="shop_view_tag"><text class="shop_view_tag_text">新鲜</text></view>
<view class="shop_view_img_u">
<image class="shop_view_img_url" src="../../static/Mask.png"></image>
</view>
</view>
<view class="shop_view_cont">
<view class="shop_view_cont_title">泡椒田鸡</view>
<view class="shop_view_cont_desc">超大只田鸡</view>
<view class="shop_view_cont_tag">
<view class="shop_view_cont_tag_text">仅剩3份</view>
<view class="shop_view_cont_tag_text">劲辣胃浓</view>
</view>
<view class="shop_view_cont_bottom">
<view class="shop_view_cont_price price">43.9<text class="market_name prices">59.9</text></view>
<view class="shop_view_cont_cart">
<view class="shop_view_cont_price price">{{item.price}}<text class="market_name prices">{{item.otPrice}}</text></view>
<view class="shop_view_cont_cart" @click.stop="addCart(item,1)">
<image class="shop_view_cont_cart_img" src="../../static/oncatr02.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</block>
</block>
</view>
</view>
<view class="load_desc">{{decs}}</view>
</view>
<view style="height: 200rpx;"></view>
<view class="nav_popup" v-if="show">
<view :style="{'height':headerHeight+42+'px'}"></view>
<view class="nav_head">
<view class="nav_head_class">
<view class="nav_head_name">全部分类</view>
<view class="nav_head_class_arrow_box" @click="openCategory()">
<image class="nav_head_class_arrow_box_img" src="../../static/up_arrow.png"></image>
</view>
</view>
<view class="nav_popup_list">
<view v-for="(item,index) in navList" :key="index" :class="currentTab == index ? 'nav_popup_selected' : '' " @click="swichNav(item,index)" class="nav_popup_item">{{ item.name }}</view>
</view>
</view>
</view>
<view class="bcg_popup" v-if="show" @click="openCategory()"></view>
</view>
</template>
<script setup>
import { loads } from '@/utils/index.js'
import { computed,ref } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onReachBottom } from "@dcloudio/uni-app"
import { frontcategory,frontproducts,skudetail,cartsave } from '@/server/api';
const counterStore = useCounterStore(); // 使 Store
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,ButtonWidth } = storeToRefs(counterStore);
const ScrollLeft = ref(0);
const pageWidth = ref(0);
const navList = ref([]);
const currentItem = ref({});
const currentTab = ref(0);
const productList = ref([]);
const pages = ref(0);
const decs = ref("");
const load = ref(true);
const scrollLefter = ref(0);
const windowWidth = ref(0);
const navPopup = ref(null);
const navShow = ref(false);
const show = ref(false);
const openCategory = ()=>{
show.value = !show.value
}
const swichNav = (item,index) => {
const cur = index;
const scrollLefters = pageWidth.value / 5;
currentItem.value = item;
if (currentTab.value == cur) return false
currentTab.value = cur;
scrollLefter.value = (cur - 1) * scrollLefters;
if(show.value){
show.value = false;
}
api_frontproducts(true);
}
const api_frontcategory = () => {
return frontcategory().then(({data})=>{
navList.value = data;
currentItem.value = data[0];
if(data.length){
api_frontproducts(false,1)
}
})
}
const api_frontproducts = (e,i) => {
if(e){
productList.value = [];
decs.value = '';
pages.value = 0;
}
decs.value = "—— 加载中... ——";
pages.value = pages.value + 1;
load.value = false;
const params = {
cid:currentItem.value.id,
page:pages.value,
limit:10
}
if(i == 1){loads('', true)}
return frontproducts(params).then(({data})=>{
if(i == 1){uni.hideLoading()}
decs.value = '—— 上拉加载更多 ——'
if(data.list.length < 10){
decs.value = '—— 嗷呜,已经到底啦 ——';
}
data.list.forEach((item,index)=>{
item.isEven = index % 2 === 0
})
productList.value = productList.value.concat(data.list);
})
.catch(({message}) => {
if(i == 1){uni.hideLoading()}
uni.showModal({
content:message,
showCancel: false
})
})
}
//
const JumpType=(item,type)=>{
if(type == 1){
uni.navigateTo({
url:`/shopProDetail/detail/detail?id=${item}`//
})
}else{
const { jumpUrl,jumpIds,jumpType } = item;
if(jumpType == 0 || jumpType == 2 || jumpType == 4) return false;
let url = "";
if(jumpType == 1){
uni.navigateTo({
url:`/shopProDetail/detail/detail?id=${jumpIds}`//
})
}else if(jumpType == 3){
uni.switchTab({
url:`/pages/classify/classify`//
})
}
}
}
//
const addCart=(i,type)=>{
const { jumpIds,productInfo,specType,id } = i;
let specTypes = false;
if(type){
specTypes = specType;
}else{
specTypes = productInfo.specType;
}
api_skudetail(specTypes,id);
}
// specTypes truefalse
const api_skudetail=(specTypes,id)=>{
loads('', true)
return skudetail(id).then(({data}) => {
if(specTypes){
}else{
const { id,productId } = data.productValue.默认;
api_cartsave(productId,id);
}
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
const api_cartsave = (productId,productAttrUnique) =>{
const params = {
cartNum:1,
productId,
productAttrUnique
}
return cartsave(params).then(({message})=>{
uni.hideLoading()
uni.showToast({
title:'添加购物车成功',
icon:'none'
})
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
//
const updatePageWidth = () => {
const systemInfo = uni.getSystemInfoSync();
@ -200,23 +296,26 @@ const updatePageWidth = () => {
const searchWidth = computed(() => {
return pageWidth.value - ButtonWidth.value - 25;
});
const goDetail= ()=>{
const onSearch=()=>{
uni.navigateTo({
url:`/shopProDetail/detail/detail`
url:`/userserve/SearchProduct/SearchProduct`
})
}
//使 uni.onLoad
onLoad((options) => {
updatePageWidth();
api_frontcategory();
});
onShow(() => {
});
onPullDownRefresh(()=>{
api_frontproducts(true);
uni.stopPullDownRefresh();
});
onReachBottom(()=>{
api_frontproducts(false);
});
</script>

View File

@ -2,10 +2,11 @@ page{
background-color: #F6F6F6;
}
.mian{
background: linear-gradient(180deg, #FCF0F1 0%, #f6f6f6 60%);
// 头部样式
.head{
position: fixed;
z-index: 100;
z-index: 88;
width: 100%;
top: 0;
left: 0;
@ -110,6 +111,7 @@ page{
}
// 商品区域样式
.cont_view{
height: 100vh;
.head_fixed{
background-color: #f6f6f6;
color: #999999;
@ -123,7 +125,6 @@ page{
padding: 13rpx 20rpx 0rpx 20rpx;
display: flex;
justify-content: space-between;
background: linear-gradient(180deg, #FCF0F1 0%, #f6f6f6 50%);
.shop_view_ul{
width: 346rpx;
.shop_view_li{
@ -146,9 +147,9 @@ page{
}
}
.shop_view_img{
width: 100%;
// width: 100%;
position: relative;
height: 320rpx;
padding: 10rpx 10rpx 0rpx 10rpx;
.shop_view_tag{
width: 66rpx;
height: 42rpx;
@ -169,15 +170,12 @@ page{
}
}
.shop_view_img_u{
width: 300rpx;
position: absolute;
z-index: 1;
left: 20rpx;
top: 20rpx;
width: 100%;
.shop_view_img_url{
width: 100%;
height: 300rpx;
display: block;
border-radius: 20rpx;
}
}
}
@ -189,10 +187,26 @@ page{
color: #000000;
min-height: 80rpx;
}
.shop_view_cont_title text{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
word-break: break-all;
}
.shop_view_cont_desc{
color: #666666;
font-size: 24rpx;
}
.shop_view_cont_desc text{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
word-break: break-all;
}
.shop_view_cont_tag{
display: flex;
flex-wrap: wrap;
@ -236,6 +250,15 @@ page{
}
}
}
.load_desc{
font-size: 28rpx;
color: #aaa;
text-align: center;
padding-top: 30rpx;
padding-bottom: 30rpx;
}
}
.price::before {
content: '¥';
@ -255,4 +278,74 @@ page{
margin-left: 5rpx;
font-weight: 400;
}
.nav_popup{
padding-bottom:5px;
width: 100%;
position: fixed;
top:0;
z-index:99;
.nav_head{
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background: linear-gradient(180deg,#FCF0F1 0%,#FFFFFF 60%);
.nav_head_class{
margin: 0 10px 0 10px;
height: 50px;
display: flex;
align-items: center;
justify-content: space-between;
.nav_head_name{
font-size: 28rpx;
color: #333333;
font-weight: 500;
}
.nav_head_class_arrow_box{
width: 30px;
height: 30px;
border-radius: 50%;
background-color: #EFEFEF;
position: relative;
display: flex;
align-items: center;
justify-content: center;
.nav_head_class_arrow_box_img{
width: 50rpx;
height: 50rpx;
}
}
}
.nav_popup_list{
display: flex;
flex-wrap: wrap;
.nav_popup_item{
background-color: #F0EFF4;
border:1px solid #F0EFF4;
width: 162rpx;
height: 58rpx;
border-radius: 6rpx;
color: #333333;
font-size: 24rpx;
margin-left: 10px;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 15px;
}
.nav_popup_selected{
border:1px solid #FF6868;
color: #FF6868;
}
}
}
}
.bcg_popup{
background-color: rgba(0,0,0,0.4);
width: 100%;
height: 100vh;
position: fixed;
top:0;
z-index:30;
}
}

View File

@ -2,7 +2,7 @@
<view class="main">
<!-- 头部区域 -->
<view class="head" :style="{'padding-top':headerHeight+'px'}" >
<view class="head_location" :class="storeName?'head_location_active':''" @click="location()"><text class="location_title">{{storeName||'正在获取定位'}}</text></view>
<view class="head_location" :class="storeName?'head_location_active':''" @click="location()"><text class="location_title">{{storeName||locationName}}</text></view>
<view class="head_search" :style="{'height':statusHeight+8+'px'}" @click="onSearch">
<image class="head_search_img" src="../../static/search_img.png" mode="widthFix"></image>
<input class="head_search_input" disabled="true" type="text" placeholder="请输入搜索内容" />
@ -66,10 +66,9 @@
</scroll-view>
</view>
<!-- 商品区域 -->
<recomGoods v-if="token" :apiType="1"></recomGoods>
<recomGoods v-if="ishomeListLoaded" :apiType="1"></recomGoods>
<view style="height: 200rpx;"></view>
<view class="footer">
<!-- <view class="footer">
<view class="footer_cont">
<view class="footer_cont_l" @click="goCarts()">
<view class="footer_cont_cart">
@ -83,75 +82,43 @@
</view>
<view class="footer_cont_btn" @click="orderConfirm">去下单</view>
</view>
</view>
</view> -->
<!-- 获取定位失败小组件提示 -->
<locationOpen></locationOpen>
</view>
</template>
<script setup>
import { frontindex,frontproduct,frontstorelist } from '@/server/api';
import { loads } from '@/utils/index.js'
import { frontindex,frontproduct,frontstorelist,skudetail,cartsave } from '@/server/api';
import recomGoods from '@/components/recomGoods/recomGoods.vue';
import locationOpen from '@/components/locationOpen/locationOpen.vue'
import { computed,ref } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onReachBottom } from "@dcloudio/uni-app"
const counterStore = useCounterStore(); // 使 Store
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,nikeName,key,token,phone,uid,storeName } = storeToRefs(counterStore);
const {statusHeight,headerHeight,nikeName,key,token,phone,uid,storeName,storeId,latitude,longitude,locationName,locationShow } = storeToRefs(counterStore);
const homeList = ref([]);
const shopList = ref([]);
const total = ref(0);
const pages = ref(0);
const limits = ref(10);
const decs = ref('')
const latitude = ref('');
const longitude = ref('')
//
const getLocation = () => {
//
uni.getLocation({
type: 'gcj02',
success(res){
latitude.value = res.latitude;
longitude.value = res.latitude;
},
fail(err){
console.error('获取位置失败:', err);
},
complete(){
api_frontstorelist();
}
});
};
//
const api_frontstorelist=()=>{
if(latitude.value && longitude.value){
const params = {
latitude:latitude.value,
longitude:longitude.value,
page:1,
limit:1
}
return frontstorelist(params).then(({data}) => {
if(!storeName.value){storeName.value = data.list[0].name;}
})
.then(()=>api_index())
.catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}else{
api_index();
}
}
const decs = ref('');
const ishomeListLoaded = ref(false);
//
const api_index=()=>{
ishomeListLoaded.value = false;
loads('', true)
return frontindex().then(({data}) => {
uni.hideLoading();
homeList.value = data.homeList;
ishomeListLoaded.value = true;
})
.catch(({message}) => {
uni.hideLoading();
ishomeListLoaded.value = true;
uni.showModal({
content:message,
showCancel: false
@ -182,11 +149,47 @@ const addCart=(i,type)=>{
}else{
specTypes = productInfo.specType;
}
if(specTypes){
console.log('多规格弹窗选类加购');
}else{
console.log('单规格直接加购')
api_skudetail(specTypes,jumpIds);
}
// specTypes truefalse
const api_skudetail=(specTypes,jumpIds)=>{
loads('', true)
return skudetail(jumpIds).then(({data}) => {
if(specTypes){
}else{
const { id,productId } = data.productValue.默认;
api_cartsave(productId,id);
}
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
const api_cartsave = (productId,productAttrUnique) =>{
const params = {
cartNum:1,
productId,
productAttrUnique
}
return cartsave(params).then(({message})=>{
uni.hideLoading()
uni.showToast({
title:'添加购物车成功',
icon:'none'
})
})
.catch(({message}) => {
uni.hideLoading()
uni.showModal({
content:message,
showCancel: false
})
})
}
const orderConfirm=()=>{
uni.navigateTo({
@ -209,6 +212,7 @@ const goCarts=()=>{
})
}
const location=()=>{
if(locationShow.value) return false;
uni.navigateTo({
url:`/userserve/location/location`
})
@ -219,8 +223,7 @@ const onSearch=()=>{
})
}
onLoad((options) => {
// wxlogin()
getLocation()
api_index();
});
onShow(() => {});
onPullDownRefresh(()=>{

View File

@ -16,6 +16,7 @@ page{
background-repeat: no-repeat; /* 防止重复 */
background-size:100%;
padding-bottom: 5px;
z-index: 88;
.head_location{
display: flex;
align-items: center;
@ -128,7 +129,7 @@ page{
.grid_wrap_l{
width: 338rpx;
height: 338rpx;
background-color: #000000;
background-color: #999999;
border-radius: 20rpx;
overflow: hidden;
position: relative;
@ -224,10 +225,9 @@ page{
background-color: #FFFFFF;
border-radius: 20rpx;
overflow: hidden;
padding-bottom: 30rpx;
display: inline-block;
margin-left: 20rpx;
// box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(0, 0, 0, 0.05);
height: 900rpx;
.scroll_view_banner{
width: 100%;
height: 340rpx;

View File

@ -1,30 +1,29 @@
<template>
<view class="mian">
<image class="banner" src="../../static/sidedish/banner.jpg" mode="widthFix"></image>
<image class="banner" :src="wishesImage" lazy-load mode="widthFix"></image>
<view class="class_content">
<view class="class_scroll">
<view class="class_scroll" v-if="navList.length">
<scroll-view
:enhanced="true"
:show-scrollbar="false"
scroll-x="true"
:scroll-with-animation="true"
:scroll-left="ScrollLeft"
:scroll-left="scrollLefter"
class="class_scroll_ul">
<view class="class_item class_item_active">推荐</view>
<view class="class_item">特惠专区</view>
<view class="class_item">时令春菜</view>
<view class="class_item">鸭货卤味</view>
<view class="class_item">/鹅肉类</view>
<view class="class_item">轻食萨拉</view>
<view class="class_item ">猪肉类</view>
<view class="class_item"
v-for="(item,index) in navList"
:key="index"
:class="currentTab == index ? 'class_item_active' : '' "
@click="swichNav(item,index)"
>{{item.name}}</view>
</scroll-view>
</view>
<view class="content">
<view class="content_item">
<view class="content" v-if="navList.length">
<view class="content_item" v-for="(list,i) in productList" :key="i">
<view class="content_head">
<view class="content_head_l">
<image class="content_head_img" src="../../static/sidedish/flame.png"></image>
<view class="content_head_title">鲜花人气榜</view>
<view class="content_head_title">{{list.title}}</view>
</view>
<view class="content_head_btn">
<image class="content_head_btnimg" src="../../static/sidedish/addCart.png"></image>
@ -32,67 +31,22 @@
</view>
<view class="content_shop">
<scroll-view class="content_shop_ul" :scroll-with-animation="true" :enhanced="true" :show-scrollbar="false" scroll-x="true">
<view class="content_shop_item" @click="goDetail()">
<view class="content_shop_item" v-for="(item,index) in list.items" :key="index" @click="JumpType(item)">
<view class="content_shop_item_img">
<!-- <view class="content_shop_item_tag"></view> -->
<image class="content_shop_item_tag" src="../../static/sidedish/no1.png"></image>
<image class="content_shop_item_imgUrl" src="../../static/Mask.png" mode="widthFix"></image>
<image v-if="index <= 2" class="content_shop_item_tag" :src="`../../static/sidedish/no${index+1}.png`"></image>
<view v-else class="content_shop_item_tagImg">{{index + 1}}</view>
<image class="content_shop_item_imgUrl" :src="item.productInfo.image" lazy-load mode="widthFix"></image>
</view>
<view class="content_shop_item_title">火锅配菜青菜</view>
<view class="content_shop_item_title">{{item.productInfo.storeName}}</view>
<view class="content_shop_item_bottom">
<view class="content_shop_item_l">
<view class="content_shop_item_price price">39.9</view>
<view class="content_shop_market prices">59.9</view>
<view class="content_shop_item_price price">{{item.productInfo.price}}</view>
<view class="content_shop_market prices">{{item.productInfo.otPrice}}</view>
</view>
<view class="content_shop_item_cart">
<image class="content_shop_item_cart_img" src="../../static/oncatr01.png" mode="widthFix"></image>
</view>
</view>
</view>
<view class="content_shop_item" @click="goDetail()">
<view class="content_shop_item_img">
<image class="content_shop_item_tag" src="../../static/sidedish/no2.png"></image>
<image class="content_shop_item_imgUrl" src="../../static/Mask.png" mode="widthFix"></image>
</view>
<view class="content_shop_item_title">火锅配菜青菜</view>
<view class="content_shop_item_bottom">
<view class="content_shop_item_l">
<view class="content_shop_item_price price">39.9</view>
<view class="content_shop_market prices">59.9</view>
</view>
<view class="content_shop_item_cart">
<image class="content_shop_item_cart_img" src="../../static/oncatr01.png" mode="widthFix"></image>
</view>
</view>
</view>
<view class="content_shop_item" @click="goDetail()">
<view class="content_shop_item_img">
<image class="content_shop_item_tag" src="../../static/sidedish/no3.png"></image>
<image class="content_shop_item_imgUrl" src="../../static/Mask.png" mode="widthFix"></image>
</view>
<view class="content_shop_item_title">火锅配菜青菜</view>
<view class="content_shop_item_bottom">
<view class="content_shop_item_l">
<view class="content_shop_item_price price">39.9</view>
<view class="content_shop_market prices">59.9</view>
</view>
<view class="content_shop_item_cart">
<image class="content_shop_item_cart_img" src="../../static/oncatr01.png" mode="widthFix"></image>
</view>
</view>
</view>
<view class="content_shop_item" @click="goDetail()">
<view class="content_shop_item_img">
<view class="content_shop_item_tagImg">4</view>
<image class="content_shop_item_imgUrl" src="../../static/Mask.png" mode="widthFix"></image>
</view>
<view class="content_shop_item_title">火锅配菜青菜</view>
<view class="content_shop_item_bottom">
<view class="content_shop_item_l">
<view class="content_shop_item_price price">39.9</view>
<view class="content_shop_market prices">59.9</view>
</view>
<view class="content_shop_item_cart">
<view class="content_shop_item_cart" @click.stop="addCart(item)">
<image class="content_shop_item_cart_img" src="../../static/oncatr01.png" mode="widthFix"></image>
</view>
</view>
@ -100,37 +54,147 @@
</scroll-view>
</view>
</view>
<view class="load_desc">{{decs}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { loads } from '@/utils/index.js'
import { computed,ref } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onReachBottom } from "@dcloudio/uni-app"
import { frontindex,frontType,frontHome } from '@/server/api';
const counterStore = useCounterStore(); // 使 Store
const ScrollLeft = ref(0);
const pageWidth = ref(0);
const navList = ref([]);
const currentItem = ref({});
const currentTab = ref(0);
const productList = ref([]);
const pages = ref(0);
const decs = ref("");
const load = ref(true);
const scrollLefter = ref(0);
const windowWidth = ref(0);
const wishesImage = ref('')
//使piniastoreToRefs(使)
// const { count,doubleCount } = storeToRefs(counterStore);
const goDetail= ()=>{
uni.navigateTo({
url:`/shopProDetail/detail/detail`
const { storeId } = storeToRefs(counterStore);
const api_index=()=>{
loads('', true)
return frontindex().then(({data}) => {
wishesImage.value = data.wishesImage
})
.then(()=>api_frontType())
.catch(({message}) => {
uni.hideLoading();
uni.showModal({
content:message,
showCancel: false
})
})
}
const swichNav = (item,index) => {
const cur = index;
const scrollLefters = pageWidth.value / 5;
currentItem.value = item;
if (currentTab.value == cur) return false
currentTab.value = cur;
scrollLefter.value = (cur - 1) * scrollLefters;
api_frontHome(true);
}
const api_frontType = () => {
const storeIds = storeId.value;
const params = {
storeId:storeIds,
limit:20,
page:1
}
return frontType(params).then(({data})=>{
navList.value = data.list;
currentItem.value = data.list[0];
if(data.list.length){
api_frontHome(false,1)
}
})
}
const api_frontHome = (e,i) => {
if(e){
productList.value = [];
decs.value = '';
pages.value = 0;
}
decs.value = "—— 加载中... ——";
pages.value = pages.value + 1;
const params = {
channel:'2',
cid:currentItem.value.cid,
page:pages.value,
limit:10
}
if(i == 1){loads('', true)}
return frontHome(params).then(({data})=>{
if(i == 1){uni.hideLoading()}
decs.value = '—— 上拉加载更多 ——'
if(data.list.length < 10){
decs.value = '—— 嗷呜,已经到底啦 ——';
}
productList.value = productList.value.concat(data.list);
})
.catch(({message}) => {
if(i == 1){uni.hideLoading()}
uni.showModal({
content:message,
showCancel: false
})
})
}
//
const JumpType=(item,type)=>{
const { jumpUrl,jumpIds,jumpType } = item;
if(jumpType == 0 || jumpType == 2 || jumpType == 4) return false;
console.log('jumpType',jumpType)
console.log('jumpIds',jumpIds)
if(jumpType == 1){
uni.navigateTo({
url:`/shopProDetail/detail/detail?id=${jumpIds}`//
})
}else if(jumpType == 3){
uni.switchTab({
url:`/pages/classify/classify`//
})
}
}
//
const addCart=(i)=>{
const { jumpIds,productInfo,specType } = i;
const specTypes = productInfo.specType;
if(specTypes){
console.log('多规格弹窗选类加购');
}else{
console.log('单规格直接加购')
}
}
//
const updatePageWidth = () => {
const systemInfo = uni.getSystemInfoSync();
pageWidth.value = systemInfo.windowWidth;
};
onLoad((options) => {
updatePageWidth();
api_index();
});
onShow(() => {
});
onPullDownRefresh(()=>{
api_frontHome(true);
uni.stopPullDownRefresh();
})
onReachBottom(()=>{
api_frontHome(false);
})
</script>

View File

@ -1,5 +1,5 @@
page{
background-color: #151517;
// background-color: #151517;
}
.mian{
.banner{
@ -11,6 +11,7 @@ page{
background-color: #393333;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
margin-top: -60rpx;
.class_scroll{
white-space: nowrap;
height: 90rpx;
@ -113,6 +114,7 @@ page{
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.content_shop_item_tagImg{
width: 50rpx;
@ -127,6 +129,7 @@ page{
line-height: 44rpx;
font-size: 20rpx;
color: #FFFFFF;
z-index: 2;
}
.content_shop_item_imgUrl{
width: 200rpx;
@ -135,6 +138,7 @@ page{
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
}
.content_shop_item_title{
@ -197,6 +201,13 @@ page{
}
}
}
.load_desc{
font-size: 28rpx;
color: #fef6d8;
text-align: center;
padding-top: 30rpx;
padding-bottom: 30rpx;
}
}
}
@keyframes scaleDr{

View File

@ -1,40 +1,129 @@
import { request } from '@/utils/http'
//首页楼层接口
//首页滚动商品
export const frontindex = (data) => {
return request({url:`api/front/index`, method: 'GET',data});
};
//首页列表数据
return request({url:`/api/front/index`,method:'GET',data});
}
//首页/推荐列表数据
export const frontproduct = (type,data) => {
return request({url:`api/front/product/${type}`, method: 'GET',data});
};
return request({url:`/api/front/product/${type}`,method:'GET',data});
}
//商品详情接口
export const frontdetail = (type) => {
return request({url:`api/front/product/detail/${type}`, method: 'GET'});
};
return request({url:`/api/front/product/detail/${type}`,method:'GET'});
}
//商品详情评论列表
export const replyproduct = (type) => {
return request({url:`api/front/reply/product/${type}`, method: 'GET'});
};
return request({url:`/api/front/reply/product/${type}`,method: 'GET'});
}
//商品评论数量
export const replyconfig = (type) => {
return request({url:`api/front/reply/config/${type}`, method: 'GET'});
};
return request({url:`/api/front/reply/config/${type}`,method:'GET'});
}
export const replylist = (data) => {
return request({url:`api/front/reply/list`, method: 'GET',data});
};
return request({url:`/api/front/reply/list`,method:'GET',data});
}
//商品规格详情
export const skudetail = (id) => {
return request({url:`/api/front/product/sku/detail/${id}`,method:'GET'});
}
//详情常见问题
export const frontproblem = (type,data) => {
return request({url:`api/front/problem/${type}`, method: 'GET',data});
};
return request({url:`/api/front/problem/${type}`,method:'GET',data});
}
//获取门店
export const frontstorelist = (data) => {
return request({url:`api/front/store/list`, method: 'POST',data});
};
return request({url:`/api/front/store/list`,method:'POST',data});
}
//获取分类导航
export const frontcategory = () =>{
return request({url:`/api/front/category/top`,method:'GET'})
}
//获取分类商品
export const frontproducts = (data) =>{
return request({url:`/api/front/products`,method:'GET',data})
}
//获取随心配导航
export const frontType = (data) =>{
return request({url:`/api/front/home/setMeal/type`,method:'GET',data})
}
//帮您配商品
export const frontHome = (data) =>{
return request({url:`/api/front/home/floor`,method:'GET',data})
}
//客户中心/帮助中心分类
export const helpcategory = () =>{
return request({url:`/api/front/help/category/list`,method:'GET'})
}
//客户中心/帮助中心列表
export const helplist = (cid,data) =>{
return request({url:`/api/front/help/list/${cid}`,method:'GET',data})
}
//客户中心/帮助中心详情
export const helpinfo = (data) =>{
return request({url:`/api/front/help/info`,method:'GET',data})
}
//客户中心/帮助中心详情点击解决未解决
export const helppraise = (data) =>{
return request({url:`/api/front/help/praise`,method:'GET',data})
}
//加入购物车
export const cartsave = (data) => {
return request({url:`/api/front/cart/save`,method:'POST',data});
}
//购物车列表
export const cartlist = (data) => {
return request({url:`/api/front/cart/list`,method:'GET',data});
}
//购物车修改数量
export const cartnum = (id,number) => {
return request({url:`/api/front/cart/num?id=${id}&number=${number}`,method:'POST',contenttype:'x-www-form-urlencoded'});
}
//购物车删除
export const cartdelete = (ids) => {
return request({url:`/api/front/cart/delete?ids=${ids}`,method:'POST',contenttype:'x-www-form-urlencoded'});
}
//购物车选中接口
export const optForCart = (data)=>{
return request({url:`/api/front/cart/optForCart`,method:'POST',data})
}
//预下单
export const preorder = (data) => {
return request({url:`/api/front/order/pre/order`,method:'POST',data});
}
//加载预下单
export const orderloadpre = (preOrderNo) =>{
return request({url:`/api/front/order/load/pre/${preOrderNo}`,method:'GET'})
}
//地址列表
export const addresslist = (data) => {
return request({url:`/api/front/address/list`,method:'GET',data});
}
//地址保存
export const addressedit = (data) => {
return request({url:`/api/front/address/edit`,method:'POST',data});
}
//地址详情{id}
export const addressdetail = (id) =>{
return request({url:`/api/front/address/detail/${id}`,method:'GET'})
}
//地址删除
export const addressdel = (data) => {
return request({url:`/api/front/address/del`,method:'POST',data});
}
//设置默认地址
export const defaultset = (data) => {
return request({url:`/api/front/address/default/set`,method:'POST',data});
}
//获取默认地址
export const addressdefault = (data) => {
return request({url:`/api/front/address/default`,method:'GET',data});
}
//省市区
export const citylist = (data) => {
return request({url:`/api/front/city/list`,method:'GET',data});
}
//配送时间
export const deliverytimes = (data) => {
return request({url:`/api/front/delivery/times`,method:'GET',data});
}

View File

@ -9,7 +9,7 @@ const type = 'dev'
* prod生产
*/
if(type === 'dev'){
url = "http://vpwy6w.natappfree.cc/";
url = "http://xx2qui.natappfree.cc";
}
if(type === 'test'){
url = "https://japiuat.3721zh.com/webapp";

View File

@ -12,7 +12,7 @@
<view class="head_item_img"></view>
</view>
</view>
<view class="head_search" :style="{'width': statusHeight+'px','height':statusHeight+'px'}">
<view class="head_search" :style="{'width': statusHeight+'px','height':statusHeight+'px'}" @click="onSearch">
<image :style="{'width': statusHeight-15+'px','height':statusHeight-15+'px'}" src="../../static/search_img.png" mode="widthFix"></image>
</view>
</block>
@ -34,8 +34,8 @@
<image @click="Openqc" class="shop_qc" src="../../static/shopdetail/qc.png" mode="widthFix"></image>
</view>
<!-- 价格标题区域 -->
<view class="shop_head">
<view class="shop_price price" v-if="productInfo.price">{{productInfo.price}}<text class="market_name prices">{{productInfo.otPrice}}</text></view>
<view class="shop_head" v-if="productInfo.price">
<view class="shop_price price">{{productInfo.price}}<text class="market_name prices">{{productInfo.otPrice}}</text></view>
<view class="shop_title">{{productInfo.storeName}}</view>
<view class="shop_desc">{{productInfo.storeInfo}}</view>
</view>
@ -142,7 +142,7 @@ const onSwiperChange=(event)=>{
const previewImage=(i)=>{
uni.previewImage({
current: i,
urls:imglist.value
urls:sliderImages.value
});
};
//
@ -229,6 +229,11 @@ const api_detail=(id)=>{
})
})
}
const onSearch=()=>{
uni.navigateTo({
url:`/userserve/SearchProduct/SearchProduct`
})
}
onLoad((options) => {
const { id } = options;
//

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

BIN
static/Empty/cart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
static/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/resolved.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
static/resolved_arr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
static/unsolved.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
static/unsolved_arr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -12,8 +12,13 @@ export const useCounterStore = defineStore('counter',()=>{
const statusBartop = ref(uni.getMenuButtonBoundingClientRect()['top']);
const ButtonWidth = ref(uni.getMenuButtonBoundingClientRect().width);
const ButtonHeight = ref(uni.getMenuButtonBoundingClientRect().height)
const storeName = ref('')
const storeName = ref('');
const storeId = ref('');
const token = ref(uni.getStorageSync('token') || '');
const latitude = ref('');
const longitude = ref('');
const locationName = ref('正在获取定位');
const locationShow = ref(false);
// 设置 Token
const setToken = (tokens,uids,phones,nikeNames) => {
token.value = tokens;
@ -29,6 +34,7 @@ export const useCounterStore = defineStore('counter',()=>{
};
//以对象的形式return供组件调用
return{
storeId,
storeName,
nikeName,
key,
@ -42,5 +48,9 @@ export const useCounterStore = defineStore('counter',()=>{
statusHeight,
headerHeight,
statusBartop,
latitude,
longitude,
locationName,
locationShow
}
})

View File

@ -2,26 +2,10 @@
<view class="main">
<view class="adderss_cont">
<view class="adderss_item">
<view class="adderss_name">地址</view>
<view class="adderss_r ">
<view class="adderss_text adderss_arr">
<input class="adderss_input" type="text" placeholder="选择地址"/>
</view>
</view>
</view>
<view class="adderss_item">
<view class="adderss_name">门牌号</view>
<view class="adderss_name">联系人</view>
<view class="adderss_r">
<view class="adderss_text">
<input class="adderss_input" type="text" placeholder="例:15栋3层301室"/>
</view>
</view>
</view>
<view class="adderss_item">
<view class="adderss_name">收货人</view>
<view class="adderss_r">
<view class="adderss_text">
<input class="adderss_input" type="text" placeholder="收货人姓名"/>
<input class="adderss_input" v-model="realName" type="text" placeholder="收货人姓名"/>
</view>
<view class="adderss_type">
<view class="adderss_type_item"><view class="adderss_type_select adderss_acty"><image class="adderss_acty_img" src="../../static/selected.png"></image></view>先生</view>
@ -33,12 +17,28 @@
<view class="adderss_name">手机号</view>
<view class="adderss_r">
<view class="adderss_text">
<input class="adderss_input" type="text" placeholder="收货人手机号"/>
<input class="adderss_input" v-model="phone" type="text" placeholder="收货人手机号"/>
</view>
</view>
</view>
<view class="adderss_item">
<view class="adderss_name">所在的地区</view>
<view class="adderss_r ">
<view class="adderss_text adderss_arr" @click="OpenAddress()">
<input class="adderss_input" v-model="address_text" disabled="true" type="text" placeholder="省、市、区"/>
</view>
</view>
</view>
<view class="adderss_item">
<view class="adderss_name">详细地址</view>
<view class="adderss_r ">
<view class="adderss_text">
<textarea class="adderss_textarea" :disable-default-padding="isIos" v-model="detail" type="text" placeholder="小区、门牌号"></textarea>
</view>
</view>
</view>
</view>
<view class="adderss_cont">
<view class="adderss_cont" v-if="!address_isDefault">
<view class="adderss_default">
<view class="adderss_default_l">
<view class="adderss_default_title">设为默认地址</view>
@ -51,8 +51,37 @@
</view>
<view style="height: 200rpx;"></view>
<view class="footer">
<view class="footer_btn" @click="save">保存地址</view>
<view class="footer_btn" :class="edit?'widths':''" @click="save">保存地址</view>
<view v-if="edit" class="footer_btn footer_border" :class="edit?'widths':''" @click="removeCart">删除地址</view>
</view>
<uni-popup ref="addressPopup" type="bottom" @change="changeAddress">
<view class="address_pup">
<view class="address_head">请选择地区<view class="address_open_close" @click="OpenAddress()"><image src="../../static/order/close.png" mode="widthFix"></image></view></view>
<view class="address_cont" v-if="province_v">
<view class="address_name" :class="hover == 1?'address_hover':''" @click="switchover(1)">{{province_v}}</view>
<block v-if="city_v">
<view class="address_x">-</view>
<view class="address_name" :class="hover == 2?'address_hover':''" @click="switchover(2)">{{city_v}}</view>
</block>
<block v-if="district_v">
<view class="address_x">-</view>
<view class="address_name" :class="hover == 3?'address_hover':''" @click="switchover(3)">{{district_v}}</view>
</block>
</view>
<view class="address_select">选择省份/地区</view>
<view class="address_list">
<block v-if="address_id === '1'">
<view class="address_list_item" v-for="(item,index) in cityData" :key="index" @click="addressClick(1,item)">{{item.name}}</view>
</block>
<block v-if="address_id === '2'">
<view class="address_list_item" v-for="(item,index) in citylists" :key="index" @click="addressClick(2,item)">{{item.name}}</view>
</block>
<block v-if="address_id === '3'">
<view class="address_list_item" v-for="(item,index) in districtlist" :key="index" @click="addressClick(3,item)">{{item.name}}</view>
</block>
</view>
</view>
</uni-popup>
</view>
</template>
@ -61,16 +90,224 @@ import { computed,ref,onMounted,onUnmounted,getCurrentInstance,nextTick } from '
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { citylist,addressedit,addressdetail,addressdel } from "@/server/api.js"
const counterStore = useCounterStore(); // 使 Store
const { proxy } = getCurrentInstance();
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop } = storeToRefs(counterStore);
const save=()=>{
const cityId = ref('');
const province = ref('')
const city = ref('')
const district = ref('')
const province_v = ref('')
const city_v = ref('')
const district_v = ref('')
const addressShow = ref(false);
const addressPopup = ref(null);
const hover = ref('1');
const address_id = ref('1')
const cityData = ref([]);
const citylists = ref([]);
const districtlist = ref([]);
const address_text = ref('');
const isDefault = ref(1);
const detail = ref('');
const phone = ref('');
const realName = ref('');
const id = ref('');
const isIos = ref(false);
const edit = ref(false);
const address_isDefault = ref(false);
const isDefaultShow = computed(() => {
return address_isDefault.value?true:false;
});
const System = () =>{
const phone = wx.getSystemInfoSync();
if (phone.platform == 'ios') {
isIos.value = true
} else if (phone.platform == 'android') {
isIos.value = false
}
};
const api_citylist=()=>{
return citylist().then(({data}) => {
cityData.value = data;
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
const OpenAddress=()=>{
addressShow.value ? addressPopup.value.close():addressPopup.value.open()
}
const changeAddress = (e)=>{
addressShow.value = e.show;
}
const removeCart=()=>{
const params = {
id:id.value
}
return addressdel(params).then(({message}) => {
uni.showToast({
title:message,
icon:'success',
success: () => {
setTimeout(()=>{
uni.navigateBack({
delta:1
})
},1400)
}
onLoad((options) => {});
})
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
const addressClick = (type,item) =>{
cityId.value = item.cityId;
if(type == 1){
address_id.value = '2'
hover.value = '1';
province.value = item.name;
province_v.value = item.name;
citylists.value = item.child;
}else if(type == 2){
address_id.value = '3'
hover.value = '2';
city.value = item.name;
city_v.value = item.name;
districtlist.value = item.child
}else{
hover.value = '3';
district.value = item.name;
district_v.value = item.name;
OpenAddress();
}
address_text.value = province.value + city.value + district.value;
}
const switchover = (type) =>{
if(hover.value == type) return false;
if(type == 1){
address_id.value = '1'
hover.value = '1';
}else if(type == 2){
address_id.value = '2'
hover.value = '2';
}else{
address_id.value = '3'
hover.value = '3';
}
}
const api_addressdetail = () =>{
return addressdetail(id.value).then(({data}) => {
phone.value = data.phone;
realName.value = data.realName;
province.value = data.province;
city.value = data.city;
district.value = data.district;
detail.value = data.detail;
address_text.value = province.value + city.value + district.value;
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
const save=()=>{
if(!realName.value){
uni.showToast({
title:'联系不能为空!',
icon:'none',
})
return false
}
if(!phone.value){
uni.showToast({
title:'手机号不能为空!',
icon:'none',
})
return false
}
if(!province.value){
uni.showToast({
title:'请选择省!',
icon:'none',
})
return false
}
if(!city.value){
uni.showToast({
title:'请选择市!',
icon:'none',
})
return false
}
if(!district.value){
uni.showToast({
title:'请选择区/县',
icon:'none',
})
return false
}
if(!detail.value){
uni.showToast({
title:'详细地址不能为空',
icon:'none',
})
return false
}
const params = {
address: {
city:city.value,
district:district.value,
province:province.value
},
detail:detail.value,
isDefault:isDefault.value == 1?true:false,
phone:phone.value,
realName:realName.value
}
if(id.value){
params.id = id.value
}
if(cityId.value){
params.address.cityId = cityId.value
}
return addressedit(params).then(({message}) => {
uni.showToast({
title:message,
icon:'success',
success: () => {
setTimeout(()=>{
uni.navigateBack({
delta:1
})
},1400)
}
})
}).catch(({message}) => {
uni.showToast({
title:message,
icon:'none',
})
})
}
onLoad((options) => {
const { edits,ids,address_isDefaults } = options;
if(ids){id.value = ids;}
if(address_isDefaults){address_isDefault.value = address_isDefaults}
System();
api_citylist();
if(edits){edit.value = edits;api_addressdetail();}
});
onShow(() => {});
onReady(()=>{})
onPullDownRefresh(()=>{})

View File

@ -20,7 +20,7 @@ page{
height: 95rpx;
display: flex;
align-items: center;
width: 120rpx;
width: 140rpx;
}
.adderss_r{
width: 480rpx;
@ -34,6 +34,16 @@ page{
display: flex;
align-items: center;
}
.adderss_textarea{
width: 440rpx;
font-size: 28rpx;
margin: 15rpx 0 15rpx 0;
padding: 20rpx;
height: 100rpx;
background-color: #f6f6f6;
border-radius: 10rpx;
}
}
.adderss_arr::after{
content: '';
@ -81,6 +91,9 @@ page{
}
}
}
.adderss_item:last-child {
border-bottom: none;
}
.adderss_default{
display: flex;
align-items: center;
@ -109,7 +122,7 @@ page{
left: 0;
right: 0;
bottom: 0;
z-index: 160;
z-index: 88;
background: #FFFFFF;
font-size: 30rpx;
padding-bottom: env(safe-area-inset-bottom);
@ -124,6 +137,7 @@ page{
width: 100%;
height: 85rpx;
background-color: #fd3f3f;
border:1rpx solid #fd3f3f;
border-radius: 50rpx;
color: #fff;
display: flex;
@ -132,5 +146,93 @@ page{
font-weight: 500;
font-size: 28rpx;
}
.footer_border{
width: 100%;
height: 85rpx;
background-color: #f6f6f6;
border:1rpx solid #D9D9D9;
border-radius: 50rpx;
color: #333333;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
font-size: 28rpx;
}
.widths{
width:48%;
}
}
}
.address_pup{
background-color: #FFFFFF;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
.address_head{
text-align: center;
font-size: 30rpx;
color: #333333;
font-weight: 500;
height: 85rpx;
line-height: 85rpx;
position: relative;
.address_open_close{
position: absolute;
width: 85rpx;
height: 85rpx;
right: 0rpx;
top: 0rpx;
display: flex;
align-items: center;
justify-content: center;
}
.address_open_close image{
width: 60rpx;
height: 60rpx;
}
}
.address_cont{
display: flex;
align-items: center;
padding:20rpx 20rpx 40rpx 20rpx;
border-bottom: 1rpx solid #D9D9D9;
.address_name{
font-size: 28rpx;
color: #333333;
padding: 10rpx 30rpx 10rpx 30rpx;
border:1rpx solid #f7f8fc;
background-color: #f7f8fc;
border-radius: 8rpx;
}
.address_hover{
font-size: 28rpx;
color: #ff0f23;
padding: 10rpx 30rpx 10rpx 30rpx;
border:1rpx solid #ff0f23;
background-color: #ffebf1;
border-radius: 8rpx;
}
.address_x{
color: #c2c4cc;
margin-left: 10rpx;
margin-right: 10rpx;
}
}
.address_select{
font-size: 30rpx;
font-weight: 500;
color: #333333;
padding: 20rpx;
}
.address_list{
padding: 0 20rpx 0 20rpx;
height: 700rpx;
overflow-y: auto;
.address_list_item{
font-size: 30rpx;
color: #333333;
height: 80rpx;
line-height: 80rpx;
}
}
}

View File

@ -1,30 +1,22 @@
<template>
<view class="main">
<view class="location_cont location_padding">
<view class="location_list flex" @click="addressBack">
<uni-swipe-action>
<uni-swipe-action-item v-for="(item,index) in list" :key="index" :right-options="options" @click="removeCart(item)">
<view class="location_list flex" :class="index != list.length - 1?'location_border':''" @click.stop="select_address(item)">
<view class="location_l">
<view class="location_address">
<text class="location_default">默认</text>
<text class="location_address_text">汤臣一品-20号楼2306室</text>
<text class="location_default" v-if="item.isDefault">默认</text>
<text class="location_address_text">{{item.province+item.city+item.district+item.detail}}</text>
</view>
<view class="location_user"><text class="location_user_name">悟语先生</text><text class="location_user_tel">15221678099</text></view>
<view class="location_user"><text class="location_user_name">{{item.realName}}</text><text class="location_user_tel">{{item.phone}}</text></view>
</view>
<view class="location_r" @click="revamp()">
<view class="location_r" @click.stop="revamp(item)">
<image class="location_img" src="../../static/userserve/edit.png"></image>
</view>
</view>
<view class="location_list flex" @click="addressBack">
<view class="location_l">
<view class="location_address">
<text class="location_address_text">花木街道浦东新区机关事务管理局人民政府-20号楼2306室</text>
</view>
<view class="location_user"><text class="location_user_name">悟语先生</text><text class="location_user_tel">15221678099</text></view>
</view>
<view class="location_r" @click="revamp()">
<image class="location_img" src="../../static/userserve/edit.png"></image>
</view>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<view style="height: 200rpx;"></view>
<view class="footer">
@ -38,27 +30,129 @@ import { computed,ref,onMounted,onUnmounted,getCurrentInstance,nextTick } from '
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { addresslist,addressdel,defaultset } from "@/server/api.js"
const counterStore = useCounterStore(); // 使 Store
const { proxy } = getCurrentInstance();
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop } = storeToRefs(counterStore);
const pages = ref(0);
const limits = ref(10);
const decs = ref('');
const list = ref([]);
const address_isDefault = ref(false);
const options = ref([
{
text: '删除',
style: {
backgroundColor: '#FD4955'
}
}
]);
const api_addresslist=()=>{
pages.value = pages.value + 1;
decs.value = "—— 加载中... ——";
const params = {
page:pages.value,
limit:limits.value
}
return addresslist(params).then(({data}) => {
decs.value = '—— 上拉加载更多 ——'
if(data.list.length < 10){
decs.value = '—— 嗷呜,已经到底啦 ——';
}
list.value = list.value.concat(data.list);
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
const select_address=(item)=>{
if(!address_isDefault.value) return false;
const params = {
id:item.id
}
return addresslist(params).then(({message}) => {
uni.showToast({
title:message,
icon:'success',
success: () => {
setTimeout(()=>{
uni.navigateBack({
delta:1
})
},1400)
}
})
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
const addressEdit=()=>{
uni.navigateTo({
url:`/userserve/addressEdit/addressEdit`
})
};
const revamp=()=>{
const revamp=(item)=>{
const { id } = item;
uni.navigateTo({
url:`/userserve/addressEdit/addressEdit`
url:`/userserve/addressEdit/addressEdit?ids=${id}&edits=true`
})
}
onLoad((options) => {});
onShow(() => {});
const removeCart=(e)=>{
const params = {
id:e.id
}
return addressdel(params).then(({message}) => {
uni.showToast({
title:message,
icon:'success',
success: () => {
setTimeout(()=>{
list.value = list.value.filter(item => item.id !== e.id);
},1400)
}
})
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
onLoad((options) => {
const { address_isDefaults } = options;
if(address_isDefaults){
address_isDefault.value = address_isDefaults;
}
});
onShow(() => {
list.value = [];
decs.value = '';
pages.value = 0;
api_addresslist();
});
onReady(()=>{})
onPullDownRefresh(()=>{})
onReachBottom(()=>{})
onPullDownRefresh(()=>{
list.value = [];
decs.value = '';
pages.value = 0;
api_addresslist();
uni.stopPullDownRefresh();
})
onReachBottom(()=>{
api_addresslist();
})
</script>
<style lang="scss">
@import './style.scss';
.uni-swipe_box{
padding: 0rpx 30rpx 0rpx 30rpx !important;
}
</style>

View File

@ -4,21 +4,21 @@ page{
.main{
.location_cont{
margin: 20rpx 20rpx 0rpx 20rpx;
padding: 30rpx;
// padding: 30rpx;
background-color: #FFFFFF;
border-radius: 16rpx;
box-shadow: 0 4rpx 8rpx rgba(0,0,0,.05);
.location_list{
padding-top: 30rpx;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #D9D9D9;
.location_l{
.location_address{
min-height: 80rpx;
.location_default{
font-size: 20rpx;
background-color: rgba(249, 212, 72, 0.2);
background-color: #fdedee;
border-radius: 10rpx;
color: #F9D448;
color: #FF0000;
margin-right: 10rpx;
padding: 2rpx 10rpx;
vertical-align: middle;
@ -52,6 +52,9 @@ page{
}
}
}
.location_border{
border-bottom: 1rpx solid #D9D9D9;
}
}
.flex{
display: flex;
@ -59,7 +62,7 @@ page{
justify-content: space-between;
}
.location_padding{
padding: 0rpx 30rpx 0rpx 30rpx;
// padding: 0rpx 30rpx 0rpx 30rpx;
}
.footer{
position: fixed;

View File

@ -45,42 +45,24 @@
:show-scrollbar="false"
scroll-x="true"
:scroll-with-animation="true"
:scroll-left="ScrollLeft"
:scroll-left="scrollLefter"
class="class_scroll_ul">
<view class="class_item class_item_active">热门问题</view>
<view class="class_item">订单问题</view>
<view class="class_item">配送问题</view>
<view class="class_item">发票问题</view>
<view class="class_item">售后问题</view>
<view
v-for="(item,index) in navList"
:key="index"
class="class_item"
:class="currentTab == index ? 'class_item_active' : '' "
@click="swichNav(item,index)"
>{{item.name}}</view>
</scroll-view>
</view>
<view class="content_list" @click="detail()">
<view class="content_l">催单</view>
<template v-for="(item,index) in list" :key="index">
<view class="content_list" @click="detail(item)">
<view class="content_l">{{item.title}}</view>
<view class="content_r"></view>
</view>
<view class="content_list" @click="detail()">
<view class="content_l">怎么查询骑手电话</view>
<view class="content_r"></view>
</view>
<view class="content_list" @click="detail()">
<view class="content_l">如何取消订单</view>
<view class="content_r"></view>
</view>
<view class="content_list" @click="detail()">
<view class="content_l">商品需要售后</view>
<view class="content_r"></view>
</view>
<view class="content_list" @click="detail()">
<view class="content_l">修改订单信息收件人/时间/备注</view>
<view class="content_r"></view>
</view>
<view class="content_list" @click="detail()">
<view class="content_l">订单已完成但未收到货</view>
<view class="content_r"></view>
</view>
</template>
</view>
</view>
<view style="height: 200px;"></view>
@ -95,10 +77,12 @@
</template>
<script setup>
import { loads } from '@/utils/index.js'
import { computed,ref,onMounted,onUnmounted,getCurrentInstance,nextTick } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { helpcategory,helplist } from '@/server/api';
const counterStore = useCounterStore(); // 使 Store
const { proxy } = getCurrentInstance();
//使piniastoreToRefs(使)
@ -107,6 +91,64 @@ const headShow = ref(false);
const showBack = ref(false);
const pageWidth = ref(0);
const opacity = ref(1);
const navList = ref([]);
const currentItem = ref({});
const currentTab = ref(0);
const list = ref([]);
const pages = ref(0);
const decs = ref("");
const scrollLefter = ref(0);
const windowWidth = ref(0);
const swichNav = (item,index) => {
const cur = index;
const scrollLefters = pageWidth.value / 5;
currentItem.value = item;
if (currentTab.value == cur) return false
currentTab.value = cur;
scrollLefter.value = (cur - 1) * scrollLefters;
api_helplist(true);
}
const api_helpcategory = () => {
return helpcategory().then(({data})=>{
navList.value = data.list;
currentItem.value = data.list[0];
if(data.list.length){
api_helplist(false,1)
}
})
}
const api_helplist = (e,i) => {
if(e){
list.value = [];
decs.value = '';
pages.value = 0;
}
decs.value = "—— 加载中... ——";
pages.value = pages.value + 1;
const params = {
page:pages.value,
limit:10
}
if(i == 1){loads('', true)}
return helplist(currentItem.value.id,params).then(({data})=>{
if(i == 1){uni.hideLoading()}
decs.value = '—— 上拉加载更多 ——'
if(data.list.length < 10){
decs.value = '—— 嗷呜,已经到底啦 ——';
}
list.value = list.value.concat(data.list);
})
.catch(({message}) => {
if(i == 1){uni.hideLoading()}
uni.showModal({
content:message,
showCancel: false
})
})
}
//
const updatePageWidth = () => {
const systemInfo = uni.getSystemInfoSync();
@ -131,9 +173,10 @@ const handleBack = () => {
});
}
};
const detail=()=>{
const detail=(item)=>{
console.log('详情',item);
uni.navigateTo({
url:`/userserve/clientservedetail/clientservedetail`
url:`/userserve/clientservedetail/clientservedetail?id=${item.id}`
})
};
const handleContact=()=>{
@ -144,6 +187,7 @@ onLoad((options) => {
//
showBack.value = getPages();
updatePageWidth();
api_helpcategory();
});
onShow(() => {});
onPageScroll((e)=>{
@ -161,8 +205,13 @@ onPageScroll((e)=>{
}
}),
onReady(()=>{})
onPullDownRefresh(()=>{})
onReachBottom(()=>{})
onPullDownRefresh(()=>{
api_helpcategory(true);
uni.stopPullDownRefresh();
})
onReachBottom(()=>{
api_helpcategory(false)
})
</script>
<style lang="scss">

View File

@ -142,7 +142,7 @@ page{
top: 0;
z-index: 999;
margin-top: 10rpx;
margin-bottom: 25rpx;
margin-bottom: 20rpx;
.class_scroll_ul{
width: 100%;
overflow: hidden;
@ -214,6 +214,8 @@ page{
padding-left: 20rpx;
padding-right: 20rpx;
border-top: 1rpx solid #efefef;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
.footer_tel{
width: 100rpx;
.footer_telimg{
@ -233,9 +235,9 @@ page{
}
.footer_btn{
width: 553rpx;
height: 68rpx;
height: 80rpx;
text-align: center;
line-height: 68rpx;
line-height: 80rpx;
border-radius: 43rpx;
border: 1px solid #FD3F3F;
color: #FD3F3F;

View File

@ -1,8 +1,12 @@
<template>
<view class="main">
<view class="main_title">如何取消订单</view>
<view class="main_title">{{detail.title}}</view>
<view class="main_detail">
<text>请点击在首页右下角我的-查看全部订单-更多-取消订单\n\n 订单配送前支持取消整单商品不支持取消部分法恢复</text>
<text>{{detail.content}}</text>
</view>
<view class="bott">
<view class="bott_item" :class="detail.usefulNum ? 'bott_item_arr':''" @click="btnClick(1)"><image class="bott_item_img" :src="usefulNum"></image>已解决</view>
<view class="bott_item" :class="detail.uselessNum ? 'bott_item_arr':''" @click="btnClick(2)"><image class="bott_item_img" :src="uselessNum"></image>未解决</view>
</view>
</view>
</template>
@ -12,13 +16,62 @@ import { computed,ref,onMounted,onUnmounted,getCurrentInstance,nextTick } from '
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { helpinfo,helppraise } from '@/server/api'
const counterStore = useCounterStore(); // 使 Store
const { proxy } = getCurrentInstance();
const detailId = ref('');
const detail = ref({});
const usefulNum = ref('');
const uselessNum = ref('');
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop,ButtonWidth,ButtonHeight } = storeToRefs(counterStore);
const id = ref('');
const api_helpinfo = () => {
let params = {
id:detailId.value
}
return helpinfo(params).then(({data})=>{
detail.value = data;
if(data.usefulNum){
usefulNum.value = "../../static/resolved_arr.png"
}else{
usefulNum.value = "../../static/resolved.png"
}
if(data.uselessNum){
uselessNum.value = "../../static/unsolved_arr.png"
}else{
uselessNum.value = "../../static/unsolved.png"
}
})
}
const btnClick = (type) => {
const params = {
id:detailId.value,
type
}
return helppraise(params).then(({message})=>{
uni.showToast({
title:message,
icon:'success',
success: () => {
setTimeout(()=>{
api_helpinfo();
},1000)
}
})
})
.catch(({message}) => {
if(i == 1){uni.hideLoading()}
uni.showModal({
content:message,
showCancel: false
})
})
}
onLoad((options) => {
const { id } = options;
detailId.value = id;
api_helpinfo();
});
onShow(() => {});
onReady(()=>{})

View File

@ -17,4 +17,31 @@ page{
font-size: 28rpx;
margin-top: 30rpx;
}
.bott{
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 40rpx;
.bott_item{
width: 280rpx;
height: 75rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #333333;
border:1px solid #999999;
border-radius: 50rpx;
.bott_item_img{
width: 35rpx;
height: 35rpx;
margin-right: 10rpx;
}
}
.bott_item_arr{
color: #FF0000;
border:1px solid #FF0000;
background-color: rgba(255, 0, 0, 0.06);
}
}
}

View File

@ -1,25 +0,0 @@
<template>
<view class="main">
</view>
</template>
<script setup>
import { computed,ref,onMounted,onUnmounted,getCurrentInstance,nextTick } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
const counterStore = useCounterStore(); // 使 Store
const { proxy } = getCurrentInstance();
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop } = storeToRefs(counterStore);
onLoad((options) => {});
onShow(() => {});
onReady(()=>{})
onPullDownRefresh(()=>{})
onReachBottom(()=>{})
</script>
<style lang="scss">
@import './style.scss';
</style>

View File

@ -1,6 +0,0 @@
page{
background-color: #f6f6f6;
}
.main{
}

View File

@ -1,6 +1,6 @@
<template>
<view class="main">
<view class="location">
<!-- <view class="location">
<view class="location_title">当前定位</view>
</view>
<view class="location_cont flex">
@ -32,25 +32,19 @@
</view>
<view class="location_user"><text class="location_user_name">悟语先生</text><text class="location_user_tel">15221678099</text></view>
</view>
<!-- <view class="location_r"></view> -->
</view>
</view>
</view> -->
<view class="location">
<view class="location_title">附近地址</view>
<view class="location_title">附近门店</view>
</view>
<view class="location_cont location_padding">
<view class="location_item" @click="addressBack">浦茗荟(陆家嘴店)</view>
<view class="location_item" @click="addressBack">汇豪天下-7号楼</view>
<view class="location_item" @click="addressBack">臻邦游泳健身中心(财富海景店</view>
<view class="location_item" @click="addressBack">优涵游泳俱乐部·YHSC(财富海景店)</view>
<view class="location_item" @click="addressBack">财富海景花园-6号楼</view>
<view class="location_item" v-for="(item,index) in list" :key="index" :class="list.length > 1?'ocation_bottom':''" @click="addressBack(item)">{{item.name}}</view>
</view>
<view class="load_desc">{{decs}}</view>
<view style="height: 200rpx;"></view>
<view class="footer">
<!-- <view class="footer">
<view class="footer_btn" @click="addressEdit">新增地址</view>
</view>
</view> -->
</view>
</template>
@ -59,16 +53,68 @@ import { computed,ref,onMounted,onUnmounted,getCurrentInstance,nextTick } from '
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { frontstorelist } from '@/server/api';
const counterStore = useCounterStore(); // 使 Store
const { proxy } = getCurrentInstance();
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop } = storeToRefs(counterStore);
const {statusHeight,headerHeight,statusBartop,storeName,storeId } = storeToRefs(counterStore);
const pages = ref(0);
const limits = ref(10);
const latitude = ref('');
const longitude = ref('');
const list = ref([]);
const decs = ref('');
//
const getLocation = () => {
//
uni.getLocation({
type: 'gcj02',
success(res){
latitude.value = res.latitude;
longitude.value = res.latitude;
},
fail(err){
console.error('获取位置失败:', err);
},
complete(){
api_frontstorelist();
}
});
};
//
const api_frontstorelist=()=>{
pages.value = pages.value + 1;
decs.value = "—— 加载中... ——";
const params = {
page:pages.value,
limit:limits.value
}
if(latitude.value && longitude.value){
params.latitude = latitude.value;
params.longitude = longitude.value
}
return frontstorelist(params).then(({data}) => {
decs.value = '—— 上拉加载更多 ——';
if(data.list.length < 10){
decs.value = '—— 更多门店敬请期待 ——';
}
list.value = list.value.concat(data.list);
})
.catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
const addressList=()=>{
uni.navigateTo({
url:`/userserve/addressList/addressList`
})
};
const addressBack=()=>{
const addressBack=(item)=>{
storeName.value = item.name;
storeId.value = item.id;
uni.navigateBack({
delta:1
})
@ -81,11 +127,21 @@ const addressEdit=()=>{
url:`/userserve/addressEdit/addressEdit`
})
};
onLoad((options) => {});
onLoad((options) => {
getLocation();
});
onShow(() => {});
onReady(()=>{})
onPullDownRefresh(()=>{})
onReachBottom(()=>{})
onPullDownRefresh(()=>{
list.value = [];
decs.value = '';
pages.value = 0;
api_frontstorelist();
uni.stopPullDownRefresh();
})
onReachBottom(()=>{
api_frontstorelist();
})
</script>
<style lang="scss">

View File

@ -101,6 +101,9 @@ page{
font-weight: 500;
color: #333333;
padding: 30rpx 0 30rpx 0;
}
.location_bottom{
border-bottom: 1rpx solid #D9D9D9;
}
}
@ -115,6 +118,13 @@ page{
.location_padding{
padding: 0rpx 30rpx 0rpx 30rpx;
}
.load_desc{
font-size: 28rpx;
color: #aaa;
text-align: center;
padding-top: 30rpx;
padding-bottom: 30rpx;
}
.footer{
position: fixed;
left: 0;

View File

@ -13,7 +13,7 @@ const refreshToken = async () => {
//1. 获取微信 code
const { code } = await uni.login({ provider: 'weixin'});
const res = await uni.request({
url: `${url}api/front/wechat/authorize/program/login?code=${code}`,
url: `${url}/api/front/wechat/authorize/program/login?code=${code}`,
method: 'POST',
data: {}
});
@ -37,7 +37,7 @@ export const request = async (options) => {
method: options.method || 'GET',
data: options.data || {},
header: {
'Content-Type': 'application/json',
'Content-Type': options.contenttype ||'application/json',
'Authori-zation':`${currentToken}`
},
success: (res) => {
@ -65,7 +65,7 @@ export const request = async (options) => {
requestsQueue.push(() => resolve(_request()));
} else {
console.log('报错啦',res);
reject(res)
reject(res.data)
}
},
fail: (err) => reject(err)