xiaokuaisong-xiaochengxu/uniapp04/pages/merchant/merchant.vue
2025-04-11 14:42:29 +08:00

1048 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import sort from "./sort.vue"
import Shopdetils from "./Shopdetails.vue"
import { apiImageUrl } from '../../API/api'
import { ref, onMounted, computed, onUnmounted, watch, nextTick } from 'vue'
import { url } from "inspector";
import { onShow } from "@dcloudio/uni-app";
const currentIndex = ref(0);
const tabs = ref([
{ name: '点餐' },
{ name: '评价' },
{ name: '商家信息' }
]);
const sortKey = ref(0);
const switchTab = (index) => {
currentIndex.value = index;
// 当切换到点餐时刷新sort组件
if (index === 0) {
sortKey.value++; // 每次切换时改变key值
}
};
//评论
const historyList = ref([])
const talk = () => {
uni.navigateTo({
url: '/pages/talk/talk'
})
}
const quantity = ref(1);
const showRight = ref(null);
const showDrawer = () => {
if (showRight.value) {
showRight.value.open();
}
};
const closeDrawer = () => {
if (showRight.value) {
showRight.value.close();
}
};
const isLiked = ref(false);
const collectState=()=>{
const businessItem=uni.getStorageSync("businessItem")
uni.request({
url:apiImageUrl+'/api/business/my/getById',
method:'GET',
data:{
businessId:businessItem
},
success(res) {
// console.log(res.data.data.isCollected);
// if(res.data.data.isCollected===true){
// const likeStarImg='../../static/small/starSelected.png'
// isLiked.value = false;
// }else if(res.data.data.isCollected===false){
// const likeStarImg='../../static/small/star.png'
// isLiked.value = true;
// }
isLiked.value = Boolean(res.data.data.isCollected);
},
fail(error) {
console.log(error);
}
})
}
onMounted(() => {
collectState()
});
const toggleLike = () => {
const originalState = isLiked.value;
// 立即切换状态提供即时反馈
isLiked.value = !originalState;
const action = originalState ? 'delete' : 'add';
uni.request({
url: `${apiImageUrl}/api/collect/${action}`,
method: 'POST',
data: {
businessId: uni.getStorageSync('businessItem') || '0'
},
header: {
'cookie': uni.getStorageSync("cookie") || ''
},
success(res) {
if (res.data.code !== 200) {
console.log(res);
// 操作失败时恢复原始状态
// isLiked.value = originalState;
// uni.showToast({
// title: res.data.msg || '操作失败',
// icon: 'none',
// duration: 2000
// });
// return;
}
uni.showToast({
title: originalState ? '已取消收藏' : '收藏成功',
duration: 2000
});
},
fail() {
// 请求失败时恢复原始状态
isLiked.value = originalState;
uni.showToast({
title: '网络错误,请重试',
icon: 'none',
duration: 2000
});
}
});
};
const cartItems = ref([]);
const updateCart = (newCartItems) => {
cartItems.value = newCartItems; // 更新购物车数据
console.log('更新后的购物车:', cartItems.value);
// cartItems.value = uni.getStorageSync('cartItems') || [];
uni.setStorageSync('cartItems', newCartItems);
};
onMounted(() => {
cartItems.value = uni.getStorageSync('cartItems') || [];
});
const deleteItem = (index) => {
cartItems.value.splice(index, 1);
uni.setStorageSync('cartItems', cartItems.value);
};
onMounted(() => {
cartItems.value = uni.getStorageSync('cartItems') || [];
});
const incrementQuantity = (index) => {
if (cartItems.value[index].quantity < 9) {
cartItems.value[index].quantity++;
}
};
const decrementQuantity = (index) => {
if (cartItems.value[index].quantity > 1) {
cartItems.value[index].quantity--;
}
};
// 计算金额
const totalAmount = computed(() => {
return cartItems.value.reduce((total, item) => {
return total + (item.dishesPrice * item.quantity);
}, 0);
});
const account = () => {
let businessid = uni.getStorageSync('businessItem') || '1830063677349658625';
const orderDetails = cartItems.value.map(item => ({
attributeNames: "小份",
dishesId: item.id,
quantity: item.quantity
}));
const data = {
businessId: String(businessid),
notes: "",
orderDetailAddRequest: orderDetails,
payMethod: 0,
phone: "15946398466",
pickupMethod: 0,
pickupTime: "",
totalPrice: totalAmount.value,
userName: "沙箱账号"
}
data.businessId = String(data.businessId)
uni.request({
url: apiImageUrl + '/api/orders/add',
method: 'POST',
data: data,
header: {
'cookie': uni.getStorageSync("cookie") || ''
},
success(res) {
console.log(res);
console.log('Success:', res.data.data);
const orderId = res.data.data;
//createPayment(orderId);
uni.setStorageSync("notPay",orderId);
uni.navigateTo({
url: '/pages/goToPay/goToPay'
});
},
fail() {
console.error('Error:', '请求失败');
}
});
};
const createPayment = (orderId) => {
console.log('Total amount to pay:', totalAmount.value);
my.request({
url: apiImageUrl + '/api/Alipay/payment/create',
method: 'GET',
data: {
id: orderId
},
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
success: function (result) {
console.log(result);
console.log(result.data.data);
uni.setStorageSync("tradeNo",result.data.data)
my.tradePay({
tradeNO: result.data.data,
success: (res) => {
console.log('成功调用')
console.log(res);
console.log(res.resultCode);
if(res.resultCode==6001){
console.log("我是6001");
uni.setStorageSync("notPay",orderId);
uni.navigateTo({
url: '/pages/goToPay/goToPay'
});
}
else if(res.resultCode==9000){
uni.setStorageSync('orderId', orderId);
uni.navigateTo({
url: '/pages/testFive/testFive'
});
}
},
fail: (res) => {
my.alert({
content: JSON.stringify(res),
})
console.log('失败');
console.log(res);
}
});
}
})
};
const merchantId = ref();
const getMerchantIdFromUrl = () => {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
console.log('Current page options:', currentPage.options);
if (currentPage && currentPage.options && currentPage.options.merchantId) {
merchantId.value = currentPage.options.merchantId;
console.log(`Merchant ID received: ${merchantId.value}`);
} else {
console.error('Could not retrieve merchantId from URL.');
}
};
onMounted(() => {
getMerchantIdFromUrl()
});
watch(merchantId, (newValue) => {
uni.$emit('merchantIdChanged', newValue);
});
/* shopdetail */
const businessMessage=ref(uni.getStorageSync("Mybusiness"))
console.log(businessMessage.value);
// 评论
const review=()=>{
const businessId=uni.getStorageSync("businessItem")
uni.request({
url:apiImageUrl+'/api/level/list/business',
method:'POST',
data:{
id:businessId
},
success(res) {
console.log(res.data.data);
historyList.value=res.data.data
},
fail() {
console.log("失败");
}
})
}
onMounted(() => {
review();
});
// 公告
// 定义响应式数据
const contentDetail = ref('');
// 定义异步请求的方法
const fetchContentItem = async () => {
const businessId = uni.getStorageSync("businessItem");
try {
const res = await uni.request({
url: apiImageUrl+'/api/businessInfo/list',
method: 'POST',
data: {
id: businessId,
}
});
console.log(res.data.data.content);
contentDetail.value = res.data.data.content; // 更新响应式变量
} catch (err) {
console.error(err);
}
};
// 页面加载时调用该方法
onMounted(() => {
fetchContentItem();
});
</script>
<template>
<scroll-view scroll-y class="preview">
<!-- 商户轮播图 -->
<view class="preview">
<swiper :circular="true" :autoplay="true" :interval="3000" indicator-dots>
<swiper-item>
<image mode="aspectFill" class="image"
src="https://ts1.cn.mm.bing.net/th/id/R-C.8f2db93b542db8adf6c850762c1cce4d?rik=erpuvqVy64IJzQ&riu=http%3a%2f%2fimg95.699pic.com%2fphoto%2f50044%2f9286.jpg_wh860.jpg&ehk=dnizwrPBuCaHnaxfih%2fryK7p%2fXZMbmolNORKknXvL%2bI%3d&risl=&pid=ImgRaw&r=0">
</image>
</swiper-item>
<swiper-item>
<image mode="aspectFill" class="image"
src="https://img95.699pic.com/photo/50127/2949.jpg_wh860.jpg"></image>
</swiper-item>
<swiper-item>
<image mode="aspectFill" class="image"
src="https://img95.699pic.com/photo/50070/9636.jpg_wh860.jpg"></image>
</swiper-item>
</swiper>
</view>
<!-- 店铺标题-->
<view class="priceTitle">
<view class="meta">
<text class="symbol">店铺详情</text>
</view>
</view>
<!-- 店铺公告 -->
<view class="notice">
<uni-notice-bar show-icon scrollable
:text="contentDetail" />
</view>
<!-- 商品详情 -->
<view class="tab-menu">
<view class="tab-item" v-for="(tab, index) in tabs" :key="index" :class="{active: currentIndex === index}"
@click="switchTab(index)">
{{ tab.name }}
</view>
</view>
<view class="content">
<block v-if="currentIndex === 0">
<sort
:key="sortKey"
@update-cart="updateCart"
:merchant-id="merchantId"
:active-tab="currentIndex"
></sort>
</block>
<block v-if="currentIndex === 1">
<view class="container">
<view class="history-list">
<view class="history-item" v-for="(item, index) in historyList" :key="index">
<view class="history-info">
<image class="history-img" src="https://tse4-mm.cn.bing.net/th/id/OIP-C.jHUH4s7TQ48X_B-1iozuJgHaHa?rs=1&pid=ImgDetMain"></image>
<view class="nameTime">
<text class="history-title">匿名用户</text>
<text class="time">{{ item.createTime.substr(0, 19).replace('T', ' ') }}</text>
</view>
<view class="star">
<text class="history-sale">{{ item.rating }}</text>
<uni-rate :readonly="true" :value="item.rating" active-color="#13c2c2" :is-fill="false"
color="#13c2c2"/>
</view>
</view>
<view class="extend">
<text @click="reviewUser(item)">{{ item.review }}</text>
<template v-if="item.businessReview && item.businessReview.trim() !== ''">
<view class="businessReviewTitle">
商家回复
</view>
<text class="businessReview">{{ item.businessReview }}</text>
</template>
</view>
</view>
</view>
</view>
</block>
<block v-if="currentIndex === 2">
<view class="aboutMessage1">
<view class="title1">店铺信息</view>
<view class="message1">
<view class="messageItem1">地址:{{businessMessage.address}}</view>
<view class="messageItem1">营业时间早700-晚2030</view>
<view class="messageItem1">联系电话:{{businessMessage.businessPhone}}</view>
</view>
</view>
<view class="title1">图片详情</view>
<view class="aboutImg1">
<view class="imgLeft1">
<image :src="businessMessage.businessAvatar"></image>
<image src="https://ts1.cn.mm.bing.net/th/id/R-C.68978afc71576a94a1d50ef5016dbd9e?rik=cDDsy5SLmDvDHQ&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50075%2f0779.jpg_wh1200.jpg&ehk=FG4Hd5S711LYcuLBIcDagQyk4KhcH1oIfqyk1MWUOyg%3d&risl=&pid=ImgRaw&r=0" class="img1"></image>
</view>
<view class="imgRight1">
<image src="https://bpic.588ku.com/back_origin_min_pic/21/03/30/251617b5c1ad3b0c7ae62fb8b51dfbbd.jpg" class="img1"></image>
</view>
</view>
</block>
</view>
</scroll-view>
<!-- 用户操作 -->
<view class="toolbar">
<view class="icons">
<button class="icons-button" @click="toggleLike">
<text class="icon-heart">
<image :src="isLiked ? '../../static/small/starSelected.png' : '../../static/small/star.png'"
style="width: 20px;height: 20px;" />
</text>
{{ isLiked ? '已收藏' : '收藏店铺' }}
</button>
<button class="icons-button" open-type="contact" @click="talk">
<text class="icon-handset">
<img src="../../static/small/service.png" style="width: 20px;height: 20px;" />
</text>
联系商家
</button>
</view>
<view class="buttons">
<view class="addcart" @click="showDrawer('showRight')">
<p>购物车</p>
</view>
</view>
</view>
<!--购物车详情-->
<view class="example-body">
<uni-drawer ref="showRight" mode="left" :mask-click="true" @change="change($event,'showRight')">
<view class="scroll-view">
<scroll-view class="scroll-view-box" scroll-y="true">
<view class="info-content" v-for="(item,index) in cartItems" :key="index">
<view class="card">
<view class="containerShow">
<view class="img">
<image :src="item.dishesImage" class="imageItem"></image>
</view>
<view class="delete-button">
<image src="../../static/small/cha.png" @click="deleteItem(index)" alt="Delete"
style="width: 15px;height: 15px;" />
</view>
<view class="message">
<view class="titleCard">{{item.dishesName}}</view>
<view class="moneCard">{{item.dishesPrice}}</view>
<view class="quantity-selector">
<view class="jia" @click="decrementQuantity(index)">-</view>
<text class="quantity-value">{{ item.quantity }}</text>
<view class="jian" @click="incrementQuantity(index)">+</view>
</view>
</view>
</view>
</view>
</view>
<button type="primary" class="sum" @click="account">
<text>立即结算{{ totalAmount }}</text>
</button>
</scroll-view>
</view>
</uni-drawer>
</view>
</template>
<style lang="scss">
.priceTitle {
width: 100%;
height: 50px;
background-color: #4095e5;
font-size: 20px;
color: #fff;
padding-left: 5px;
line-height: 50px;
}
.tabs {
display: flex;
justify-content: space-around;
line-height: 60rpx;
margin: 0 10rpx;
background-color: #fff;
box-shadow: 0 4rpx 6rpx rgba(240, 240, 240, 0.6);
position: relative;
z-index: 9;
.item {
flex: 1;
text-align: center;
padding: 20rpx;
font-size: 28rpx;
color: #262626;
}
.cursor {
position: absolute;
left: 0;
bottom: 0;
width: 18%;
height: 6rpx;
padding: 0 50rpx;
background-color: #4095e5;
transition: all 0.4s;
}
}
.preview {
margin-bottom: 20px;
}
.preview image {
width: 100%;
}
page {
height: 100%;
overflow: hidden;
}
.viewport {
height: 100%;
display: flex;
flex-direction: column;
}
.search {
padding: 0 30rpx 20rpx;
background-color: #fff;
.input {
display: flex;
align-items: center;
justify-content: space-between;
height: 64rpx;
padding-left: 26rpx;
color: #8b8b8b;
font-size: 28rpx;
border-radius: 32rpx;
background-color: #f3f4f4;
}
}
.icon-search {
&::before {
margin-right: 10rpx;
}
}
.categories {
flex: 1;
min-height: 400rpx;
display: flex;
}
.primary {
overflow: hidden;
width: 180rpx;
flex: none;
background-color: #f6f6f6;
.item {
display: flex;
justify-content: center;
align-items: center;
height: 96rpx;
font-size: 26rpx;
color: #595c63;
position: relative;
&::after {
content: '';
position: absolute;
left: 42rpx;
bottom: 0;
width: 96rpx;
border-top: 1rpx solid #e3e4e7;
}
}
.active {
background-color: #fff;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 8rpx;
height: 100%;
background-color: #ed0a3f;
}
}
}
.content{
height: 100vh;
margin-bottom: 40px;
}
.primary .item:last-child::after,
.primary .active::after {
display: none;
}
.secondary {
background-color: #fff;
.carousel {
height: 200rpx;
margin: 0 30rpx 20rpx;
border-radius: 4rpx;
overflow: hidden;
}
.panel {
margin: 0 30rpx 0rpx;
}
.title {
height: 60rpx;
line-height: 60rpx;
color: #333;
font-size: 28rpx;
border-bottom: 1rpx solid #f7f7f8;
.more {
float: right;
padding-left: 20rpx;
font-size: 24rpx;
color: #999;
}
}
.more {
&::after {
font-family: 'erabbit' !important;
content: '\e70c';
}
}
.section {
width: 100%;
display: flex;
flex-wrap: wrap;
padding: 20rpx 0;
.goods {
width: 150rpx;
margin: 0rpx 30rpx 20rpx 0;
&:nth-child(3n) {
margin-right: 0;
}
image {
width: 150rpx;
height: 150rpx;
}
.name {
padding: 5rpx;
font-size: 22rpx;
color: #333;
}
.price {
padding: 5rpx;
font-size: 18rpx;
color: #cf4444;
}
.number {
font-size: 24rpx;
margin-left: 2rpx;
}
}
}
}
.toolbar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
background-color: #fff;
height: 100rpx;
padding: 0 20rpx var(--window-bottom);
border-top: 1rpx solid #eaeaea;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: content-box;
.buttons {
display: flex;
&>view {
width: 220rpx;
text-align: center;
line-height: 72rpx;
font-size: 26rpx;
color: #fff;
border-radius: 72rpx;
}
.addcart {
background-color: #4095e5;
}
.buynow,
.payment {
background-color: #4095e5;
margin-left: 20rpx;
}
}
.icons {
padding-right: 10rpx;
display: flex;
align-items: center;
flex: 1;
.icons-button {
flex: 1;
text-align: center;
line-height: 1.4;
padding: 0;
margin: 0;
border-radius: 0;
font-size: 20rpx;
color: #333;
background-color: #fff;
&::after {
border: none;
}
}
text {
display: block;
font-size: 34rpx;
}
}
}
.tab-menu {
display: flex;
justify-content: space-around;
padding: 10px 0;
background-color: #f5f5f5;
}
.tab-item {
padding: 10px;
cursor: pointer;
}
.tab-item.active {
color: #4095e5;
font-weight: bold;
}
.container {
align-items: center;
width: 90%;
height: 100vh;
margin: 0 auto;
}
.history-list {
width: 95%;
background-color: #fff;
margin-bottom: 5px;
border-radius: 15px;
padding: 10px;
}
.history-item {
margin-bottom: 20rpx;
}
.history-img {
width: 100rpx;
height: 100rpx;
border-radius: 50%; /* 设置为正圆形 */
margin-right: 10px;
padding-right: 50px;
}
.history-info {
display: flex;
flex-direction: row;
}
.nameTime {
display: flex;
flex-direction: column;
}
.history-title {
font-size: 32rpx;
font-weight: bold;
width: 170px;
}
.time {
font-size: 24rpx;
color: #999;
padding-top: 5px;
}
.star {
display: inline-block;
line-height: 15px;
display: flex;
flex-direction: column;
align-items: flex-end;
}
.history-sale {
font-size: 30rpx;
color: #000;
float: right;
display: inline-block;
line-height: 15px;
font-weight: 700;
}
.extend {
font-size: 30rpx;
color: #000;
padding-top: 10px;
}
.example-body {
padding: 10px;
}
.scroll-view {
/* #ifndef APP-NVUE */
width: 100%;
height: 100%;
/* #endif */
flex: 1
}
.scroll-view-box {
flex: 1;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.info {
padding: 15px;
color: #666;
}
.info-text {
font-size: 14px;
color: #666;
}
.info-content {
padding: 5px 15px;
}
.card {
width: 100%;
height: 100px;
border-radius: 15px;
background-image: -webkit-linear-gradient(top, #fff, #B0D3F4);
}
.containerShow {
padding: 7px;
position: relative;
}
.img {
width: 60px;
height: 40px;
display: inline-block;
margin-top: 30px;
}
.imageItem {
width: 100%;
height: 100%;
border-radius: 15px;
margin: auto 0;
}
.message {
width: 110px;
height: 88px;
float: right;
display: inline-block;
}
.quantity-selector {
display: flex;
justify-content: center;
margin-top: 10rpx;
}
.quantity-value {
font-size: 32rpx;
font-weight: bold;
margin: 0 20rpx;
}
.titleCard {
font-size: 16px;
padding-bottom: 3px;
}
.moneyCard {
font-size: 15px;
color: #666;
padding: 0;
}
.jia,
.jian {
background-color: #fff;
padding: 3px 5px 3px 5px;
border: 1px solid #999;
}
.sum {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
}
.containerShow:last-child {
padding-bottom: 150px;
}
.delete-button {
position: absolute;
top: 0;
right: 0;
}
/* shopdetail */
.title1 {
width: 100%;
height: 60px;
font-size: 20px;
color: #000;
padding-left: 5px;
line-height: 60px;
}
.message1 {
width: 80%;
height: 200rpx;
margin: 0 auto;
}
.messageItem1 {
font-size: 18px;
padding-bottom: 10rpx;
}
.aboutImg1 {
width: 90%;
height: 100vh;
margin: 0 auto;
}
.imgLeft1 {
float: left;
width: 48%;
height: 100vh;
}
.imgRight1 {
float: right;
width: 48%;
height: 100vh;
}
.img1 {
width: 100%;
border-radius: 15px;
margin-bottom: 10px;
}
.businessReview {
background-color: rgba(#1fd4f8, 0.2);
border-radius: 15px;
padding: 10px;
margin: 5px;
display: block;
}
.businessReviewTitle {
color: #000;
font-size: 16px;
font-weight: 700;
margin: 8px;
}
</style>