接口封装方法优化

This commit is contained in:
邝军华 2025-04-01 12:05:30 +08:00
parent 0b02dc7458
commit 933e20c695
28 changed files with 308 additions and 811 deletions

View File

@ -33,8 +33,8 @@
<view class="shop_comment_head_arrow">全部</view>
</view>
<view class="faqlist">
<view class="shop_ask shop_padding"><text>{{productProblem.content}}</text></view>
<!-- <view class="shop_answer shop_padding"><text>虾头中含有一种叫做酪氨酸酶的酶当虾死亡后这种酶会催化虾体内的酪氨酸生成黑色素导致虾头变黑这是一种自然现象通常不影响虾肉的食用安全</text></view> -->
<view class="shop_ask shop_padding"><text>{{productProblem.title}}</text></view>
<view class="shop_answer shop_padding"><text>{{productProblem.content}}</text></view>
</view>
</view>
</template>
@ -44,18 +44,17 @@
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
import { onLoad,onShow,onPullDownRefresh,onPageScroll,onReachBottom,onReady } from "@dcloudio/uni-app"
import { replyconfig,replyproduct } from '@/server/api'
const counterStore = useCounterStore(); // 使 Store
//使piniastoreToRefs(使)
const { token } = storeToRefs(counterStore);
//使piniacounterStore
const { replyconfig,replyproduct } = counterStore;
const problemNum = ref('');
const problemNum = ref(0);
const productProblem = ref({});
const productReply = ref({});
const replyChance = ref('');
const reviewTags = ref([]);
const picsCount = ref('');
const sumCount = ref('');
const sumCount = ref(0);
const props = defineProps({
apiType:{
type:Number,
@ -63,8 +62,7 @@
}
})
const api_replyproduct=()=>{
const params = {}
return replyproduct(props.apiType,params,token.value).then(({data}) => {
return replyproduct(props.apiType).then(({data}) => {
problemNum.value = data.problemNum;
productProblem.value = data.productProblem;
if(data.sumCount){
@ -89,8 +87,7 @@
})
}
const api_replyconfig=()=>{
const params = {}
return replyconfig(props.apiType,params,token.value).then(({data}) => {
return replyconfig(props.apiType).then(({data}) => {
reviewTags.value = data.reviewTags;
picsCount.value = data.picsCount;
sumCount.value = data.sumCount;

View File

@ -83,6 +83,7 @@
</template>
<script setup>
import { frontproduct } from '@/server/api';
import { computed,ref,onMounted } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
import { storeToRefs } from 'pinia';//
@ -90,8 +91,6 @@
const counterStore = useCounterStore(); // 使 Store
//使piniastoreToRefs(使)
const { token } = storeToRefs(counterStore);
//使piniacounterStore
const { frontproduct } = counterStore;
const shopList = ref([]);
const total = ref(0);
const decs = ref('');
@ -106,26 +105,20 @@
const api_product=()=>{
pages.value = pages.value + 1;
decs.value = "—— 加载中... ——";
if(shopList.value.length > 0 && shopList.value.length >= total.value){
decs.value = "—— 嗷呜,已经到底啦 ——";
return false
}
const params = {
page:pages.value,
limit:limits.value
}
return frontproduct(props.apiType,params,token.value).then(({data}) => {
return frontproduct(props.apiType,params).then(({data}) => {
total.value = data.total;
decs.value = '—— 上拉加载更多 ——'
data.list.forEach((item,index)=>{
item.isEven = index % 2 === 0
})
shopList.value = shopList.value.concat(data.list);
if(shopList.value < total.value){
decs.value = '—— 上拉加载更多 ——'
}else{
if(data.list.length < 10){
decs.value = '—— 嗷呜,已经到底啦 ——';
}
shopList.value = shopList.value.concat(data.list);
}).catch(({message}) => {
uni.showModal({
content:message,
@ -253,7 +246,7 @@
.shop_view_img{
// width: 100%;
position: relative;
padding: 10rpx;
padding: 10rpx 10rpx 0rpx 10rpx;
.shop_view_tag{
width: 66rpx;
height: 42rpx;

View File

@ -1,10 +1,8 @@
import { createSSRApp } from 'vue'
// import store from './store' // 如果使用Vuex等状态管理库则需要引入store等配置项。
import { createPinia } from 'pinia'; // 引入 Pinia
import App from './App.vue'
// 创建 Pinia 实例
const pinia = createPinia();
export function createApp() {
const app = createSSRApp(App) // 使用createSSRApp创建应用实例对于小程序很重要
// 使用 Pinia

View File

@ -60,9 +60,10 @@
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "将获取您的具体位置信息,用于门店和您之间的距离以变您进行消费"
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
}
}
},
"requiredPrivateInfos" : [ "getLocation" ]
},
"mp-alipay" : {
"usingComponents" : true

View File

@ -17,7 +17,7 @@
</view>
</view>
</view>
<view class="order_cont" :style="{'padding-top':statusHeight+headerHeight+65+'px'}">
<view class="order_cont" :style="{'padding-top':statusHeight+headerHeight+61+'px'}">
<view class="order_list" @click="orderDetail()">
<view class="order_type">已完成</view>
<view class="order_time">2025/1/15 17:20 周三</view>

View File

@ -124,127 +124,9 @@
</view> -->
</view>
</view>
<view class="user_title" v-if="!showEdit">
<text class="user_name">为您推荐</text>
</view>
<!-- 商品区域 -->
<view class="shop_view" v-if="!showEdit">
<view class="shop_view_ul">
<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>
<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">
<image class="shop_view_cont_cart_img" src="../../static/oncatr02.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</view>
<view class="shop_view_ul">
<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>
<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>
</view>
<template v-if="!showEdit">
<recomGoods v-if="token" :apiType="5"></recomGoods>
</template>
<view style="height: 200rpx;"></view>
<view class="footer">
<view class="footer_l">
@ -316,13 +198,14 @@
</template>
<script setup>
import recomGoods from '@/components/recomGoods/recomGoods.vue';
import { ref,computed } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
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 } = storeToRefs(counterStore);
const {statusHeight,headerHeight,token } = storeToRefs(counterStore);
const couponPopup = ref(null);
const couponShow = ref(false);
const show = ref(false);

View File

@ -341,158 +341,7 @@ page{
}
}
.user_title{
display: flex;
align-items: center;
justify-content: center;
margin-top: 60rpx;
.user_name{
color: #FF0000;
font-size: 36rpx;
font-weight: 500;
margin: 0 10rpx 0 10rpx;
vertical-align: middle;
display: inline-block;
}
}
.user_title::before{
content: "";
vertical-align: middle;
display: inline-block;
width: 30rpx;
height: 30rpx;
background-image: url('../../static/user/leftimg.png');
background-size: cover;
margin-right: 10rpx;
}
.user_title::after{
vertical-align: middle;
content: "";
display: inline-block;
width: 30rpx;
height: 30rpx;
background-image: url('../../static/user/rightimg.png');
background-size: cover;
margin-left: 10rpx;
}
// 商品区域样式
.shop_view{
margin-top: 10rpx;
padding: 13rpx 20rpx 0rpx 20rpx;
display: flex;
justify-content: space-between;
.shop_view_ul{
width: 346rpx;
.shop_view_li{
background-color: #FFFFFF;
border-radius: 20rpx;
width: 100%;
box-shadow: 0 4rpx 8rpx rgba(0,0,0,.05);
margin-bottom: 20rpx;
.shop_view_li_swiper{
width: 100%;
height: 504rpx;
.shop_view_li_swiper_item{
width: 100%;
.shop_view_li_swiper_img_url{
width: 100%;
height: 504rpx;
display: block;
border-radius: 20rpx;
}
}
}
.shop_view_img{
width: 100%;
position: relative;
height: 320rpx;
.shop_view_tag{
width: 66rpx;
height: 42rpx;
position: absolute;
z-index: 2;
right: -15rpx;
top: 20rpx;
background: url(../../static/tag_img.png);
background-repeat: no-repeat;
background-size: 100% 100%;
.shop_view_tag_text{
font-size: 20rpx;
color: #FFFFFF;
height: 30rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.shop_view_img_u{
width: 300rpx;
position: absolute;
z-index: 1;
left: 20rpx;
top: 20rpx;
.shop_view_img_url{
width: 100%;
height: 300rpx;
display: block;
}
}
}
.shop_view_cont{
padding: 20rpx;
.shop_view_cont_title{
font-size: 28rpx;
font-weight: 500;
color: #000000;
min-height: 80rpx;
}
.shop_view_cont_desc{
color: #666666;
font-size: 24rpx;
}
.shop_view_cont_tag{
display: flex;
flex-wrap: wrap;
.shop_view_cont_tag_text{
border-radius: 6rpx;
border: 1px solid #FF6868;
padding: 0rpx 10rpx;
border-radius: 10rpx;
color: #ff6868;
font-size: 18rpx;
margin-top: 10rpx;
margin-right: 10rpx;
}
}
}
.shop_view_cont_bottom{
display: flex;
align-items: center;
justify-content: space-between;
.shop_view_cont_price{
font-size: 32rpx;
color: red;
font-weight: 500;
}
.shop_view_cont_cart{
width: 65rpx;
height: 65rpx;
display: flex;
align-items: center;
justify-content: flex-end;
.shop_view_cont_cart_img{
width: 40rpx;
height: 40rpx;
display: block;
}
}
}
}
.shop_view_bcg{
background-color: inherit;
}
}
}
.footer{
position: fixed;
z-index: 88;

View File

@ -2,7 +2,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_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="请输入搜索内容" />
@ -11,7 +11,7 @@
</view>
<!-- 推荐区域 -->
<view class="grid_top">
<view class="head_fixed" :style="{'height':statusHeight+headerHeight+43+'px'}">下拉刷新...</view>
<view class="head_fixed" :style="{'height':statusHeight+headerHeight+47+'px'}">下拉刷新...</view>
<view class="grid_wrap">
<view class="grid_wrap_l">
<image class="grid_wrap_live" src=""></image>
@ -35,6 +35,8 @@
</view>
</view>
</view>
<!-- 滚动区域 -->
<view class="scroll_view">
<scroll-view class="typescoll" :scroll-with-animation="true" :enhanced="true" :show-scrollbar="false" scroll-x="true">
@ -65,6 +67,7 @@
</view>
<!-- 商品区域 -->
<recomGoods v-if="token" :apiType="1"></recomGoods>
<view style="height: 200rpx;"></view>
<view class="footer">
<view class="footer_cont">
@ -85,6 +88,7 @@
</template>
<script setup>
import { frontindex,frontproduct,frontstorelist } from '@/server/api';
import recomGoods from '@/components/recomGoods/recomGoods.vue';
import { computed,ref } from 'vue';
import { useCounterStore } from '@/store/counter'; // Pinia Store
@ -92,42 +96,55 @@ 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 } = storeToRefs(counterStore);
//使piniacounterStore
const { wechatlogin,frontindex,frontproduct } = counterStore;
const {statusHeight,headerHeight,nikeName,key,token,phone,uid,storeName } = storeToRefs(counterStore);
const homeList = ref([]);
const shopList = ref([]);
const total = ref(0);
const pages = ref(0);
const limits = ref(10);
const decs = ref('')
//code
const wxlogin=()=>{
uni.login({
provider:'weixin',
success: ({code}) => {
console.log('code',code);
api_login(code);
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();
}
})
}
//api
const api_login=(code)=>{
const params = {}
return wechatlogin(params,code).then(({data}) => {
nikeName.value = data.nikeName
key.value = data.key
token.value = data.token
phone.value = data.phone
uid.value = data.uid
})
.then(()=>api_index())
.catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
});
};
//
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 api_index=()=>{
@ -201,7 +218,10 @@ const onSearch=()=>{
url:`/userserve/SearchProduct/SearchProduct`
})
}
onLoad((options) => {wxlogin()});
onLoad((options) => {
// wxlogin()
getLocation()
});
onShow(() => {});
onPullDownRefresh(()=>{
api_index();

View File

@ -2,7 +2,7 @@ page{
background-color: #F6F6F6;
}
.main{
background: url('https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/bcges.jpg');
background: url('https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/bcges.png');
background-repeat: no-repeat; /* 防止重复 */
background-size:100%;
// 头部样式
@ -15,7 +15,7 @@ page{
background: url('https://zhkj1.oss-cn-shanghai.aliyuncs.com/zhscMerchant/bcges.jpg');
background-repeat: no-repeat; /* 防止重复 */
background-size:100%;
padding-bottom: 10px;
padding-bottom: 5px;
.head_location{
display: flex;
align-items: center;
@ -121,7 +121,7 @@ page{
padding-bottom: 10px;
}
.grid_wrap{
padding: 20rpx 20rpx 20rpx 20rpx;
padding: 10rpx 20rpx 20rpx 20rpx;
display: flex;
justify-content: space-between;

View File

@ -151,159 +151,6 @@ page{
box-shadow: -10rpx 0 10rpx -5rpx rgba(244, 244, 244, 0.8); /* 左边框阴影 */
}
}
.user_title{
display: flex;
align-items: center;
justify-content: center;
margin-top: 60rpx;
.user_name{
color: #FF0000;
font-size: 36rpx;
font-weight: 500;
margin: 0 10rpx 0 10rpx;
vertical-align: middle;
display: inline-block;
}
}
.user_title::before{
content: "";
vertical-align: middle;
display: inline-block;
width: 30rpx;
height: 30rpx;
background-image: url('../../static/user/leftimg.png');
background-size: cover;
margin-right: 10rpx;
}
.user_title::after{
vertical-align: middle;
content: "";
display: inline-block;
width: 30rpx;
height: 30rpx;
background-image: url('../../static/user/rightimg.png');
background-size: cover;
margin-left: 10rpx;
}
// 商品区域样式
.shop_view{
margin-top: 10rpx;
padding: 13rpx 20rpx 0rpx 20rpx;
display: flex;
justify-content: space-between;
.shop_view_ul{
width: 346rpx;
.shop_view_li{
background-color: #FFFFFF;
border-radius: 20rpx;
width: 100%;
box-shadow: 0 4rpx 8rpx rgba(0,0,0,.05);
margin-bottom: 20rpx;
.shop_view_li_swiper{
width: 100%;
height: 504rpx;
.shop_view_li_swiper_item{
width: 100%;
.shop_view_li_swiper_img_url{
width: 100%;
height: 504rpx;
display: block;
border-radius: 20rpx;
}
}
}
.shop_view_img{
width: 100%;
position: relative;
height: 320rpx;
.shop_view_tag{
width: 66rpx;
height: 42rpx;
position: absolute;
z-index: 2;
right: -15rpx;
top: 20rpx;
background: url(../../static/tag_img.png);
background-repeat: no-repeat;
background-size: 100% 100%;
.shop_view_tag_text{
font-size: 20rpx;
color: #FFFFFF;
height: 30rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.shop_view_img_u{
width: 300rpx;
position: absolute;
z-index: 1;
left: 20rpx;
top: 20rpx;
.shop_view_img_url{
width: 100%;
height: 300rpx;
display: block;
}
}
}
.shop_view_cont{
padding: 20rpx;
.shop_view_cont_title{
font-size: 28rpx;
font-weight: 500;
color: #000000;
min-height: 80rpx;
}
.shop_view_cont_desc{
color: #666666;
font-size: 24rpx;
}
.shop_view_cont_tag{
display: flex;
flex-wrap: wrap;
.shop_view_cont_tag_text{
border-radius: 6rpx;
border: 1px solid #FF6868;
padding: 0rpx 10rpx;
border-radius: 10rpx;
color: #ff6868;
font-size: 18rpx;
margin-top: 10rpx;
margin-right: 10rpx;
}
}
}
.shop_view_cont_bottom{
display: flex;
align-items: center;
justify-content: space-between;
.shop_view_cont_price{
font-size: 32rpx;
color: red;
font-weight: 500;
}
.shop_view_cont_cart{
width: 65rpx;
height: 65rpx;
display: flex;
align-items: center;
justify-content: flex-end;
.shop_view_cont_cart_img{
width: 40rpx;
height: 40rpx;
display: block;
}
}
}
}
.shop_view_bcg{
background-color: inherit;
}
}
}
.price::before {
content: '¥';
font-size: 24rpx;

View File

@ -48,141 +48,22 @@
<view class="user_cont_li_name">{{item.name}}</view>
</view>
</view>
<view class="user_title">
<text class="user_name">为您推荐</text>
</view>
<!-- 商品区域 -->
<view class="shop_view">
<view class="shop_view_ul">
<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>
<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">
<image class="shop_view_cont_cart_img" src="../../static/oncatr02.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</view>
<view class="shop_view_ul">
<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>
<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>
</view>
<recomGoods v-if="token" :apiType="5"></recomGoods>
<view style="height: 200rpx;"></view>
</view>
</template>
<script setup>
import recomGoods from '@/components/recomGoods/recomGoods.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
const statusHeight = ref(uni.getMenuButtonBoundingClientRect()['height'])
const headerHeight = ref(uni.getSystemInfoSync()['statusBarHeight'])
//使piniastoreToRefs(使)
const { statusHeight,headerHeight,token } = storeToRefs(counterStore);
// const statusHeight = ref(uni.getMenuButtonBoundingClientRect()['height'])
// const headerHeight = ref(uni.getSystemInfoSync()['statusBarHeight'])
const order = ref([
{
id:1,

40
server/api.js Normal file
View File

@ -0,0 +1,40 @@
import { request } from '@/utils/http'
//首页楼层接口
export const frontindex = (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});
};
//商品详情接口
export const frontdetail = (type) => {
return request({url:`api/front/product/detail/${type}`, method: 'GET'});
};
//商品详情评论列表
export const replyproduct = (type) => {
return request({url:`api/front/reply/product/${type}`, method: 'GET'});
};
//商品评论数量
export const replyconfig = (type) => {
return request({url:`api/front/reply/config/${type}`, method: 'GET'});
};
export const replylist = (data) => {
return request({url:`api/front/reply/list`, method: 'GET',data});
};
//详情常见问题
export const frontproblem = (type,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});
};

View File

@ -1,47 +0,0 @@
import { url } from './config'
import {signGen} from "@/utils"
function _request(options, showErrorModal = true) {
return new Promise((resolve, reject)=> {
uni.request(options).then(({data}) => {
if(data.code === 200){
resolve(data)
}else{
reject(data);
}
}).catch((err) => {
reject(err);
})
})
}
export const apiService = {
query(path, query,token,sign = false) {
return _request({
url: url + path,
data: sign ? signGen(query) : query,
header: {
'Authori-zation':token
}
})
},
get(path, query,token,sign = false) {
return _request({
url: url + path,
data:sign ? signGen(query) : query,
header: {
'Authori-zation':token
}
})
},
post(path,params,token,sign = false,showErrorModal = true) {
return _request({
url: url + path,
data:sign ? signGen(params) : params,
method: 'POST',
header: {
'Authori-zation':token
}
}, showErrorModal)
}
}

View File

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

View File

@ -23,8 +23,8 @@
<view class="shop_swiper" :style="{'height':swiperHeight+'rpx'}" >
<swiper class="shop_swiper_wrap" interval="3000" :current="currentIndex" circular @change="onSwiperChange" :style="{'height':swiperHeight+'rpx'}">
<swiper-item class="shop_swiper_marquees" v-if="sliderImages.length" v-for="(item,index) in sliderImages" :key="index">
<view class="shop_swiper_img">
<image class="shop_swiper_imgUrl" :src="item" lazy-load @load="onImageLoad" @click="previewImage(index)"></image>
<view class="shop_swiper_img" :style="{'height':swiperHeight+'rpx'}">
<image class="shop_swiper_imgUrl" :src="item" lazy-load @load="onImageLoad" @click="previewImage(index)" :style="{'height':swiperHeight+'rpx'}"></image>
</view>
</swiper-item>
</swiper>
@ -35,14 +35,14 @@
</view>
<!-- 价格标题区域 -->
<view class="shop_head">
<view class="shop_price price">{{productInfo.price}}<text class="market_name prices">{{productInfo.otPrice}}</text></view>
<view class="shop_price price" v-if="productInfo.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>
</view>
<!-- 评论区域 -->
<view class="item">
<comment v-if="token && productId" :apiType="productId"></comment>
<comment v-if="productId" :apiType="productId"></comment>
</view>
<!-- 图文详情 -->
<view class="shop_detail item">
@ -52,7 +52,7 @@
</view>
</view>
<view class="item">
<recomGoods v-if="token" :apiType="5"></recomGoods>
<recomGoods :apiType="5"></recomGoods>
</view>
<view style="height: 200rpx;"></view>
<!-- 底部 -->
@ -91,6 +91,7 @@
</template>
<script setup>
import { loads } from '@/utils/index.js'
import recomGoods from '@/components/recomGoods/recomGoods.vue';
import comment from '@/components/comment/comment.vue';
import { computed,ref,onMounted,onUnmounted,getCurrentInstance,nextTick } from 'vue';
@ -102,7 +103,7 @@ const { proxy } = getCurrentInstance();
const qcPopup = ref(null);
const qcShow = ref(false);
const show = ref(false);
const swiperHeight = ref(200);
const swiperHeight = ref(750);
const imgheights = ref([]);
const currentIndex = ref(0);
const showBack = ref(false);
@ -121,8 +122,7 @@ const content = ref('');
const productId = ref('');
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop,token } = storeToRefs(counterStore);
//使piniacounterStore
const { frontdetail } = counterStore;
import { frontdetail } from '@/server/api'
const Openqc =() =>{
qcShow.value ? qcPopup.value.close():qcPopup.value.open()
};
@ -211,8 +211,9 @@ const orderConfirm = ()=>{
const api_detail=(id)=>{
const params = {}
return frontdetail(id,params,token.value).then(({data}) => {
loads('', true);
return frontdetail(id).then(({data}) => {
uni.hideLoading();
productAttr.value = data.productAttr;
productInfo.value = data;
productValue.value = data.productValue;
@ -221,6 +222,7 @@ const api_detail=(id)=>{
content.value = data.content.replace(/\<img|\width:[^;]+;/gi,'<img style="width:100%;height:auto;display:block;" ');
}
}).catch(({message}) => {
uni.hideLoading();
uni.showModal({
content:message,
showCancel: false

View File

@ -85,14 +85,14 @@ page{
height: 100%;
.shop_swiper_img{
width: 100%;
height: 100%;
height: 750rpx;
.shop_swiper_video_list{
width: 100%;
height: 100%;
height: 750rpx;
}
.shop_swiper_imgUrl{
width: 100%;
height: 100%;
height: 750rpx;
}
}
}

View File

@ -63,8 +63,7 @@ const counterStore = useCounterStore(); // 使用 Store
const { proxy } = getCurrentInstance();
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop,token } = storeToRefs(counterStore);
//使piniacounterStore
const { replyconfig,replylist } = counterStore;
import { replyconfig,replylist } from '@/server/api'
const productId = ref('');//id
const havePics = ref('');//1
const latest = ref('');//1
@ -87,7 +86,7 @@ const referClick=(item,index)=>{
latest.value = '';
tag.value = '';
type.type = 0;
}else if(index == 1){
}else if(index == 1 && item.tag == '图片'){
havePics.value = 1;
latest.value = '';
tag.value = '';
@ -110,8 +109,7 @@ const referClick=(item,index)=>{
api_replylist()
}
const api_replyconfig=()=>{
const params = {}
return replyconfig(productId.value,params,token.value).then(({data}) => {
return replyconfig(productId.value).then(({data}) => {
let arr = [
{tag:"全部",num:data.sumCount},
{tag:'最新',num:0,imgUrl:'../../static/eval/newest.png'},
@ -172,7 +170,7 @@ const api_replylist=()=>{
}else{
params.type = type.value;
}
return replylist(params,token.value).then(({data}) => {
return replylist(params).then(({data}) => {
total.value = data.total;
decs.value = '—— 上拉加载更多 ——'
data.list.forEach((item,index)=>{

View File

@ -1,15 +1,9 @@
<template>
<view class="mian">
<view class="faqlist">
<view class="shop_ask shop_padding"><text>有的虾头发黑是为什么?</text></view>
<view class="shop_answer shop_padding"><text>虾头中含有一种叫做酪氨酸酶的酶当虾死亡后这种酶会催化虾体内的酪氨酸生成黑色素导致虾头变黑这是一种自然现象通常不影响虾肉的食用安全</text></view>
<view class="faqlist" v-for="(item,index) in List" :key="index">
<view class="shop_ask shop_padding"><text>{{item.title}}</text></view>
<view class="shop_answer shop_padding"><text>{{item.content}}</text></view>
</view>
<view class="faqlist">
<view class="shop_ask shop_padding"><text>有的虾头发黑是为什么?</text></view>
<view class="shop_answer shop_padding"><text>虾头中含有一种叫做酪氨酸酶的酶当虾死亡后这种酶会催化虾体内的酪氨酸生成黑色素导致虾头变黑这是一种自然现象通常不影响虾肉的食用安全</text></view>
</view>
</view>
</template>
@ -18,16 +12,64 @@ 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 { frontproblem } from '@/server/api'
const counterStore = useCounterStore(); // 使 Store
const { proxy } = getCurrentInstance();
//使piniastoreToRefs(使)
const {statusHeight,headerHeight,statusBartop } = storeToRefs(counterStore);
onLoad((options) => {});
const { token } = storeToRefs(counterStore);
const List = ref([]);
const total = ref(0);
const decs = ref('');
const pages = ref(0);
const limits = ref(10);
const productIds = ref('');
const api_frontproblem=()=>{
pages.value = pages.value + 1;
decs.value = "—— 加载中... ——";
if(List.value.length > 0 && List.value.length >= total.value){
decs.value = "—— 嗷呜,已经到底啦 ——";
return false
}
const params = {
page:pages.value,
limit:limits.value
}
return frontproblem(productIds.value,params).then(({data}) => {
total.value = data.total;
decs.value = '—— 上拉加载更多 ——'
List.value = List.value.concat(data.list);
if(List.value < List.value){
decs.value = '—— 上拉加载更多 ——'
}else{
decs.value = '—— 嗷呜,已经到底啦 ——';
}
}).catch(({message}) => {
uni.showModal({
content:message,
showCancel: false
})
})
}
onLoad((options) => {
const { productId } = options;
if(productId){
productIds.value = productId
}
api_frontproblem()
});
onShow(() => {});
onReady(()=>{})
onPullDownRefresh(()=>{})
onReachBottom(()=>{})
onPullDownRefresh(()=>{
List.value = [];
total.value = 0;
decs.value = '';
pages.value = 0;
api_frontproblem();
uni.stopPullDownRefresh();
})
onReachBottom(()=>{
api_frontproblem();
})
</script>
<style lang="scss">

View File

@ -3,7 +3,11 @@ page{
}
.mian{
.faqlist{
padding: 20rpx 20rpx 0rpx 20rpx;
padding: 20rpx 20rpx 20rpx 20rpx;
margin: 20rpx 20rpx 0rpx 20rpx;
background-color: #FFFFFF;
border-radius: 20rpx;
box-shadow: 0 4rpx 8rpx rgba(0,0,0,.05);
.shop_ask{
font-size: 30rpx;
color: #333333;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 13 KiB

BIN
static/bcges.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

BIN
static/bcges_副本.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

View File

@ -1,6 +1,5 @@
import { defineStore } from 'pinia';
import { computed,ref } from 'vue';
import { apiService } from "@/server/api.service";
export const useCounterStore = defineStore('counter',()=>{
//定义数据state)
const openId = ref('');
@ -8,47 +7,34 @@ export const useCounterStore = defineStore('counter',()=>{
const key = ref('');
const phone = ref('');
const uid = ref('');
const token = ref('');
const statusHeight = ref(uni.getMenuButtonBoundingClientRect()['height']);
const headerHeight = ref(uni.getSystemInfoSync()['statusBarHeight']);
const statusBartop = ref(uni.getMenuButtonBoundingClientRect()['top']);
const ButtonWidth = ref(uni.getMenuButtonBoundingClientRect().width);
const ButtonHeight = ref(uni.getMenuButtonBoundingClientRect().height)
//登录授权
const wechatlogin = (params,query)=>{
return apiService.post(`api/front/wechat/authorize/program/login?code=${query}`,params)
}
//首页楼层
const frontindex = (params)=>{
return apiService.get('api/front/index',params)
}
//首页列表数据
const frontproduct = (type,params,token)=>{
return apiService.get(`api/front/product/${type}`,params,token)
}
//商品详情接口
const frontdetail = (type,params,token)=>{
return apiService.get(`api/front/product/detail/${type}`,params,token)
}
//商品详情评论列表
const replyproduct = (type,params,token)=>{
return apiService.get(`api/front/reply/product/${type}`,params,token)
}
//商品评论数量
const replyconfig = (type,params,token)=>{
return apiService.get(`api/front/reply/config/${type}`,params,token)
}
//商品评论数量
const replylist = (params,token)=>{
return apiService.get(`api/front/reply/list`,params,token)
}
const storeName = ref('')
const token = ref(uni.getStorageSync('token') || '');
// 设置 Token
const setToken = (tokens,uids,phones,nikeNames) => {
token.value = tokens;
uid.value = uids;
phone.value = phones;
nikeName.value = nikeNames;
uni.setStorageSync('token', tokens);
};
// 清除 Token
const clearToken = () => {
token.value = '';
uni.removeStorageSync('token');
};
//以对象的形式return供组件调用
return{
storeName,
nikeName,
key,
token,
token,
setToken,
clearToken,
phone,
uid,
ButtonWidth,
@ -56,12 +42,5 @@ export const useCounterStore = defineStore('counter',()=>{
statusHeight,
headerHeight,
statusBartop,
wechatlogin,
frontindex,
frontproduct,
frontdetail,
replyproduct,
replyconfig,
replylist
}
})

View File

@ -1,44 +0,0 @@
import { createStore } from 'vuex';
import { apiService } from "@/server/api.service"
// 创建 Vuex Store
const store = createStore({
state: {
count: 0, // 示例状态
userInfo: null // 用户信息
},
mutations: {
// 修改状态的方法
increment(state) {
state.count++;
},
setUserInfo(state, userInfo) {
state.userInfo = userInfo;
}
},
actions: {
// 异步操作
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
},
fetchUserInfo({ commit }, userId) {
// 模拟异步请求
return new Promise((resolve) => {
setTimeout(() => {
const userInfo = { id: userId, name: 'John Doe' };
commit('setUserInfo', userInfo);
resolve(userInfo);
}, 1000);
});
}
},
getters: {
// 计算属性
doubleCount(state) {
return state.count * 2;
}
}
});
export default store;

80
utils/http.js Normal file
View File

@ -0,0 +1,80 @@
// utils/http.js
import { ref } from 'vue';
import { url } from '@/server/config.js'
import { useCounterStore } from '@/store/counter';
const authStore = useCounterStore();
let isRefreshing = false;// 是否正在刷新 Token
let requestsQueue = [];// 等待队列
let retryCount = 0;// 当前重试次数
/**
* 刷新 Token
*/
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}`,
method: 'POST',
data: {}
});
const { token,uid,phone,nikeName } = res.data.data;
//成功:更新 Token 并重置重试计数
authStore.setToken(token,uid,phone,nikeName);
retryCount = 0;
return true;
};
/**
* 封装请求防死循环关键逻辑
*/
export const request = async (options) => {
//发起请求
const _request = () => {
return new Promise((resolve, reject) => {
//动态读取最新Token
const currentToken = authStore.token;
uni.request({
url:`${url}${options.url}` ,
method: options.method || 'GET',
data: options.data || {},
header: {
'Content-Type': 'application/json',
'Authori-zation':`${currentToken}`
},
success: (res) => {
const { code } = res.data;
if(code === 200){
resolve(res.data);
}else if (code === 401) {
//1. 如果正在刷新,加入队列等待
if (isRefreshing) {
requestsQueue.push(() => resolve(_request()));
return;
}
//2. 触发刷新 Token
isRefreshing = true;
refreshToken().then((success) => {
if (success) {
//刷新成功:重试队列中的请求
requestsQueue.forEach(cb => cb());
}
}).finally(() => {
isRefreshing = false;
requestsQueue = []; // 清空队列(无论成功与否)
});
// 3.当前请求加入队列
requestsQueue.push(() => resolve(_request()));
} else {
console.log('报错啦',res);
reject(res)
}
},
fail: (err) => reject(err)
});
});
};
try {
return await _request();
} catch (err) {
throw err;
}
};

View File

@ -1,33 +1,7 @@
import md5 from 'js-md5'
import qs from 'qs'
const appKey = "3721zhkj"
// 生成签名
function alphabeticalSort(a, b) {
return a.toUpperCase().localeCompare(b.toUpperCase());
}
function filterFunc(prefix, value) {
if (prefix === "dishOtherOrderItems" || prefix === "template"|| prefix==='productItems') {
const rel = value.map(item =>
`{${
qs.stringify(item, {
sort: alphabeticalSort,
delimiter: ",",
encode: false
})
}}`
);
return `[${rel.join(",")}]`
}
return value;
}
export const signGen = function(data) {
const str = qs.stringify(data, {
sort: alphabeticalSort,
encode: false,
filter: filterFunc
}) + '&key=' + appKey
let sign = md5(str).toUpperCase();
return Object.assign({
sign
}, data)
}
//加载load使用
export const loads = ((title, mask = false)=>{
return uni.showLoading({title,mask})
})