合并代码
This commit is contained in:
@@ -26,7 +26,8 @@ const routesWithBottomNav = [
|
|||||||
'/mainpage',
|
'/mainpage',
|
||||||
'/myprofile',
|
'/myprofile',
|
||||||
'/mymatching',
|
'/mymatching',
|
||||||
'/myshop'
|
'/myshop',
|
||||||
|
'/customerservice'
|
||||||
]
|
]
|
||||||
|
|
||||||
// 计算是否显示底部导航
|
// 计算是否显示底部导航
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
:class="{ active: isActive('/mymatching') }"
|
:class="{ active: isActive('/mymatching') }"
|
||||||
@click="handleNavClick('/mymatching')"
|
@click="handleNavClick('/mymatching')"
|
||||||
>
|
>
|
||||||
<User class="nav-icon" />
|
<Connection class="nav-icon" />
|
||||||
<span class="nav-label">货款匹配</span>
|
<span class="nav-label">货款匹配</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -21,17 +21,9 @@
|
|||||||
:class="{ active: isActive('/myshop') }"
|
:class="{ active: isActive('/myshop') }"
|
||||||
@click="handleNavClick('/myshop')"
|
@click="handleNavClick('/myshop')"
|
||||||
>
|
>
|
||||||
<User class="nav-icon" />
|
<Coin class="nav-icon" />
|
||||||
<span class="nav-label">积分商城</span>
|
<span class="nav-label">积分商城</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
class="nav-item"
|
|
||||||
:class="{ active: isActive('/myprofile') }"
|
|
||||||
@click="handleNavClick('/myprofile')"
|
|
||||||
>
|
|
||||||
<User class="nav-icon" />
|
|
||||||
<span class="nav-label">个人中心</span>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
:class="{ active: isActive('/transfers') }"
|
:class="{ active: isActive('/transfers') }"
|
||||||
@@ -40,6 +32,14 @@
|
|||||||
<Money class="nav-icon" />
|
<Money class="nav-icon" />
|
||||||
<span class="nav-label">货款管理</span>
|
<span class="nav-label">货款管理</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="nav-item"
|
||||||
|
:class="{ active: isActive('/myprofile') }"
|
||||||
|
@click="handleNavClick('/myprofile')"
|
||||||
|
>
|
||||||
|
<User class="nav-icon" />
|
||||||
|
<span class="nav-label">个人中心</span>
|
||||||
|
</div>
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
:class="{ active: isActive('/matching') }"
|
:class="{ active: isActive('/matching') }"
|
||||||
|
|||||||
@@ -201,6 +201,14 @@ const routes = [
|
|||||||
title: '关于我们'
|
title: '关于我们'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/customerservice',
|
||||||
|
name: 'CustomerService',
|
||||||
|
component: () => import('@/views/CustomerService.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '客服中心'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/:pathMatch(.*)*',
|
path: '/:pathMatch(.*)*',
|
||||||
name: 'NotFound',
|
name: 'NotFound',
|
||||||
|
|||||||
@@ -7,12 +7,20 @@
|
|||||||
<h2>{{ agentInfo?.real_name }} - {{ agentInfo?.city_name }}{{ agentInfo?.district_name }}代理</h2>
|
<h2>{{ agentInfo?.real_name }} - {{ agentInfo?.city_name }}{{ agentInfo?.district_name }}代理</h2>
|
||||||
<p>手机号:{{ agentInfo?.phone }}</p>
|
<p>手机号:{{ agentInfo?.phone }}</p>
|
||||||
</div>
|
</div>
|
||||||
<el-button type="danger" @click="handleLogout">退出登录</el-button>
|
<!-- <el-button type="danger" @click="handleLogout">退出登录</el-button> -->
|
||||||
|
<el-button
|
||||||
|
style="background-color: #409EFF; border-color: #409EFF; color: white; width: 84px;height: 32px;"
|
||||||
|
@click="handleLogout"
|
||||||
|
>
|
||||||
|
退出登录
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 统计卡片 -->
|
<!-- 统计卡片 -->
|
||||||
<div class="stats-grid">
|
<div class="stats-grid">
|
||||||
|
<!-- 第一行:仅 "招募商户" 和 "总佣金" 水平排列 -->
|
||||||
|
<div class="stats-row">
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon merchant">
|
<div class="stat-icon merchant">
|
||||||
<el-icon><User /></el-icon>
|
<el-icon><User /></el-icon>
|
||||||
@@ -34,8 +42,10 @@
|
|||||||
<div class="stat-sub">已到账:¥{{ (Number(stats.paid_commission) || 0).toFixed(2) }}</div>
|
<div class="stat-sub">已到账:¥{{ (Number(stats.paid_commission) || 0).toFixed(2) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="stat-card">
|
<!-- 第二行:"已使用二维码" 单独一行 -->
|
||||||
|
<div class="stat-card single-stat">
|
||||||
<div class="stat-icon code">
|
<div class="stat-icon code">
|
||||||
<el-icon><Document /></el-icon>
|
<el-icon><Document /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
@@ -118,7 +128,18 @@
|
|||||||
v-model:page-size="merchantsPageSize"
|
v-model:page-size="merchantsPageSize"
|
||||||
:total="merchantsTotal"
|
:total="merchantsTotal"
|
||||||
:page-sizes="[10, 20, 50]"
|
:page-sizes="[10, 20, 50]"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes"
|
||||||
|
@current-change="loadMerchants"
|
||||||
|
@size-change="loadMerchants"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="merchantsPage"
|
||||||
|
v-model:page-size="merchantsPageSize"
|
||||||
|
:total="merchantsTotal"
|
||||||
|
:page-sizes="[10, 20, 50]"
|
||||||
|
layout="prev, pager, next, jumper"
|
||||||
@current-change="loadMerchants"
|
@current-change="loadMerchants"
|
||||||
@size-change="loadMerchants"
|
@size-change="loadMerchants"
|
||||||
/>
|
/>
|
||||||
@@ -177,7 +198,18 @@
|
|||||||
v-model:page-size="commissionsPageSize"
|
v-model:page-size="commissionsPageSize"
|
||||||
:total="commissionsTotal"
|
:total="commissionsTotal"
|
||||||
:page-sizes="[10, 20, 50]"
|
:page-sizes="[10, 20, 50]"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes"
|
||||||
|
@current-change="loadCommissions"
|
||||||
|
@size-change="loadCommissions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="commissionsPage"
|
||||||
|
v-model:page-size="commissionsPageSize"
|
||||||
|
:total="commissionsTotal"
|
||||||
|
:page-sizes="[10, 20, 50]"
|
||||||
|
layout="prev, pager, next, jumper"
|
||||||
@current-change="loadCommissions"
|
@current-change="loadCommissions"
|
||||||
@size-change="loadCommissions"
|
@size-change="loadCommissions"
|
||||||
/>
|
/>
|
||||||
@@ -406,12 +438,10 @@ onMounted(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.agent-dashboard {
|
.agent-dashboard {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #f5f7fa;
|
background: linear-gradient(to bottom, #72c9ffae, #f3f3f3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-header {
|
.dashboard-header {
|
||||||
background: white;
|
|
||||||
border-bottom: 1px solid #e4e7ed;
|
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,65 +464,74 @@ onMounted(() => {
|
|||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 整体统计卡片容器 */
|
||||||
.stats-grid {
|
.stats-grid {
|
||||||
display: grid;
|
width: 343px;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
margin: 24px auto;
|
||||||
gap: 24px;
|
|
||||||
padding: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 第一行:仅 "招募商户" 和 "总佣金" 水平排列 */
|
||||||
|
.stats-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 12px; /* 与下方 "已使用二维码" 卡片间距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计卡片通用样式 */
|
||||||
.stat-card {
|
.stat-card {
|
||||||
|
flex: 1; /* 自动平分空间 */
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 24px;
|
padding: 16px;
|
||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* "已使用二维码" 单独一行 */
|
||||||
|
.stat-card.single-stat {
|
||||||
|
width: 100%; /* 占满整行 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标样式 */
|
||||||
.stat-icon {
|
.stat-icon {
|
||||||
width: 48px;
|
width: 40px;
|
||||||
height: 48px;
|
height: 40px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 24px;
|
font-size: 20px;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 背景渐变 */
|
||||||
.stat-icon.merchant {
|
.stat-icon.merchant {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-icon.commission {
|
.stat-icon.commission {
|
||||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-icon.code {
|
.stat-icon.code {
|
||||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-content {
|
/* 文字样式 */
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-number {
|
.stat-number {
|
||||||
font-size: 24px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-label {
|
.stat-label {
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
color: #606266;
|
color: #606266;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-sub {
|
.stat-sub {
|
||||||
font-size: 12px;
|
font-size: 10px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,6 +544,7 @@ onMounted(() => {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 343px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header {
|
.card-header {
|
||||||
@@ -589,6 +629,7 @@ onMounted(() => {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 343px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-table) {
|
:deep(.el-table) {
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="agent-login-container">
|
<div class="agent-login-page">
|
||||||
|
<div class="login-container">
|
||||||
<div class="login-card">
|
<div class="login-card">
|
||||||
<div class="login-header">
|
<div class="login-header">
|
||||||
<h2>区域代理登录</h2>
|
<h2>区域代理登录</h2>
|
||||||
<p>浙江省区域代理管理系统</p>
|
<p>浙江省区域代理管理系统</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="image">
|
||||||
|
<img src="/imgs/login-agent.png" alt="区域代理管理系统">
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-form
|
<el-form
|
||||||
ref="loginFormRef"
|
ref="loginFormRef"
|
||||||
:model="loginForm"
|
:model="loginForm"
|
||||||
@@ -19,6 +24,7 @@
|
|||||||
placeholder="请输入手机号"
|
placeholder="请输入手机号"
|
||||||
prefix-icon="Phone"
|
prefix-icon="Phone"
|
||||||
size="large"
|
size="large"
|
||||||
|
clearable
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@@ -30,6 +36,8 @@
|
|||||||
prefix-icon="Lock"
|
prefix-icon="Lock"
|
||||||
size="large"
|
size="large"
|
||||||
show-password
|
show-password
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleLogin"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@@ -37,11 +45,11 @@
|
|||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
class="login-btn"
|
class="login-button"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@click="handleLogin"
|
@click="handleLogin"
|
||||||
>
|
>
|
||||||
登录
|
{{ loading ? '登录中...' : '登录' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -52,6 +60,14 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 背景装饰 -->
|
||||||
|
<div class="background-decoration">
|
||||||
|
<div class="decoration-circle circle-1"></div>
|
||||||
|
<div class="decoration-circle circle-2"></div>
|
||||||
|
<div class="decoration-circle circle-3"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 申请代理对话框 -->
|
<!-- 申请代理对话框 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
@@ -278,22 +294,29 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.agent-login-container {
|
/* 使用与主登录页面一致的样式 */
|
||||||
|
.agent-login-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: linear-gradient(135deg, #a2f6ff 0%, #f3f3f3 100%);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-card {
|
.login-card {
|
||||||
background: white;
|
backdrop-filter: blur(10px);
|
||||||
border-radius: 12px;
|
border-radius: 16px;
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
padding: 40px 30px;
|
||||||
padding: 40px;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-header {
|
.login-header {
|
||||||
@@ -302,40 +325,183 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.login-header h2 {
|
.login-header h2 {
|
||||||
color: #333;
|
color: #4784ff;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-header p {
|
.login-header p {
|
||||||
color: #666;
|
color: #666;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin: 0;
|
}
|
||||||
|
|
||||||
|
/* 图片容器样式 */
|
||||||
|
.image {
|
||||||
|
width: 375px;
|
||||||
|
height: 200px;
|
||||||
|
margin: 0 auto 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.image img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式适配 */
|
||||||
|
@media (max-width: 375px) {
|
||||||
|
.image {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
aspect-ratio: 375 / 200;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-form {
|
.login-form {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-btn {
|
.login-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-footer {
|
.login-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 20px;
|
margin-bottom: 20px;
|
||||||
border-top: 1px solid #eee;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-footer .el-link {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-decoration {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decoration-circle {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
animation: float 6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-1 {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
top: 10%;
|
||||||
|
left: 10%;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-2 {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
top: 60%;
|
||||||
|
right: 10%;
|
||||||
|
animation-delay: 2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle-3 {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
bottom: 20%;
|
||||||
|
left: 20%;
|
||||||
|
animation-delay: 4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% {
|
||||||
|
transform: translateY(0px) rotate(0deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(-20px) rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入框样式 */
|
||||||
:deep(.el-input__wrapper) {
|
:deep(.el-input__wrapper) {
|
||||||
|
background: transparent !important;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.el-input__wrapper:hover),
|
||||||
|
:deep(.el-input__wrapper.is-focus) {
|
||||||
|
box-shadow: 0 0 0 1px #409eff inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-form-item.is-error .el-input__wrapper) {
|
||||||
|
box-shadow: 0 0 0 1px #f56c6c inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-form-item.is-success .el-input__wrapper) {
|
||||||
|
box-shadow: 0 0 0 1px #67c23a inset;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-button) {
|
:deep(.el-button) {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 对话框样式调整 */
|
||||||
|
:deep(.el-dialog) {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-dialog__header) {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding: 15px 20px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-dialog__title) {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-dialog__body) {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-dialog__footer) {
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
padding: 15px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 动画效果 */
|
||||||
|
.login-card {
|
||||||
|
animation: slideInUp 0.6s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.login-container {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card {
|
||||||
|
padding: 30px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -32,10 +32,6 @@
|
|||||||
<el-input v-model="form.nickname" placeholder="请输入昵称" />
|
<el-input v-model="form.nickname" placeholder="请输入昵称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="邮箱" prop="email">
|
|
||||||
<el-input v-model="form.email" placeholder="请输入邮箱" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="真实姓名" prop="realName">
|
<el-form-item label="真实姓名" prop="realName">
|
||||||
<el-input v-model="form.realName" placeholder="请输入真实姓名" />
|
<el-input v-model="form.realName" placeholder="请输入真实姓名" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -225,7 +221,6 @@ const userStore = useUserStore()
|
|||||||
const form = reactive({
|
const form = reactive({
|
||||||
username: '',
|
username: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
email: '',
|
|
||||||
phone: '',
|
phone: '',
|
||||||
realName: '',
|
realName: '',
|
||||||
idCard: '',
|
idCard: '',
|
||||||
@@ -251,10 +246,6 @@ const rules = {
|
|||||||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||||
{ min: 3, max: 20, message: '用户名长度在 3 到 20 个字符', trigger: 'blur' }
|
{ min: 3, max: 20, message: '用户名长度在 3 到 20 个字符', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
email: [
|
|
||||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
|
||||||
{ type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
|
|
||||||
],
|
|
||||||
realName: [
|
realName: [
|
||||||
{ required: true, message: '请输入真实姓名', trigger: 'blur' },
|
{ required: true, message: '请输入真实姓名', trigger: 'blur' },
|
||||||
{ min: 2, max: 10, message: '真实姓名长度在 2 到 10 个字符', trigger: 'blur' }
|
{ min: 2, max: 10, message: '真实姓名长度在 2 到 10 个字符', trigger: 'blur' }
|
||||||
|
|||||||
@@ -113,12 +113,12 @@ export default {
|
|||||||
{
|
{
|
||||||
image: '/imgs/mainpage/客服中心.png',
|
image: '/imgs/mainpage/客服中心.png',
|
||||||
text: '客服中心',
|
text: '客服中心',
|
||||||
path: '/support',
|
path: '/customerservice',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: '/imgs/mainpage/系统公告.png',
|
image: '/imgs/mainpage/系统公告.png',
|
||||||
text: '系统公告',
|
text: '系统公告',
|
||||||
path: '/announcements',
|
path: '#',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const newsItems = ref([
|
const newsItems = ref([
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
<p>• 金额范围:5000-50000元</p>
|
<p>• 金额范围:5000-50000元</p>
|
||||||
<p>• 15000元以下:分成3笔随机金额</p>
|
<p>• 15000元以下:分成3笔随机金额</p>
|
||||||
<p>• 15000元以上:随机分拆,每笔1000-8000元</p>
|
<p>• 15000元以上:随机分拆,每笔1000-8000元</p>
|
||||||
<p>• 优先匹配已完成出款的用户</p>
|
<p>• 优先匹配已完成进货的用户</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<p>• 系统将为您匹配3笔转账,总金额5000元</p>
|
<p>• 系统将为您匹配3笔转账,总金额5000元</p>
|
||||||
<p>• 优先匹配已完成出款的用户</p>
|
<p>• 优先匹配已完成进货的用户</p>
|
||||||
<p>• 每笔金额随机分配,确保资金循环</p>
|
<p>• 每笔金额随机分配,确保资金循环</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
<p>• 金额范围:5000-50000元</p>
|
<p>• 金额范围:5000-50000元</p>
|
||||||
<p>• 15000元以下:分成3笔随机金额</p>
|
<p>• 15000元以下:分成3笔随机金额</p>
|
||||||
<p>• 15000元以上:随机分拆,每笔1000-8000元</p>
|
<p>• 15000元以上:随机分拆,每笔1000-8000元</p>
|
||||||
<p>• 优先匹配已完成出款的用户</p>
|
<p>• 优先匹配已完成进货的用户</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,8 +30,7 @@
|
|||||||
<div class="category-section">
|
<div class="category-section">
|
||||||
<div class="category-header-container">
|
<div class="category-header-container">
|
||||||
<div class="category-header">分类区</div>
|
<div class="category-header">分类区</div>
|
||||||
</div>
|
<div class="category-items-vertical">
|
||||||
<div class="category-items">
|
|
||||||
<div
|
<div
|
||||||
v-for="category in categories"
|
v-for="category in categories"
|
||||||
:key="category.id"
|
:key="category.id"
|
||||||
@@ -43,20 +42,45 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧商品展示区域 - 修改后的部分 -->
|
||||||
|
<div class="product-showcase">
|
||||||
|
<router-link to="/shop">
|
||||||
|
<div v-if="loading" class="loading-products">
|
||||||
|
加载中...
|
||||||
|
</div>
|
||||||
|
<div v-else class="product-showcase-grid">
|
||||||
|
<div class="product-item" v-for="product in featuredProducts" :key="product.id">
|
||||||
|
<img :src="product.image" :alt="product.name" class="product-image">
|
||||||
|
<div class="product-info">
|
||||||
|
<div class="product-name">{{ product.name }}</div>
|
||||||
|
<div class="product-price">
|
||||||
|
<span class="points">{{ product.points }}</span>
|
||||||
|
<span class="original-price" v-if="product.originalPoints">{{ product.originalPoints }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 添加一个空白项来填充剩余空间 -->
|
||||||
|
<div class="product-item empty-item" v-if="featuredProducts.length > 0 && featuredProducts.length < 3"></div>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { transferAPI } from '../utils/api'
|
import api from '@/utils/api' // 确保导入正确的api模块
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const userPoints = ref(0)
|
const userPoints = ref(0)
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
// 分类数据
|
// 分类数据
|
||||||
const categories = ref([
|
const categories = ref([
|
||||||
@@ -68,20 +92,43 @@ export default {
|
|||||||
{ id: '其他', name: '其他', icon: '📦' }
|
{ id: '其他', name: '其他', icon: '📦' }
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// 精选商品数据
|
||||||
|
const featuredProducts = ref([])
|
||||||
|
|
||||||
// 获取用户积分
|
// 获取用户积分
|
||||||
const getUserPoints = async () => {
|
const getUserPoints = async () => {
|
||||||
try {
|
try {
|
||||||
const {data} = await transferAPI.getUserAccount();
|
const {data} = await api.get('/user/points') // 使用api而不是transferAPI
|
||||||
console.log(data);
|
console.log(data)
|
||||||
|
userPoints.value = data.points || 0
|
||||||
// 根据实际API响应结构调整,以下是几种可能的取值方式
|
|
||||||
userPoints.value = data.data.points || 0;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取积分信息失败', error)
|
console.error('获取积分信息失败', error)
|
||||||
ElMessage.error('获取积分信息失败,请稍后重试')
|
ElMessage.error('获取积分信息失败,请稍后重试')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取商品列表
|
||||||
|
const getProducts = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
const {data} = await api.get('/products', { // 使用api而不是transferAPI
|
||||||
|
params: {
|
||||||
|
page: 1,
|
||||||
|
limit: 3, // 只获取前3个商品
|
||||||
|
sort: 'sales' // 按销量排序获取热门商品
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 只取前3个商品作为精选商品
|
||||||
|
featuredProducts.value = data.data.products.slice(0, 3)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取商品列表失败:', error)
|
||||||
|
ElMessage.error('获取商品列表失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 跳转到商城对应分类
|
// 跳转到商城对应分类
|
||||||
const goToCategory = (categoryId) => {
|
const goToCategory = (categoryId) => {
|
||||||
router.push({
|
router.push({
|
||||||
@@ -90,11 +137,16 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
getUserPoints()
|
getUserPoints()
|
||||||
|
getProducts()
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userPoints,
|
userPoints,
|
||||||
categories,
|
categories,
|
||||||
|
featuredProducts,
|
||||||
|
loading,
|
||||||
getUserPoints,
|
getUserPoints,
|
||||||
goToCategory
|
goToCategory
|
||||||
}
|
}
|
||||||
@@ -276,50 +328,43 @@ export default {
|
|||||||
/* 分类区域样式 */
|
/* 分类区域样式 */
|
||||||
.category-section {
|
.category-section {
|
||||||
width: 343px;
|
width: 343px;
|
||||||
height: 274px;
|
height: auto; /* 改为自适应高度 */
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: var(--box-shadow);
|
box-shadow: var(--box-shadow);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: flex;
|
display: flex; /* 添加flex布局 */
|
||||||
|
gap: 16px; /* 添加间距 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-header-container {
|
.category-header-container {
|
||||||
width: 114px;
|
width: 114px; /* 保持原有宽度 */
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
flex-direction: column; /* 改为垂直布局 */
|
||||||
justify-content: center;
|
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
border-right: 1px solid #f0f0f0;
|
border-right: 1px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-header {
|
.category-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%; /* 高度由父容器决定 */
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--dark-color);
|
color: var(--dark-color);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
background-color: #cae5ff;
|
background-color: #cae5ff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
margin-bottom: 16px; /* 增加与分类项的间距 */
|
||||||
align-items: flex-start; /* 改为flex-start使内容置顶 */
|
|
||||||
justify-content: center; /* 保持水平居中 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-items {
|
.category-items-vertical {
|
||||||
flex: 1;
|
display: flex;
|
||||||
display: grid;
|
flex-direction: column;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
gap: 12px; /* 调整分类项间距 */
|
||||||
grid-template-rows: repeat(2, 1fr);
|
|
||||||
gap: 16px;
|
|
||||||
margin-left: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-grid {
|
.category-grid {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
background-color: #fff0d0;
|
background-color: #fff0d0;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -328,7 +373,7 @@ export default {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
padding: 12px;
|
padding: 8px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-grid:hover {
|
.category-grid:hover {
|
||||||
@@ -338,17 +383,93 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.category-icon {
|
.category-icon {
|
||||||
font-size: 24px;
|
font-size: 20px; /* 稍微调小图标 */
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.category-name {
|
.category-name {
|
||||||
font-size: 14px;
|
font-size: 12px; /* 稍微调小字体 */
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--dark-color);
|
color: var(--dark-color);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 右侧商品展示区域 */
|
||||||
|
.product-showcase {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-showcase-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-item {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-item {
|
||||||
|
visibility: hidden; /* 隐藏空白项但保留其空间 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-item:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
object-fit: cover;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-info {
|
||||||
|
padding: 8px;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0 0 4px 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-price {
|
||||||
|
margin-top: auto; /* 将价格推到底部 */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.points {
|
||||||
|
color: #ff6b35;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.original-price {
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
/* 使用与主页面一致的变量 */
|
/* 使用与主页面一致的变量 */
|
||||||
:root {
|
:root {
|
||||||
--primary-color: #4361ee;
|
--primary-color: #4361ee;
|
||||||
@@ -363,4 +484,12 @@ export default {
|
|||||||
--box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
--box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
--transition: all 0.3s ease;
|
--transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-products {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -14,11 +14,11 @@ export default defineConfig({
|
|||||||
port: 5173,
|
port: 5173,
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://localhost:3000',
|
target: 'http://114.55.111.44:3001',
|
||||||
changeOrigin: true
|
changeOrigin: true
|
||||||
},
|
},
|
||||||
'/uploads': {
|
'/uploads': {
|
||||||
target: 'http://localhost:3000',
|
target: 'http://114.55.111.44:3001',
|
||||||
changeOrigin: true
|
changeOrigin: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user