feat(路由): 添加用户和聊天页面路由
style(页脚): 更新版权信息和样式,添加链接和响应式设计 style(全局样式): 引入CSS变量,统一设计系统 refactor(主页面): 使用CSS变量优化样式,提升可维护性 style(购物车): 应用CSS变量,优化交互效果和动画 feat(头部导航): 增强用户信息展示和搜索类型切换动画 feat(聊天页面): 新增聊天功能界面,支持用户列表和消息交互 feat(用户信息): 重构用户信息页面,添加订单状态和功能菜单
This commit is contained in:
@@ -7,6 +7,8 @@ import Search from '../Views/Search.vue'
|
||||
import ProductDetail from '../Views/product/productdetil.vue'
|
||||
import Cart from '../Views/Cart.vue'
|
||||
import Order from '../Views/Order.vue'
|
||||
import User from '../Views/User/User.vue'
|
||||
import Chat from '../Views/Chat.vue'
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +43,17 @@ const routes = [
|
||||
name: 'order',
|
||||
component: Order
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
name: 'user',
|
||||
component: User
|
||||
},
|
||||
{
|
||||
path: '/chat',
|
||||
name: 'chat',
|
||||
component: Chat
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -1,13 +1,112 @@
|
||||
/* 全局样式 */
|
||||
body {
|
||||
height: 100%;
|
||||
padding: 0 20px;
|
||||
padding: 0 var(--spacing-lg);
|
||||
background-color: var(--bg-color);
|
||||
font-family: var(--font-family);
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
font-size: 16px;
|
||||
color: var(--text-primary);
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: bold;
|
||||
transition: all 0.3s ease-in-out;
|
||||
transition: all var(--transition-normal);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
:root {
|
||||
/* 主色调 */
|
||||
--primary-color: #ff5000;
|
||||
--primary-hover: #ff7a45;
|
||||
--primary-active: #ff3a00;
|
||||
--primary-light: rgba(255, 80, 0, 0.05);
|
||||
--primary-light-rgb: 255, 80, 0;
|
||||
|
||||
/* 辅助色 */
|
||||
--secondary-color: #1890ff;
|
||||
--secondary-hover: #40a9ff;
|
||||
--success-color: #52c41a;
|
||||
--success-light: #f6ffed;
|
||||
--warning-color: #faad14;
|
||||
--warning-light: #fff7e6;
|
||||
--error-color: #ff4d4f;
|
||||
--error-light: #fff2f0;
|
||||
|
||||
/* 登录按钮渐变色 */
|
||||
--login-gradient-start: #667eea;
|
||||
--login-gradient-end: #764ba2;
|
||||
|
||||
/* 中性色 */
|
||||
--bg-color: #f5f5f5;
|
||||
--bg-light: #fafafa;
|
||||
--bg-primary-light: #fff5f5;
|
||||
--bg-primary-lighter: #fff0f0;
|
||||
--bg-primary-lightest: #fff0e8;
|
||||
--card-bg: #ffffff;
|
||||
--text-primary: #333333;
|
||||
--text-dark: #2d3436;
|
||||
--text-secondary: #666666;
|
||||
--text-tertiary: #999999;
|
||||
--border-color: #e0e0e0;
|
||||
--border-light: #e8e8e8;
|
||||
|
||||
/* 字体 */
|
||||
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
--font-size-xs: 12px;
|
||||
--font-size-sm: 14px;
|
||||
--font-size-base: 16px;
|
||||
--font-size-lg: 18px;
|
||||
--font-size-xl: 20px;
|
||||
--font-size-2xl: 24px;
|
||||
--font-size-3xl: 32px;
|
||||
--font-size-4xl: 36px;
|
||||
|
||||
/* 间距 */
|
||||
--spacing-xs: 4px;
|
||||
--spacing-sm: 8px;
|
||||
--spacing-md: 16px;
|
||||
--spacing-lg: 24px;
|
||||
--spacing-xl: 32px;
|
||||
--spacing-xxl: 40px;
|
||||
|
||||
/* 圆角 */
|
||||
--border-radius-sm: 4px;
|
||||
--border-radius-md: 8px;
|
||||
--border-radius-lg: 12px;
|
||||
--border-radius-xl: 16px;
|
||||
--border-radius-2xl: 24px;
|
||||
--border-radius-3xl: 28px;
|
||||
--border-radius-full: 50%;
|
||||
|
||||
/* 阴影 */
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.12);
|
||||
--shadow-xl: 0 6px 20px rgba(0, 0, 0, 0.15);
|
||||
--shadow-2xl: 0 12px 32px rgba(0, 0, 0, 0.2);
|
||||
|
||||
/* 过渡 */
|
||||
--transition-fast: 0.2s ease;
|
||||
--transition-normal: 0.3s ease;
|
||||
--transition-slow: 0.5s ease;
|
||||
--transition-transform: 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
|
||||
/* 搜索框相关 */
|
||||
--search-height: 52px;
|
||||
--search-radius: 28px;
|
||||
|
||||
/* 消息相关 */
|
||||
--message-radius: 18px;
|
||||
|
||||
/* 输入框相关 */
|
||||
--input-bg: #f9fafb;
|
||||
--input-error: #ef4444;
|
||||
--error-bg: #fee2e2;
|
||||
--error-text: #dc2626;
|
||||
}
|
||||
|
||||
@@ -263,24 +263,24 @@ const removeItem = (id: number) => {
|
||||
#cart {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #f5f5f5 0%, #fafafa 100%);
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, var(--bg-color) 0%, var(--bg-light) 100%);
|
||||
padding: var(--spacing-md);
|
||||
}
|
||||
|
||||
.cart-container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #fafafa 100%);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
background: linear-gradient(135deg, var(--card-bg) 0%, var(--bg-light) 100%);
|
||||
border-radius: var(--border-radius-xl);
|
||||
box-shadow: var(--shadow-md);
|
||||
overflow: hidden;
|
||||
border: 1px solid #f0f0f0;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.cart-header {
|
||||
padding: 20px 40px;
|
||||
border-bottom: 3px solid #f0f0f0;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
||||
padding: var(--spacing-md) var(--spacing-xxl);
|
||||
border-bottom: 3px solid var(--border-color);
|
||||
background: linear-gradient(135deg, var(--card-bg) 0%, var(--bg-light) 100%);
|
||||
display: block;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
@@ -294,7 +294,7 @@ const removeItem = (id: number) => {
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 80, 0, 0.05), transparent);
|
||||
background: linear-gradient(90deg, transparent, var(--primary-light), transparent);
|
||||
transition: left 0.6s ease;
|
||||
}
|
||||
|
||||
@@ -303,94 +303,94 @@ const removeItem = (id: number) => {
|
||||
}
|
||||
|
||||
.cart-title {
|
||||
font-size: 32px;
|
||||
font-size: var(--font-size-3xl);
|
||||
font-weight: 800;
|
||||
color: #2d3436;
|
||||
color: var(--text-dark);
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
gap: var(--spacing-md);
|
||||
position: relative;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
transition: all var(--transition-transform);
|
||||
}
|
||||
|
||||
.cart-title:hover {
|
||||
color: #ff5000;
|
||||
transform: translateX(8px);
|
||||
text-shadow: 0 4px 8px rgba(255, 80, 0, 0.2);
|
||||
color: var(--primary-color);
|
||||
transform: translateX(var(--spacing-sm));
|
||||
text-shadow: 0 4px 8px rgba(var(--primary-light-rgb), 0.2);
|
||||
}
|
||||
|
||||
.cart-title i {
|
||||
font-size: 36px;
|
||||
color: #ff5000;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
font-size: var(--font-size-4xl);
|
||||
color: var(--primary-color);
|
||||
transition: all var(--transition-transform);
|
||||
}
|
||||
|
||||
.cart-title:hover i {
|
||||
transform: rotate(10deg) scale(1.2);
|
||||
filter: drop-shadow(0 2px 6px rgba(255, 80, 0, 0.3));
|
||||
filter: drop-shadow(0 2px 6px rgba(var(--primary-light-rgb), 0.3));
|
||||
}
|
||||
|
||||
.filter-buttons {
|
||||
margin-top: 20px;
|
||||
margin-top: var(--spacing-md);
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
gap: var(--spacing-md);
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
padding: 12px 36px;
|
||||
border-radius: 28px;
|
||||
font-size: 15px;
|
||||
padding: var(--spacing-sm) var(--spacing-xxl);
|
||||
border-radius: var(--border-radius-3xl);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: 600;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
border: 2px solid #e0e0e0;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #fafafa 100%);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
transition: all var(--transition-transform);
|
||||
border: 2px solid var(--border-color);
|
||||
background: linear-gradient(135deg, var(--card-bg) 0%, var(--bg-light) 100%);
|
||||
box-shadow: var(--shadow-md);
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.filter-btn.active {
|
||||
background: linear-gradient(135deg, #ff5000 0%, #ff6b00 100%);
|
||||
border-color: #ff5000;
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
|
||||
border-color: var(--primary-color);
|
||||
color: #ffffff;
|
||||
box-shadow: 0 6px 20px rgba(255, 80, 0, 0.35);
|
||||
box-shadow: 0 6px 20px rgba(var(--primary-light-rgb), 0.35);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.filter-btn:not(.active):hover {
|
||||
border-color: #ff5000;
|
||||
color: #ff5000;
|
||||
background: linear-gradient(135deg, #fff5f5 0%, #fff0f0 100%);
|
||||
box-shadow: 0 4px 16px rgba(255, 80, 0, 0.15);
|
||||
border-color: var(--primary-color);
|
||||
color: var(--primary-color);
|
||||
background: linear-gradient(135deg, var(--bg-primary-light) 0%, var(--bg-primary-lighter) 100%);
|
||||
box-shadow: 0 4px 16px rgba(var(--primary-light-rgb), 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.filter-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 8px rgba(255, 80, 0, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(var(--primary-light-rgb), 0.2);
|
||||
}
|
||||
|
||||
.cart-list {
|
||||
padding: 20px 40px;
|
||||
padding: var(--spacing-md) var(--spacing-xxl);
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.cart-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #fafafa 100%);
|
||||
border-radius: 24px;
|
||||
margin-bottom: 30px;
|
||||
border: 2px solid #f5f5f5;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
|
||||
padding: var(--spacing-md);
|
||||
background: linear-gradient(135deg, var(--card-bg) 0%, var(--bg-light) 100%);
|
||||
border-radius: var(--border-radius-2xl);
|
||||
margin-bottom: var(--spacing-xl);
|
||||
border: 2px solid var(--border-color);
|
||||
transition: all var(--transition-transform);
|
||||
box-shadow: var(--shadow-md);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
gap: 30px;
|
||||
gap: var(--spacing-xl);
|
||||
animation: float 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@@ -406,55 +406,55 @@ const removeItem = (id: number) => {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
cursor: pointer;
|
||||
accent-color: #ff5000;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
accent-color: var(--primary-color);
|
||||
transition: all var(--transition-transform);
|
||||
position: relative;
|
||||
border-radius: 6px;
|
||||
background-color: #ffffff;
|
||||
border: 2px solid #e0e0e0;
|
||||
border-radius: var(--border-radius-md);
|
||||
background-color: var(--card-bg);
|
||||
border: 2px solid var(--border-color);
|
||||
}
|
||||
|
||||
.checkbox-input:hover {
|
||||
transform: scale(1.2);
|
||||
box-shadow: 0 0 0 10px rgba(255, 80, 0, 0.12);
|
||||
border-color: #ff5000;
|
||||
box-shadow: 0 0 0 10px rgba(var(--primary-light-rgb), 0.12);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.checkbox-input:checked {
|
||||
box-shadow: 0 0 0 8px rgba(255, 80, 0, 0.25);
|
||||
border-color: #ff5000;
|
||||
box-shadow: 0 0 0 8px rgba(var(--primary-light-rgb), 0.25);
|
||||
border-color: var(--primary-color);
|
||||
animation: checkbox-pulse 0.4s ease;
|
||||
}
|
||||
|
||||
.checkbox-input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 6px rgba(255, 80, 0, 0.2);
|
||||
border-color: #ff5000;
|
||||
box-shadow: 0 0 0 6px rgba(var(--primary-light-rgb), 0.2);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
@keyframes checkbox-pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 4px rgba(255, 80, 0, 0.2);
|
||||
box-shadow: 0 0 0 4px rgba(var(--primary-light-rgb), 0.2);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 0 12px rgba(255, 80, 0, 0.1);
|
||||
box-shadow: 0 0 0 12px rgba(var(--primary-light-rgb), 0.1);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 8px rgba(255, 80, 0, 0.25);
|
||||
box-shadow: 0 0 0 8px rgba(var(--primary-light-rgb), 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
.cart-item-img-container {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
border-radius: 20px;
|
||||
border-radius: var(--border-radius-xl);
|
||||
overflow: hidden;
|
||||
border: 3px solid #f0f0f0;
|
||||
border: 3px solid var(--border-color);
|
||||
flex-shrink: 0;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
transition: all var(--transition-transform);
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, #fafafa 0%, #ffffff 100%);
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
|
||||
background: linear-gradient(135deg, var(--bg-light) 0%, var(--card-bg) 100%);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.cart-item-img-container::after {
|
||||
@@ -464,10 +464,10 @@ const removeItem = (id: number) => {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 20px;
|
||||
border-radius: var(--border-radius-xl);
|
||||
border: 3px solid transparent;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
background: linear-gradient(135deg, rgba(255, 80, 0, 0.08) 0%, rgba(255, 80, 0, 0.03) 100%);
|
||||
transition: all var(--transition-transform);
|
||||
background: linear-gradient(135deg, rgba(var(--primary-light-rgb), 0.08) 0%, rgba(var(--primary-light-rgb), 0.03) 100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@@ -478,21 +478,21 @@ const removeItem = (id: number) => {
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg, transparent, rgba(255, 80, 0, 0.1), transparent);
|
||||
background: linear-gradient(45deg, transparent, rgba(var(--primary-light-rgb), 0.1), transparent);
|
||||
transform: rotate(45deg);
|
||||
transition: all 0.6s ease;
|
||||
transition: all var(--transition-slow);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cart-item:hover .cart-item-img-container {
|
||||
border-color: #ff5000;
|
||||
border-color: var(--primary-color);
|
||||
transform: scale(1.1) translateY(-4px);
|
||||
box-shadow: 0 12px 32px rgba(255, 80, 0, 0.2);
|
||||
box-shadow: 0 12px 32px rgba(var(--primary-light-rgb), 0.2);
|
||||
}
|
||||
|
||||
.cart-item:hover .cart-item-img-container::after {
|
||||
border-color: #ff5000;
|
||||
box-shadow: 0 0 0 8px rgba(255, 80, 0, 0.2);
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 8px rgba(var(--primary-light-rgb), 0.2);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -524,9 +524,9 @@ const removeItem = (id: number) => {
|
||||
}
|
||||
|
||||
.cart-item-name {
|
||||
font-size: 18px;
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
/* 限制显示两行 */
|
||||
@@ -535,15 +535,15 @@ const removeItem = (id: number) => {
|
||||
-webkit-line-clamp: 5;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1.5;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
transition: all var(--transition-transform);
|
||||
position: relative;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.cart-item:hover .cart-item-name {
|
||||
color: #ff5000;
|
||||
transform: translateX(8px);
|
||||
text-shadow: 0 2px 6px rgba(255, 80, 0, 0.2);
|
||||
color: var(--primary-color);
|
||||
transform: translateX(var(--spacing-sm));
|
||||
text-shadow: 0 2px 6px rgba(var(--primary-light-rgb), 0.2);
|
||||
}
|
||||
|
||||
.cart-item-name::after {
|
||||
|
||||
703
src/Views/Chat.vue
Normal file
703
src/Views/Chat.vue
Normal file
@@ -0,0 +1,703 @@
|
||||
<!-- 聊天界面 -->
|
||||
<template>
|
||||
<div>
|
||||
<div id="chat">
|
||||
<!-- 左右结构 左边聊天导航栏(用户1 用户2 用户3 等 从上到下分布 一个用户一个li标签) 右边聊天内容(根据导航栏切换) -->
|
||||
<div id="chat-nav">
|
||||
<div class="nav-header">
|
||||
<h2>消息</h2>
|
||||
<!-- 搜索框 -->
|
||||
<div class="search-container">
|
||||
<input type="text" placeholder="搜索用户" v-model="searchTerm" class="search-input">
|
||||
<i class="fas fa-search search-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-list-container">
|
||||
<ul class="user-list">
|
||||
<li v-for="user in chatUsers" :key="user.id" :class="{ active: activeUserId === user.id }"
|
||||
@click="selectUser(user.id)">
|
||||
<div class="user-avatar">
|
||||
<img :src="user.avatar" :alt="user.name">
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<div class="user-header">
|
||||
<span class="user-name">{{ user.name }}</span>
|
||||
<span class="message-time">{{ user.lastMessageTime }}</span>
|
||||
</div>
|
||||
<div class="user-last-message">
|
||||
{{ user.lastMessage }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="user.unreadCount > 0" class="unread-badge">
|
||||
{{ user.unreadCount }}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右边聊天内容 -->
|
||||
<div id="chat-content">
|
||||
<!-- 聊天头部 -->
|
||||
<div v-if="activeUser" class="chat-header">
|
||||
<div class="chat-user-info">
|
||||
<div>
|
||||
<h3>{{ activeUser.name }}</h3>
|
||||
<p class="user-status">在线</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 聊天历史 -->
|
||||
<div v-if="activeUser" class="chat-history">
|
||||
<div v-for="(message, index) in messages" :key="index"
|
||||
:class="{ 'chat-message': true, 'sent': message.sender === 'me', 'received': message.sender !== 'me' }">
|
||||
<div v-if="message.sender !== 'me'" class="user-avatar small">
|
||||
<img :src="activeUser.avatar" :alt="activeUser.name">
|
||||
</div>
|
||||
<div class="message-content">
|
||||
<div class="message-text">{{ message.text }}</div>
|
||||
<div class="message-time">{{ message.time }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 消息输入区 -->
|
||||
<div v-if="activeUser" class="chat-input-area">
|
||||
<div class="input-container">
|
||||
<button class="input-btn">😊</button>
|
||||
<button class="input-btn">📎</button>
|
||||
<input type="text" v-model="newMessage" placeholder="输入消息..." class="message-input"
|
||||
@keyup.enter="sendMessage">
|
||||
<button class="input-btn">🎤</button>
|
||||
</div>
|
||||
<button class="send-btn" @click="sendMessage">发送</button>
|
||||
</div>
|
||||
<!-- 空状态 -->
|
||||
<div v-else class="empty-state">
|
||||
<img src="#" alt="选择聊天">
|
||||
<h3>选择一个聊天</h3>
|
||||
<p>开始与您的联系人聊天</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
// 搜索用户的关键词
|
||||
const searchTerm = ref('')
|
||||
|
||||
// 聊天用户数据
|
||||
const chatUsers = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '用户1',
|
||||
avatar: '?prompt=user%20avatar%20friendly%20smile&image_size=square',
|
||||
lastMessage: '你好,我想购买商品1',
|
||||
lastMessageTime: '10:00',
|
||||
unreadCount: 2
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '用户2',
|
||||
avatar: '?prompt=user%20avatar%20professional%20business&image_size=square',
|
||||
lastMessage: '订单什么时候发货?',
|
||||
lastMessageTime: '09:30',
|
||||
unreadCount: 0
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '用户3',
|
||||
avatar: '?prompt=user%20avatar%20casual%20young&image_size=square',
|
||||
lastMessage: '商品质量怎么样?',
|
||||
lastMessageTime: '昨天',
|
||||
unreadCount: 1
|
||||
}
|
||||
])
|
||||
|
||||
// 消息数据
|
||||
const messages = ref([
|
||||
{
|
||||
sender: 'user1',
|
||||
text: '你好,我想购买商品1',
|
||||
time: '10:00'
|
||||
},
|
||||
{
|
||||
sender: 'me',
|
||||
text: '您好,欢迎咨询,请问有什么可以帮助您的?',
|
||||
time: '10:01'
|
||||
},
|
||||
{
|
||||
sender: 'user1',
|
||||
text: '商品1有货吗?',
|
||||
time: '10:02'
|
||||
}
|
||||
])
|
||||
|
||||
// 当前活跃用户ID
|
||||
const activeUserId = ref(1)
|
||||
|
||||
// 新消息
|
||||
const newMessage = ref('')
|
||||
|
||||
// 计算当前活跃用户
|
||||
const activeUser = computed(() => {
|
||||
return chatUsers.value.find(user => user.id === activeUserId.value)
|
||||
})
|
||||
|
||||
// 选择用户
|
||||
const selectUser = (userId: number) => {
|
||||
activeUserId.value = userId
|
||||
// 清除未读消息数
|
||||
const user = chatUsers.value.find(user => user.id === userId)
|
||||
if (user) {
|
||||
user.unreadCount = 0
|
||||
}
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
const sendMessage = () => {
|
||||
if (newMessage.value.trim()) {
|
||||
messages.value.push({
|
||||
sender: 'me',
|
||||
text: newMessage.value,
|
||||
time: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
|
||||
})
|
||||
// 更新最后一条消息
|
||||
if (activeUser.value) {
|
||||
activeUser.value.lastMessage = newMessage.value
|
||||
activeUser.value.lastMessageTime = new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
|
||||
}
|
||||
// 清空输入框
|
||||
newMessage.value = ''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#chat {
|
||||
background-color: var(--bg-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
border-radius: var(--border-radius-lg);
|
||||
padding: var(--spacing-xl) 150px 0 150px;
|
||||
}
|
||||
|
||||
/* 左侧聊天导航栏 */
|
||||
#chat-nav {
|
||||
width: 320px;
|
||||
background-color: var(--bg-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
border-radius: var(--border-radius-lg) 0 0 var(--border-radius-lg);
|
||||
padding: var(--spacing-sm) 0 0 var(--spacing-sm);
|
||||
border: 1px solid var(--border-color);
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.nav-header {
|
||||
padding: var(--spacing-md);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-header h2 {
|
||||
margin: 0;
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.search-container {
|
||||
margin-top: var(--spacing-sm);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: var(--border-radius-xl);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--text-tertiary);
|
||||
margin-left: var(--spacing-sm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.user-list-container {
|
||||
background-color: var(--card-bg);
|
||||
overflow-x: auto;
|
||||
max-height: 50vh;
|
||||
}
|
||||
|
||||
.new-chat-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--border-radius-full);
|
||||
background-color: var(--primary-color);
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
font-size: var(--font-size-lg);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all var(--transition-normal);
|
||||
}
|
||||
|
||||
.new-chat-btn:hover {
|
||||
background-color: var(--primary-hover);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
#chat-nav .user-list-container ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#chat-nav .user-list-container li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing-md) var(--spacing-md);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-normal);
|
||||
}
|
||||
|
||||
#chat-nav .user-list-container li:hover {
|
||||
background-color: var(--bg-color);
|
||||
border-radius: var(--border-radius-sm);
|
||||
}
|
||||
|
||||
#chat-nav .user-list-container li.active {
|
||||
background-color: var(--bg-primary-lightest);
|
||||
border-radius: var(--border-radius-sm);
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: var(--border-radius-full);
|
||||
overflow: hidden;
|
||||
margin-right: var(--spacing-md);
|
||||
flex-shrink: 0;
|
||||
border-radius: var(--border-radius-lg);
|
||||
}
|
||||
|
||||
.user-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.user-avatar.small {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-right: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.user-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.user-last-message {
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--text-secondary);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.unread-badge {
|
||||
background-color: var(--primary-color);
|
||||
color: #ffffff;
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: 600;
|
||||
padding: 2px 8px;
|
||||
border-radius: var(--border-radius-xl);
|
||||
min-width: 20px;
|
||||
text-align: center;
|
||||
margin-left: var(--spacing-sm);
|
||||
}
|
||||
|
||||
/* 右侧聊天内容 */
|
||||
#chat-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 0 var(--border-radius-lg) var(--border-radius-lg) 0;
|
||||
border: 1px solid var(--border-color);
|
||||
border-left: none;
|
||||
|
||||
}
|
||||
|
||||
/* 聊天头部 */
|
||||
.chat-header {
|
||||
background-color: var(--bg-color);
|
||||
padding: var(--spacing-md) var(--spacing-md);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-radius: 0 var(--border-radius-lg) 0 0;
|
||||
|
||||
}
|
||||
|
||||
.chat-user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.chat-user-info h3 {
|
||||
margin: 0 0 2px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.user-status {
|
||||
font-size: 12px;
|
||||
color: #4caf50;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.chat-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background-color: #f0f0f0;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.action-btn:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
/* 聊天历史 */
|
||||
.chat-history {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
background-color: #f5f5f5;
|
||||
background-image: url('?prompt=chat%20background%20pattern%20subtle%20light&image_size=landscape_16_9');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.chat-message {
|
||||
display: flex;
|
||||
margin-bottom: 15px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.chat-message.sent {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.chat-message.sent .user-avatar {
|
||||
margin-right: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
max-width: 70%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.chat-message.sent .message-content {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.message-text {
|
||||
padding: 10px 15px;
|
||||
border-radius: 18px;
|
||||
margin-bottom: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.chat-message.received .message-text {
|
||||
background-color: #ffffff;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
|
||||
.chat-message.sent .message-text {
|
||||
background-color: #ff5000;
|
||||
color: #ffffff;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: 11px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 消息输入区 */
|
||||
.chat-input-area {
|
||||
background-color: #f5f5f5;
|
||||
padding: 15px 20px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-radius: 0 0 10px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.input-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 24px;
|
||||
padding: 8px 15px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.input-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.message-input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.message-input::placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
padding: 8px 20px;
|
||||
background-color: #ff5000;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.send-btn:hover {
|
||||
background-color: #ff6a00;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #f5f5f5;
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-state img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin-bottom: 20px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.empty-state h3 {
|
||||
margin: 0 0 10px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
#chat-nav {
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.chat-history {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
max-width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
#chat-nav {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
#chat-nav.active {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
#chat-content {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.chat-input-area {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
1353
src/Views/User/User.vue
Normal file
1353
src/Views/User/User.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,28 +2,902 @@
|
||||
<!-- 布局 从上到下 user信息:用户头像 用户名 -->
|
||||
<template>
|
||||
<div class="user-info">
|
||||
<!-- 用户信息头部 -->
|
||||
<div class="user-info-top">
|
||||
<div class="user-avatar">
|
||||
<!-- <img :src="user.avatar" alt="用户头像"> -->
|
||||
<div class="user-avatar-wrapper">
|
||||
<div class="user-avatar">
|
||||
<img :src="user.avatar" alt="用户头像" class="avatar-img">
|
||||
<span class="avatar-edit-badge">编辑</span>
|
||||
</div>
|
||||
<!-- <span class="user-online-indicator"></span> -->
|
||||
<div class="user-name">
|
||||
<span class="name-text">{{ user.username }}</span>
|
||||
<span class="user-level">Lv.{{ user.level }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-name">
|
||||
<div>用户名:</div>
|
||||
<div>关注店铺 收货地址</div>
|
||||
<div class="user-name-section">
|
||||
<div class="user-stats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-value">{{ user.followCount }}</span>
|
||||
<span class="stat-label">关注</span>
|
||||
</div>
|
||||
<div class="stat-divider"></div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value">{{ user.fansCount }}</span>
|
||||
<span class="stat-label">粉丝</span>
|
||||
</div>
|
||||
<div class="stat-divider"></div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value">{{ user.collectionCount }}</span>
|
||||
<span class="stat-label">收藏</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-actions">
|
||||
<a href="/user/address" class="action-link">收货地址</a>
|
||||
<a href="/user/follow" class="action-link">关注店铺</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-info-main">
|
||||
<div>
|
||||
购物信息 :购物车 待收货 代发货 待付款
|
||||
|
||||
<!-- 订单状态卡片 -->
|
||||
<div class="order-status-card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">我的订单</h3>
|
||||
<!-- <a href="/user/orders" class="card-more">查看全部 <SettingOutlined style="transform: rotate(90deg);" /></a> -->
|
||||
</div>
|
||||
<div>
|
||||
订单信息 :已完成 待评价 待付款 待发货
|
||||
<div class="order-status-grid">
|
||||
<div class="status-item" @click="navigateToOrder('pending_payment')">
|
||||
<div class="status-icon">
|
||||
<CreditCardOutlined />
|
||||
</div>
|
||||
<div class="status-label">待付款</div>
|
||||
<div class="status-badge" v-if="orderCounts.pending_payment > 0">{{ orderCounts.pending_payment }}</div>
|
||||
</div>
|
||||
<div class="status-item" @click="navigateToOrder('pending_shipment')">
|
||||
<div class="status-icon">
|
||||
<LoadingOutlined />
|
||||
</div>
|
||||
<div class="status-label">待发货</div>
|
||||
<div class="status-badge" v-if="orderCounts.pending_shipment > 0">{{ orderCounts.pending_shipment }}</div>
|
||||
</div>
|
||||
<div class="status-item" @click="navigateToOrder('pending_receipt')">
|
||||
<div class="status-icon">
|
||||
<CarOutlined />
|
||||
</div>
|
||||
<div class="status-label">待收货</div>
|
||||
<div class="status-badge" v-if="orderCounts.pending_receipt > 0">{{ orderCounts.pending_receipt }}</div>
|
||||
</div>
|
||||
<div class="status-item" @click="navigateToOrder('pending_review')">
|
||||
<div class="status-icon">
|
||||
<SolutionOutlined />
|
||||
</div>
|
||||
<div class="status-label">待评价</div>
|
||||
<div class="status-badge" v-if="orderCounts.pending_review > 0">{{ orderCounts.pending_review }}</div>
|
||||
</div>
|
||||
<div class="status-item" @click="navigateToOrder('completed')">
|
||||
<div class="status-icon">
|
||||
<CheckOutlined />
|
||||
</div>
|
||||
<div class="status-label">已完成</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
优惠 :红包 优惠卷 淘币
|
||||
</div>
|
||||
|
||||
<!-- 功能菜单网格 -->
|
||||
<div class="user-function-grid">
|
||||
<!-- 购物相关 -->
|
||||
<div class="function-card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">购物相关</h3>
|
||||
</div>
|
||||
<div class="function-grid">
|
||||
<div class="function-item" @click="navigateTo('/cart')">
|
||||
<div class="function-icon">
|
||||
<ShoppingCartOutlined />
|
||||
</div>
|
||||
<div class="function-label">购物车</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/wishlist')">
|
||||
<div class="function-icon">
|
||||
<HeartOutlined />
|
||||
</div>
|
||||
<div class="function-label">收藏夹</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/history')">
|
||||
<div class="function-icon">
|
||||
<HistoryOutlined />
|
||||
</div>
|
||||
<div class="function-label">浏览历史</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/followed_shops')">
|
||||
<div class="function-icon">
|
||||
<ShopOutlined />
|
||||
</div>
|
||||
<div class="function-label">关注店铺</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
足迹信息 : 已买完 收藏夹 购买过的店 足迹信息
|
||||
|
||||
<!-- 优惠相关 -->
|
||||
<div class="function-card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">优惠相关</h3>
|
||||
</div>
|
||||
<div class="function-grid">
|
||||
<div class="function-item" @click="navigateTo('/user/coupons')">
|
||||
<div class="function-icon">
|
||||
<GiftOutlined />
|
||||
</div>
|
||||
<div class="function-label">红包</div>
|
||||
<div class="function-badge" v-if="user.couponCount > 0">{{ user.couponCount }}</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/discounts')">
|
||||
<div class="function-icon">
|
||||
<TagOutlined />
|
||||
</div>
|
||||
<div class="function-label">优惠券</div>
|
||||
<div class="function-badge" v-if="user.discountCount > 0">{{ user.discountCount }}</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/tao_coin')">
|
||||
<div class="function-icon">
|
||||
<GoldOutlined />
|
||||
</div>
|
||||
<div class="function-label">淘币</div>
|
||||
<div class="function-value">{{ user.taoCoin }}</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/points')">
|
||||
<div class="function-icon">
|
||||
<TrophyOutlined />
|
||||
</div>
|
||||
<div class="function-label">积分</div>
|
||||
<div class="function-value">{{ user.points }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 账户相关 -->
|
||||
<div class="function-card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">账户相关</h3>
|
||||
</div>
|
||||
<div class="function-grid">
|
||||
<div class="function-item" @click="navigateTo('/user/profile')">
|
||||
<div class="function-icon">
|
||||
<SettingOutlined />
|
||||
</div>
|
||||
<div class="function-label">账户设置</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/address')">
|
||||
<div class="function-icon">
|
||||
<EnvironmentOutlined />
|
||||
</div>
|
||||
<div class="function-label">收货地址</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/customer_service')">
|
||||
<div class="function-icon">
|
||||
<CustomerServiceOutlined />
|
||||
</div>
|
||||
<div class="function-label">客服中心</div>
|
||||
</div>
|
||||
<div class="function-item" @click="navigateTo('/user/help')">
|
||||
<div class="function-icon">
|
||||
<QuestionCircleOutlined />
|
||||
</div>
|
||||
<div class="function-label">帮助中心</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ShoppingCartOutlined, HeartOutlined, HistoryOutlined, ShopOutlined, GiftOutlined, GoldOutlined, TrophyOutlined, SettingOutlined, EnvironmentOutlined, CustomerServiceOutlined, QuestionCircleOutlined, CreditCardOutlined, CarOutlined, LoadingOutlined, CheckOutlined, SolutionOutlined, TagOutlined } from '@ant-design/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 用户信息
|
||||
const user = ref({
|
||||
username: '用户名',
|
||||
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=user123',
|
||||
level: 3,
|
||||
followCount: 12,
|
||||
fansCount: 8,
|
||||
collectionCount: 25,
|
||||
couponCount: 3,
|
||||
discountCount: 5,
|
||||
taoCoin: 1280,
|
||||
points: 560
|
||||
})
|
||||
|
||||
// 订单状态数量
|
||||
const orderCounts = ref({
|
||||
pending_payment: 2,
|
||||
pending_shipment: 1,
|
||||
pending_receipt: 3,
|
||||
pending_review: 0,
|
||||
completed: 0
|
||||
})
|
||||
|
||||
// 导航到指定页面
|
||||
const navigateTo = (path: string) => {
|
||||
// 根据路径跳转到User.vue中对应的导航项
|
||||
if (path === '/user/address') {
|
||||
router.push({ path: '/user', query: { nav: 'address' } })
|
||||
} else if (path === '/user/wishlist' || path === '/user/favorite') {
|
||||
router.push({ path: '/user', query: { nav: 'favorite' } })
|
||||
} else if (path === '/user/customer_service') {
|
||||
router.push({ path: '/user', query: { nav: 'customerService' } })
|
||||
} else if (path === '/user/help') {
|
||||
router.push({ path: '/user', query: { nav: 'help' } })
|
||||
} else if (path === '/user/profile' || path === '/user/settings') {
|
||||
router.push({ path: '/user', query: { nav: 'userInfo' } })
|
||||
} else {
|
||||
// 其他路径保持不变
|
||||
router.push(path)
|
||||
}
|
||||
}
|
||||
|
||||
// 导航到订单页面并带上状态参数
|
||||
const navigateToOrder = (status: string) => {
|
||||
router.push({
|
||||
path: '/user',
|
||||
query: {
|
||||
nav: 'order',
|
||||
status: status
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-info {
|
||||
margin: 0 auto;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 用户信息头部 */
|
||||
.user-info-top {
|
||||
align-items: center;
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #4ecdc4 50%, #45b7d1 100%);
|
||||
border-radius: 16px;
|
||||
padding: 10px;
|
||||
margin-bottom: 30px;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-info-top::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(45deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.user-avatar-wrapper {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
position: relative;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
border: 4px solid rgba(255, 255, 255, 0.3);
|
||||
transition: all 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.user-avatar:hover {
|
||||
transform: scale(1.1) rotate(360deg);
|
||||
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
|
||||
border-color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.avatar-edit-badge {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: #ffffff;
|
||||
font-size: 6px;
|
||||
padding: 4px 0;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.user-online-indicator {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-color: #52c41a;
|
||||
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2px 8px rgba(82, 196, 26, 0.4);
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
.user-name-section {
|
||||
padding: 0 12px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
border-radius: 16px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.name-text {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.user-level {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
padding: 4px 12px;
|
||||
border-radius: 16px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.user-stats {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.stat-divider {
|
||||
width: 1px;
|
||||
height: 30px;
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
.user-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.action-link {
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
padding: 6px 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
border-radius: 20px;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.action-link:hover {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
transform: translateY(-2px) scale(1.05);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
backdrop-filter: blur(15px);
|
||||
}
|
||||
|
||||
/* 订单状态卡片 */
|
||||
.order-status-card {
|
||||
background-color: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 10px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
margin-top: 45px;
|
||||
}
|
||||
|
||||
.order-status-card:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: rgba(255, 107, 107, 0.2);
|
||||
}
|
||||
|
||||
.order-status-card .card-header {
|
||||
background: linear-gradient(90deg, #ff9ff3 0%, #feca57 100%);
|
||||
color: white;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
margin: -10px -10px 5px -10px;
|
||||
}
|
||||
|
||||
.order-status-card .card-title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.order-status-card .card-more {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.order-status-card .card-more:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card-more {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card-more:hover {
|
||||
color: #ff5000;
|
||||
}
|
||||
|
||||
.order-status-grid {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
padding: 16px 4px;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.status-item:hover {
|
||||
background-color: #f8f9fa;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
background-color: #f0f2f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
font-size: 24px;
|
||||
color: #666666;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.status-item:hover .status-icon {
|
||||
background-color: rgba(255, 107, 107, 0.1);
|
||||
color: #ff6b6b;
|
||||
transform: scale(1.1) rotate(5deg);
|
||||
box-shadow: 0 4px 12px rgba(255, 107, 107, 0.3);
|
||||
}
|
||||
|
||||
.status-label {
|
||||
font-size: 8px;
|
||||
color: #333333;
|
||||
margin-bottom: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.status-item:hover .status-label {
|
||||
color: #ff6b6b;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
background-color: #ff4d4f;
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
min-width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 功能菜单网格 */
|
||||
.user-function-grid {
|
||||
position: absolute;
|
||||
left: -300%;
|
||||
top: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
z-index: 10;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 1s ease;
|
||||
}
|
||||
|
||||
.user-info:hover .user-function-grid {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
left: -215%;
|
||||
}
|
||||
|
||||
.function-card {
|
||||
background-color: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
width: 160px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 调整user-info的宽度,确保左侧有足够空间显示功能菜单 */
|
||||
.user-info {
|
||||
width: 100%;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
/* 调整功能网格布局,使其在窄列中更紧凑 */
|
||||
.function-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.function-card:hover {
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
border-color: rgba(255, 107, 107, 0.2);
|
||||
}
|
||||
|
||||
/* 功能卡片头部公共样式 */
|
||||
.function-card .card-header {
|
||||
color: white;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
margin: -16px -16px 16px -16px;
|
||||
}
|
||||
|
||||
.function-card .card-title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 购物相关卡片 */
|
||||
.function-card:nth-child(1) .card-header {
|
||||
background: linear-gradient(90deg, #ff6b6b 0%, #ff8e53 100%);
|
||||
}
|
||||
|
||||
/* 优惠相关卡片 */
|
||||
.function-card:nth-child(2) .card-header {
|
||||
background: linear-gradient(90deg, #4ecdc4 0%, #45b7d1 100%);
|
||||
}
|
||||
|
||||
/* 账户相关卡片 */
|
||||
.function-card:nth-child(3) .card-header {
|
||||
background: linear-gradient(90deg, #96ceb4 0%, #feca57 100%);
|
||||
}
|
||||
|
||||
.function-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
padding: 12px 4px;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.function-item:hover {
|
||||
background-color: #f8f9fa;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.function-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background-color: #f0f2f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 6px;
|
||||
font-size: 20px;
|
||||
color: #666666;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.function-item:hover .function-icon {
|
||||
background-color: rgba(78, 205, 196, 0.1);
|
||||
color: #4ecdc4;
|
||||
transform: scale(1.1) rotate(5deg);
|
||||
box-shadow: 0 4px 12px rgba(78, 205, 196, 0.3);
|
||||
}
|
||||
|
||||
.function-label {
|
||||
font-size: 12px;
|
||||
color: #333333;
|
||||
margin-bottom: 2px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.function-item:hover .function-label {
|
||||
color: #4ecdc4;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.function-badge {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
background-color: #ff4d4f;
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
min-width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.function-value {
|
||||
font-size: 12px;
|
||||
color: #ff5000;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(82, 196, 26, 0.7);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 10px rgba(82, 196, 26, 0);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(82, 196, 26, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.user-info {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.user-info-top {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.user-avatar-wrapper {
|
||||
margin-right: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.user-stats {
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.user-actions {
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.order-status-grid {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
padding: 12px 4px;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.status-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.user-function-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.function-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.function-item {
|
||||
padding: 12px 4px;
|
||||
}
|
||||
|
||||
.function-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.function-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 调整卡片头部样式 */
|
||||
.function-card .card-header {
|
||||
padding: 10px 12px;
|
||||
margin: -16px -16px 16px -16px;
|
||||
}
|
||||
|
||||
.function-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.order-status-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.order-status-card .card-header {
|
||||
padding: 10px 12px;
|
||||
margin: -16px -16px 16px -16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.user-info-top {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.name-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.user-stats {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.order-status-grid {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
padding: 8px 2px;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.status-label {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.function-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.function-item {
|
||||
padding: 8px 2px;
|
||||
}
|
||||
|
||||
.function-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.function-label {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 375px) {
|
||||
.order-status-grid {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
}
|
||||
|
||||
.status-item {
|
||||
padding: 6px 2px;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.function-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
.function-item {
|
||||
padding: 6px 2px;
|
||||
}
|
||||
|
||||
.function-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -6,7 +6,19 @@
|
||||
</div>
|
||||
<div id="footer-copyright">
|
||||
<!-- 版权信息 -->
|
||||
<h2>Copyright @ 2023 淘淘王</h2>
|
||||
<div class="copyright-content">
|
||||
<p class="copyright-text">© 2026 TaoTaoWang. 保留所有权利</p>
|
||||
<div class="copyright-links">
|
||||
<a href="/about">关于我们</a>
|
||||
<span class="copyright-separator">|</span>
|
||||
<a href="/privacy">隐私政策</a>
|
||||
<span class="copyright-separator">|</span>
|
||||
<a href="/terms">服务条款</a>
|
||||
<span class="copyright-separator">|</span>
|
||||
<a href="/contact">联系我们</a>
|
||||
</div>
|
||||
<p class="copyright-icp">京ICP备12345678号-1 | 京公网安备11010502030123号</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -59,7 +71,7 @@ const productLists = ref([
|
||||
<style scoped>
|
||||
#footer {
|
||||
width: 100%;
|
||||
padding: 0 20px;
|
||||
padding: 0 var(--spacing-md);
|
||||
}
|
||||
h1 {
|
||||
color: #42b983;
|
||||
@@ -69,4 +81,74 @@ h1 {
|
||||
/* 高度根据内容自适应 */
|
||||
height: initial;
|
||||
}
|
||||
|
||||
/* 版权信息样式 */
|
||||
#footer-copyright {
|
||||
background-color: var(--bg-light);
|
||||
padding: var(--spacing-md) 0;
|
||||
border-top: 1px solid var(--border-light);
|
||||
margin-top: var(--spacing-xl);
|
||||
}
|
||||
|
||||
.copyright-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.copyright-text {
|
||||
margin: 0 0 var(--spacing-sm) 0;
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.copyright-links {
|
||||
margin: 0 0 var(--spacing-sm) 0;
|
||||
}
|
||||
|
||||
.copyright-links a {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
margin: 0 var(--spacing-sm);
|
||||
transition: color var(--transition-normal);
|
||||
}
|
||||
|
||||
.copyright-links a:hover {
|
||||
color: #ff5000;
|
||||
}
|
||||
|
||||
.copyright-separator {
|
||||
color: #999;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.copyright-icp {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.copyright-content {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.copyright-links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.copyright-links a {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.copyright-separator {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -5,8 +5,14 @@
|
||||
<!-- 用户信息悬浮菜单 -->
|
||||
<Dropdown :menu="{ items: userMenu }" trigger="hover">
|
||||
<div class="user-info-container">
|
||||
<Avatar size="large" src="https://api.dicebear.com/7.x/avataaars/svg?seed=user123" />
|
||||
<span class="user-name">用户名</span>
|
||||
<div class="user-avatar-wrapper">
|
||||
<Avatar size="large" src="https://api.dicebear.com/7.x/avataaars/svg?seed=user123" class="user-avatar" />
|
||||
<span class="user-online-indicator"></span>
|
||||
</div>
|
||||
<div class="user-info-text">
|
||||
<span class="user-name">用户名</span>
|
||||
<span class="user-level">Lv.3</span>
|
||||
</div>
|
||||
<span class="user-arrow">▼</span>
|
||||
</div>
|
||||
</Dropdown>
|
||||
@@ -14,11 +20,15 @@
|
||||
<div id="header-profile-right">
|
||||
<!-- 右侧功能菜单 -->
|
||||
<Dropdown :menu="{ items: rightMenu }" trigger="hover">
|
||||
<Button type="text">更多</Button>
|
||||
<Button type="text" class="header-more-btn">更多 <i class="iconfont icon-zhankaishouqi"></i></Button>
|
||||
</Dropdown>
|
||||
<a href="/">首页</a>
|
||||
<Button type="primary" @click="router.push('/cart')">购物车</Button>
|
||||
<Button type="primary" @click="router.push('/order')">订单</Button>
|
||||
<a href="/" class="header-nav-link">首页</a>
|
||||
<Button type="primary" @click="router.push('/cart')" class="header-cart-btn">
|
||||
<i class="iconfont icon-gouwuche"></i> 购物车
|
||||
</Button>
|
||||
<Button type="primary" @click="router.push('/order')" class="header-order-btn">
|
||||
<i class="iconfont icon-dingdan"></i> 订单
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Row id="header-nav-row" v-if="booleanSearch">
|
||||
@@ -31,8 +41,8 @@
|
||||
<!-- 搜索类型选择 -->
|
||||
<div class="search-type-selector">
|
||||
<ul>
|
||||
<li class="search-type-item active" @click="setSearchType('宝贝')">宝贝</li>
|
||||
<li class="search-type-item" @click="setSearchType('店铺')">店铺</li>
|
||||
<li class="search-type-item active" @click="setSearchType('宝贝', $event)">宝贝</li>
|
||||
<li class="search-type-item" @click="setSearchType('店铺', $event)">店铺</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -41,15 +51,8 @@
|
||||
<div class="search-input-prefix">
|
||||
<i class="iconfont icon-sousuo prefix-icon"></i>
|
||||
</div>
|
||||
<Input
|
||||
v-model:value="searchValue"
|
||||
placeholder="请输入搜索关键词"
|
||||
style="width: 100%"
|
||||
@search="onSearch"
|
||||
@focus="onInputFocus"
|
||||
@blur="onInputBlur"
|
||||
class="custom-search-input"
|
||||
/>
|
||||
<Input v-model:value="searchValue" placeholder="请输入搜索关键词" style="width: 100%" @search="onSearch"
|
||||
@focus="onInputFocus" @blur="onInputBlur" class="custom-search-input" />
|
||||
<div class="search-input-suffix" v-if="searchValue">
|
||||
<i class="iconfont icon-guanbi" @click="clearSearch"></i>
|
||||
</div>
|
||||
@@ -100,7 +103,7 @@ const searchValue = ref('')
|
||||
const showHistory = ref(false)
|
||||
// 标志:是否正在清空历史记录
|
||||
const isClearingHistory = ref(false)
|
||||
// 标志:是否在搜索界面
|
||||
// 控制搜索框是否显示
|
||||
const booleanSearch = ref(true)
|
||||
// 路由事件
|
||||
router.beforeEach((to, from, next) => {
|
||||
@@ -109,7 +112,7 @@ router.beforeEach((to, from, next) => {
|
||||
}
|
||||
console.log(to.name)
|
||||
// 如果在商品页面 隐藏搜索框
|
||||
if (to.name === 'productDetail') {
|
||||
if (to.name === 'productDetail' || to.name === 'chat') {
|
||||
booleanSearch.value = false
|
||||
} else {
|
||||
booleanSearch.value = true
|
||||
@@ -173,15 +176,56 @@ const onInputBlur = () => {
|
||||
}, 200)
|
||||
}
|
||||
|
||||
// 当前搜索类型
|
||||
const currentSearchType = ref('宝贝')
|
||||
|
||||
// 设置搜索类型
|
||||
const setSearchType = (type: string) => {
|
||||
const setSearchType = (type: string, event: MouseEvent) => {
|
||||
const typeItems = document.querySelectorAll('.search-type-item')
|
||||
typeItems.forEach(item => {
|
||||
item.classList.remove('active')
|
||||
})
|
||||
// 添加active类到点击的元素
|
||||
// event?.currentTarget?.classList.add('active')
|
||||
console.log('搜索类型:', type)
|
||||
// 找到当前活跃的元素
|
||||
const currentActiveItem = document.querySelector('.search-type-item.active')
|
||||
// 保存点击的元素引用
|
||||
const clickedTarget = event.currentTarget as HTMLElement
|
||||
|
||||
// 为当前活跃的元素添加消失动画
|
||||
if (currentActiveItem && currentActiveItem !== clickedTarget) {
|
||||
if (currentSearchType.value === '宝贝' && type === '店铺') {
|
||||
// 宝贝 -> 店铺:宝贝元素从左往右消失
|
||||
currentActiveItem.classList.add('animate-right-out')
|
||||
} else if (currentSearchType.value === '店铺' && type === '宝贝') {
|
||||
// 店铺 -> 宝贝:店铺元素从右往左消失
|
||||
currentActiveItem.classList.add('animate-left-out')
|
||||
}
|
||||
|
||||
// 等待消失动画完成后再继续
|
||||
setTimeout(() => {
|
||||
// 移除所有元素的类
|
||||
typeItems.forEach(item => {
|
||||
item.classList.remove('active', 'animate-left', 'animate-right', 'animate-left-out', 'animate-right-out')
|
||||
})
|
||||
|
||||
// 添加active类到点击的元素
|
||||
if (clickedTarget) {
|
||||
// 判断切换方向
|
||||
if (currentSearchType.value === '宝贝' && type === '店铺') {
|
||||
// 宝贝 -> 店铺:从左往右出现
|
||||
clickedTarget.classList.add('active', 'animate-right')
|
||||
} else if (currentSearchType.value === '店铺' && type === '宝贝') {
|
||||
// 店铺 -> 宝贝:从右往左出现
|
||||
clickedTarget.classList.add('active', 'animate-left')
|
||||
} else {
|
||||
// 默认动画
|
||||
clickedTarget.classList.add('active')
|
||||
}
|
||||
currentSearchType.value = type
|
||||
}
|
||||
console.log('搜索类型:', type)
|
||||
|
||||
}, 300)
|
||||
} else {
|
||||
// 如果点击的是当前活跃的元素,直接返回
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 清除搜索输入
|
||||
@@ -226,8 +270,8 @@ const rightMenu = [
|
||||
<style scoped>
|
||||
#header {
|
||||
width: 100%;
|
||||
background-color: #ffffff;
|
||||
padding: 10px 20px;
|
||||
background-color: var(--card-bg);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
|
||||
position: relative;
|
||||
z-index: 1000;
|
||||
@@ -242,7 +286,6 @@ const rightMenu = [
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
#header-profile-left {
|
||||
@@ -255,38 +298,290 @@ const rightMenu = [
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
gap: var(--spacing-md);
|
||||
}
|
||||
|
||||
/* 用户信息容器样式 */
|
||||
.user-info-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 20px;
|
||||
gap: var(--spacing-md);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
border-radius: var(--border-radius-3xl);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
transition: all var(--transition-transform);
|
||||
background-color: var(--card-bg);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.user-info-container:hover {
|
||||
background-color: #f0f2f5;
|
||||
background-color: var(--bg-light);
|
||||
box-shadow: var(--shadow-md);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* 用户头像区域 */
|
||||
.user-avatar-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
border: 2px solid #ffffff;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
|
||||
.user-info-container:hover .user-avatar {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.user-online-indicator {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: var(--success-color);
|
||||
border: 2px solid var(--card-bg);
|
||||
border-radius: var(--border-radius-full);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(82, 196, 26, 0.7);
|
||||
}
|
||||
|
||||
70% {
|
||||
box-shadow: 0 0 0 10px rgba(82, 196, 26, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(82, 196, 26, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 用户信息文本区域 */
|
||||
.user-info-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 14px;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.user-level {
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
color: var(--warning-color);
|
||||
background-color: #fff7e6;
|
||||
padding: 1px 6px;
|
||||
border-radius: var(--border-radius-xl);
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.user-arrow {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
transition: transform 0.3s ease;
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--text-tertiary);
|
||||
transition: transform var(--transition-transform);
|
||||
}
|
||||
|
||||
.user-info-container:hover .user-arrow {
|
||||
transform: rotate(180deg);
|
||||
transform: rotate(180deg) scale(1.1);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 右侧功能菜单样式 */
|
||||
.header-more-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xs);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-2xl);
|
||||
transition: all var(--transition-transform);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.header-more-btn:hover {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.header-nav-link {
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
border-radius: var(--border-radius-2xl);
|
||||
transition: all var(--transition-transform);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-nav-link:hover {
|
||||
color: var(--primary-color);
|
||||
background-color: var(--bg-primary-lightest);
|
||||
}
|
||||
|
||||
.header-nav-link::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 1px;
|
||||
transition: all var(--transition-transform);
|
||||
}
|
||||
|
||||
.header-nav-link:hover::after {
|
||||
width: 80%;
|
||||
left: 10%;
|
||||
}
|
||||
|
||||
/* 购物车和订单按钮样式 */
|
||||
.header-cart-btn,
|
||||
.header-order-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xs);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
border-radius: var(--border-radius-3xl);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: 500;
|
||||
transition: all var(--transition-transform);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header-cart-btn {
|
||||
background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));
|
||||
border: none;
|
||||
}
|
||||
|
||||
.header-order-btn {
|
||||
background: linear-gradient(135deg, var(--secondary-color), var(--secondary-hover));
|
||||
border: none;
|
||||
}
|
||||
|
||||
.header-cart-btn:hover,
|
||||
.header-order-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.header-cart-btn:active,
|
||||
.header-order-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.header-cart-btn::before,
|
||||
.header-order-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||||
transform: rotate(45deg);
|
||||
animation: shine 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes shine {
|
||||
0% {
|
||||
transform: rotate(45deg) translateX(-100%) translateY(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(45deg) translateX(100%) translateY(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
#header-profile {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.user-info-container {
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.user-level {
|
||||
font-size: 11px;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
#header-profile-right {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.header-nav-link {
|
||||
font-size: 13px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.header-cart-btn,
|
||||
.header-order-btn {
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.header-cart-btn i,
|
||||
.header-order-btn i,
|
||||
.header-more-btn i {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.user-info-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-info-container {
|
||||
padding: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.header-nav-link {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.header-cart-btn span,
|
||||
.header-order-btn span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.header-cart-btn,
|
||||
.header-order-btn {
|
||||
padding: 8px;
|
||||
border-radius: 50%;
|
||||
min-width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
/* Logo样式 */
|
||||
@@ -311,7 +606,7 @@ const rightMenu = [
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 700px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@@ -394,22 +689,81 @@ const rightMenu = [
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
left: -10%;
|
||||
width: 120%;
|
||||
height: 2px;
|
||||
background-color: #ff5000;
|
||||
border-radius: 1px;
|
||||
animation: slideIn 0.3s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
/* 从左往右动画 */
|
||||
.search-type-item.animate-right::after {
|
||||
animation: slideInRight 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* 从右往左动画 */
|
||||
.search-type-item.animate-left::after {
|
||||
animation: slideInLeft 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* 从左往右消失动画 */
|
||||
.search-type-item.animate-right-out::after {
|
||||
animation: slideOutRight 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* 从右往左消失动画 */
|
||||
.search-type-item.animate-left-out::after {
|
||||
animation: slideOutLeft 0.3s ease-out;
|
||||
}
|
||||
/* 搜索类型选择器从左往右动画 */
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
width: 0;
|
||||
left: 50%;
|
||||
left: -10%;
|
||||
}
|
||||
|
||||
to {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
width: 120%;
|
||||
left: -10%;
|
||||
}
|
||||
}
|
||||
/* 搜索类型选择器从右往左动画 */
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
width: 0;
|
||||
left: 120%;
|
||||
|
||||
}
|
||||
|
||||
to {
|
||||
width: 120%;
|
||||
left: -10%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 从左往右消失动画 */
|
||||
@keyframes slideOutRight {
|
||||
from {
|
||||
width: 120%;
|
||||
left: -10%;
|
||||
}
|
||||
|
||||
to {
|
||||
width: 0;
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 从右往左消失动画 */
|
||||
@keyframes slideOutLeft {
|
||||
from {
|
||||
width: 10%;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
width: 0%;
|
||||
right: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,15 +796,17 @@ const rightMenu = [
|
||||
font-size: 16px;
|
||||
min-height: 52px;
|
||||
height: 52px;
|
||||
padding: 0 50px 0 48px;
|
||||
padding: 0 25px 0 15px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
background-color: transparent;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.5px;
|
||||
box-sizing: border-box; /* 关键! */
|
||||
outline: none; /* 避免默认焦点轮廓 */
|
||||
box-sizing: border-box;
|
||||
/* 关键! */
|
||||
outline: none;
|
||||
/* 避免默认焦点轮廓 */
|
||||
}
|
||||
|
||||
/* 可选:焦点状态 */
|
||||
@@ -499,6 +855,7 @@ const rightMenu = [
|
||||
opacity: 0;
|
||||
transform: translateY(-50%) scale(0.8);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(-50%) scale(1);
|
||||
@@ -517,8 +874,7 @@ const rightMenu = [
|
||||
|
||||
/* 搜索按钮 */
|
||||
.search-button-container {
|
||||
margin-right: 1px;
|
||||
padding: 15.5px;
|
||||
padding: 16.5px 30px;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #ff5000, #ff8c00);
|
||||
color: #ffffff;
|
||||
|
||||
@@ -83,7 +83,7 @@ const adList = [
|
||||
<style scoped>
|
||||
#main {
|
||||
width: 100%;
|
||||
padding: 0 20px;
|
||||
padding: 0 var(--spacing-md);
|
||||
}
|
||||
|
||||
h1 {
|
||||
@@ -95,8 +95,8 @@ h1 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
padding: 16px 0;
|
||||
gap: var(--spacing-md);
|
||||
padding: var(--spacing-md) 0;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@@ -128,17 +128,17 @@ h1 {
|
||||
}
|
||||
/* 商品分类样式 */
|
||||
.main-content-col-top {
|
||||
padding: 20px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
padding: var(--spacing-md);
|
||||
background-color: var(--card-bg);
|
||||
border-radius: var(--border-radius-lg);
|
||||
box-shadow: var(--shadow-lg);
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
transition: all var(--transition-transform);
|
||||
}
|
||||
|
||||
.main-content-col-top:hover {
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
|
||||
box-shadow: var(--shadow-xl);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,36 +161,35 @@ h1 {
|
||||
}
|
||||
|
||||
.main-content-col-top li {
|
||||
margin-bottom: 12px;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
margin-bottom: var(--spacing-sm);
|
||||
padding: var(--spacing-sm);
|
||||
border-radius: var(--border-radius-md);
|
||||
transition: all var(--transition-transform);
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* 分类详情样式 */
|
||||
.main-content-col-top li:hover {
|
||||
background-color: #fff5f5;
|
||||
transform: translateX(8px);
|
||||
box-shadow: 0 2px 8px rgba(255, 80, 0, 0.1);
|
||||
background-color: var(--bg-primary-light);
|
||||
transform: translateX(var(--spacing-sm));
|
||||
box-shadow: 0 2px 8px rgba(var(--primary-light-rgb), 0.1);
|
||||
}
|
||||
|
||||
/* 分类项样式 */
|
||||
.category-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
gap: var(--spacing-xs);
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
border-radius: var(--border-radius-md);
|
||||
transition: all var(--transition-transform);
|
||||
}
|
||||
|
||||
.category-item:hover {
|
||||
/* .category-item:hover {
|
||||
background-color: rgba(255, 80, 0, 0.05);
|
||||
}
|
||||
} */
|
||||
|
||||
/* 分类详情样式 */
|
||||
.category-detail {
|
||||
@@ -199,17 +198,17 @@ h1 {
|
||||
top: -60px;
|
||||
width: 600px;
|
||||
height: 400px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
|
||||
padding: 20px;
|
||||
margin-left: 10px;
|
||||
background-color: var(--card-bg);
|
||||
border-radius: var(--border-radius-lg);
|
||||
box-shadow: var(--shadow-xl);
|
||||
padding: var(--spacing-md);
|
||||
margin-left: var(--spacing-sm);
|
||||
z-index: 9999;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateX(-20px);
|
||||
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
border: 2px solid #f0f0f0;
|
||||
transition: all var(--transition-transform);
|
||||
border: 2px solid var(--border-color);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
@@ -363,6 +362,7 @@ h1 {
|
||||
/* 轮播广告样式 */
|
||||
#carousel-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
@@ -371,7 +371,7 @@ h1 {
|
||||
.carousel-item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -419,20 +419,5 @@ h1 {
|
||||
|
||||
/* 个人信息样式 */
|
||||
.main-content-col-bottom {
|
||||
padding: 20px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.main-content-col-bottom h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 16px;
|
||||
background-color: #fafafa;
|
||||
border-radius: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user