503 lines
11 KiB
Vue
503 lines
11 KiB
Vue
<template>
|
||
<view class="page-merchant">
|
||
<!-- 未登录商家账号 -->
|
||
<view v-if="!sellerStore.isSellerLoggedIn()" class="login-tip">
|
||
<text class="tip-text">请先注册/登录商家账号</text>
|
||
<button class="login-btn" @tap="goSellerRegister">去注册/登录</button>
|
||
</view>
|
||
|
||
<!-- 已登录但未申请店铺 -->
|
||
<view v-else-if="!sellerStore.hasMerchant()" class="apply-section">
|
||
<view class="seller-info">
|
||
<text class="seller-name">{{ sellerStore.sellerInfo?.contactName }}</text>
|
||
<text class="seller-phone">{{ sellerStore.sellerInfo?.phone }}</text>
|
||
</view>
|
||
<text class="apply-title">创建店铺</text>
|
||
<text class="apply-desc">完成店铺信息填写,提交审核后即可营业</text>
|
||
<button class="apply-btn" @tap="goCreateShop">创建店铺</button>
|
||
<button class="logout-btn" @tap="handleLogoutSeller">退出商家账号</button>
|
||
</view>
|
||
|
||
<!-- 已有店铺:加载中 -->
|
||
<view v-else-if="!merchant" class="loading-section">
|
||
<text class="loading-text">加载中...</text>
|
||
</view>
|
||
|
||
<!-- 已有店铺 -->
|
||
<view v-else class="merchant-content">
|
||
<!-- 店铺信息 -->
|
||
<view class="shop-header">
|
||
<image class="shop-logo" :src="merchant.logo || '/static/default-avatar.png'" mode="aspectFill" />
|
||
<view class="shop-info">
|
||
<text class="shop-name">{{ merchant.shopName }}</text>
|
||
<view class="status-row">
|
||
<text :class="['shop-status', merchant.status]">{{ statusText }}</text>
|
||
<!-- 审核中状态显示提示 -->
|
||
<text v-if="merchant.status === 'pending'" class="status-tip">等待平台审核</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 审核拒绝原因 -->
|
||
<view v-if="merchant.status === 'rejected' && merchant.rejectReason" class="reject-section">
|
||
<view class="reject-header">
|
||
<text class="reject-icon">!</text>
|
||
<text class="reject-title">审核拒绝原因</text>
|
||
</view>
|
||
<text class="reject-reason">{{ merchant.rejectReason }}</text>
|
||
<text class="reject-tip">请修改店铺信息后重新提交审核</text>
|
||
</view>
|
||
|
||
<!-- 店铺信息卡片(非审核中状态) -->
|
||
<view v-if="merchant.status !== 'pending'" class="shop-detail-card">
|
||
<view class="detail-item">
|
||
<text class="detail-label">联系电话</text>
|
||
<text class="detail-value">{{ merchant.phone }}</text>
|
||
</view>
|
||
<view class="detail-item" v-if="merchant.city">
|
||
<text class="detail-label">所在城市</text>
|
||
<text class="detail-value">{{ merchant.province }} {{ merchant.city }} {{ merchant.district }}</text>
|
||
</view>
|
||
<view class="detail-item" v-if="merchant.address">
|
||
<text class="detail-label">详细地址</text>
|
||
<text class="detail-value">{{ merchant.address }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 数据概览(仅审核通过显示) -->
|
||
<view v-if="merchant.status === 'approved'" class="stat-grid">
|
||
<view class="stat-item">
|
||
<text class="stat-value">0</text>
|
||
<text class="stat-label">今日订单</text>
|
||
</view>
|
||
<view class="stat-item">
|
||
<text class="stat-value">0</text>
|
||
<text class="stat-label">在售房源</text>
|
||
</view>
|
||
<view class="stat-item">
|
||
<text class="stat-value">0</text>
|
||
<text class="stat-label">今日收入</text>
|
||
</view>
|
||
<view class="stat-item">
|
||
<text class="stat-value">{{ merchant.rating }}</text>
|
||
<text class="stat-label">店铺评分</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 操作按钮 -->
|
||
<view class="action-section">
|
||
<!-- 审核通过/拒绝时可修改店铺 -->
|
||
<button
|
||
v-if="merchant.status === 'approved' || merchant.status === 'rejected'"
|
||
class="edit-btn"
|
||
@tap="goEditShop"
|
||
>
|
||
修改店铺信息
|
||
</button>
|
||
<!-- 审核中状态不可修改 -->
|
||
<view v-if="merchant.status === 'pending'" class="pending-tip">
|
||
<text class="pending-text">店铺信息审核中,暂不可修改</text>
|
||
</view>
|
||
<!-- 冻结状态 -->
|
||
<view v-if="merchant.status === 'frozen'" class="frozen-tip">
|
||
<text class="frozen-text">店铺已被冻结,请联系平台客服</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 功能菜单(仅审核通过显示) -->
|
||
<view v-if="merchant.status === 'approved'" class="menu-section">
|
||
<view class="menu-group">
|
||
<view class="menu-item" @tap="navigateTo('/pages/seller/orders')">
|
||
<text class="menu-label">订单管理</text>
|
||
<text class="menu-arrow">></text>
|
||
</view>
|
||
<view class="menu-item" @tap="navigateTo('/pages/seller/rooms')">
|
||
<text class="menu-label">房源管理</text>
|
||
<text class="menu-arrow">></text>
|
||
</view>
|
||
<view class="menu-item" @tap="navigateTo('/pages/seller/room-calendar')">
|
||
<text class="menu-label">房量房价</text>
|
||
<text class="menu-arrow">></text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, onMounted } from 'vue';
|
||
import { useSellerStore } from '@/store/seller';
|
||
import { getMyMerchant } from '@/api/seller/merchant';
|
||
|
||
const sellerStore = useSellerStore();
|
||
const merchant = ref<any>(null);
|
||
|
||
const merchantStatus: Record<string, string> = {
|
||
pending: '审核中',
|
||
approved: '营业中',
|
||
rejected: '已拒绝',
|
||
frozen: '已冻结',
|
||
};
|
||
|
||
const statusText = computed(() => {
|
||
if (!merchant.value) return '';
|
||
return merchantStatus[merchant.value.status] || '';
|
||
});
|
||
|
||
onMounted(async () => {
|
||
if (sellerStore.isSellerLoggedIn() && sellerStore.hasMerchant()) {
|
||
try {
|
||
const res = await getMyMerchant();
|
||
merchant.value = res.data;
|
||
// 同步更新 sellerStore 中的状态
|
||
if (sellerStore.sellerInfo && res.data.status !== sellerStore.sellerInfo.merchantStatus) {
|
||
sellerStore.sellerInfo.merchantStatus = res.data.status;
|
||
uni.setStorageSync('sellerInfo', sellerStore.sellerInfo);
|
||
}
|
||
} catch { /* 获取店铺信息失败 */ }
|
||
}
|
||
});
|
||
|
||
function goSellerRegister() {
|
||
uni.navigateTo({ url: '/pages/seller/register' });
|
||
}
|
||
|
||
function goCreateShop() {
|
||
uni.navigateTo({ url: '/pages/seller/shop-create' });
|
||
}
|
||
|
||
function goEditShop() {
|
||
uni.navigateTo({ url: '/pages/seller/shop-edit' });
|
||
}
|
||
|
||
function handleLogoutSeller() {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '确定退出商家账号?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
sellerStore.logoutSeller();
|
||
}
|
||
},
|
||
});
|
||
}
|
||
|
||
function navigateTo(url: string) {
|
||
uni.navigateTo({ url });
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page-merchant {
|
||
min-height: 100vh;
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.login-tip {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 200rpx 48rpx;
|
||
}
|
||
|
||
.tip-text {
|
||
font-size: 30rpx;
|
||
color: #999;
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.login-btn {
|
||
background: #FF6B35;
|
||
color: #fff;
|
||
border-radius: 40rpx;
|
||
padding: 20rpx 80rpx;
|
||
font-size: 30rpx;
|
||
border: none;
|
||
}
|
||
|
||
.apply-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 120rpx 48rpx;
|
||
}
|
||
|
||
.seller-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-bottom: 48rpx;
|
||
}
|
||
|
||
.seller-name {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.seller-phone {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
.apply-title {
|
||
font-size: 40rpx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
}
|
||
|
||
.apply-desc {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
margin: 16rpx 0 48rpx;
|
||
}
|
||
|
||
.apply-btn {
|
||
background: linear-gradient(135deg, #FF6B35, #ff8a5c);
|
||
color: #fff;
|
||
border-radius: 40rpx;
|
||
padding: 24rpx 80rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
border: none;
|
||
}
|
||
|
||
.logout-btn {
|
||
margin-top: 32rpx;
|
||
background: transparent;
|
||
color: #999;
|
||
border: 1rpx solid #ddd;
|
||
border-radius: 40rpx;
|
||
padding: 20rpx 60rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.shop-header {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 40rpx 24rpx;
|
||
background: linear-gradient(135deg, #FF6B35, #ff8a5c);
|
||
}
|
||
|
||
.shop-logo {
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
border-radius: 50%;
|
||
border: 4rpx solid rgba(255, 255, 255, 0.5);
|
||
}
|
||
|
||
.shop-info {
|
||
margin-left: 24rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.shop-name {
|
||
font-size: 34rpx;
|
||
font-weight: 600;
|
||
color: #fff;
|
||
}
|
||
|
||
.status-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
.shop-status {
|
||
font-size: 24rpx;
|
||
padding: 4rpx 16rpx;
|
||
border-radius: 16rpx;
|
||
color: #fff;
|
||
|
||
&.approved { background: rgba(82, 196, 26, 0.8); }
|
||
&.pending { background: rgba(250, 173, 20, 0.8); }
|
||
&.rejected { background: rgba(255, 77, 79, 0.8); }
|
||
&.frozen { background: rgba(140, 140, 140, 0.8); }
|
||
}
|
||
|
||
.status-tip {
|
||
font-size: 24rpx;
|
||
color: rgba(255, 255, 255, 0.8);
|
||
margin-left: 12rpx;
|
||
}
|
||
|
||
.reject-section {
|
||
background: #fff2f0;
|
||
border: 1rpx solid #ffccc7;
|
||
border-radius: 16rpx;
|
||
margin: 24rpx;
|
||
padding: 24rpx;
|
||
}
|
||
|
||
.reject-header {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.reject-icon {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
background: #ff4d4f;
|
||
border-radius: 50%;
|
||
color: #fff;
|
||
font-size: 20rpx;
|
||
font-weight: 700;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.reject-title {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #ff4d4f;
|
||
margin-left: 12rpx;
|
||
}
|
||
|
||
.reject-reason {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.reject-tip {
|
||
font-size: 24rpx;
|
||
color: #ff7875;
|
||
margin-top: 12rpx;
|
||
}
|
||
|
||
.shop-detail-card {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
margin: 24rpx;
|
||
padding: 24rpx;
|
||
}
|
||
|
||
.detail-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 16rpx 0;
|
||
border-bottom: 1rpx solid #f5f5f5;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
}
|
||
|
||
.detail-label {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.detail-value {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.stat-grid {
|
||
display: flex;
|
||
background: #fff;
|
||
margin: 24rpx;
|
||
border-radius: 16rpx;
|
||
padding: 32rpx 0;
|
||
}
|
||
|
||
.stat-item {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.stat-value {
|
||
font-size: 36rpx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-top: 8rpx;
|
||
}
|
||
|
||
.action-section {
|
||
padding: 0 24rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.edit-btn {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
background: #fff;
|
||
color: #FF6B35;
|
||
border: 2rpx solid #FF6B35;
|
||
border-radius: 44rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.pending-tip, .frozen-tip {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 32rpx 24rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.pending-text {
|
||
font-size: 28rpx;
|
||
color: #faad14;
|
||
}
|
||
|
||
.frozen-text {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.loading-section {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 200rpx 0;
|
||
}
|
||
|
||
.loading-text {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.menu-section {
|
||
padding: 0 24rpx;
|
||
}
|
||
|
||
.menu-group {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.menu-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 32rpx 24rpx;
|
||
border-bottom: 1rpx solid #f5f5f5;
|
||
|
||
&:last-child { border-bottom: none; }
|
||
}
|
||
|
||
.menu-label {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.menu-arrow {
|
||
font-size: 28rpx;
|
||
color: #ccc;
|
||
}
|
||
</style> |