first commit
This commit is contained in:
147
pages/appointment/index.js
Normal file
147
pages/appointment/index.js
Normal file
@@ -0,0 +1,147 @@
|
||||
// pages/appointment/index.js
|
||||
Page({
|
||||
data: {
|
||||
appointmentList: [],
|
||||
services: [
|
||||
{ id: 1, name: '面部护理', duration: 60, price: 298 },
|
||||
{ id: 2, name: '身体按摩', duration: 90, price: 398 },
|
||||
{ id: 3, name: '美甲服务', duration: 45, price: 158 },
|
||||
{ id: 4, name: '美发造型', duration: 120, price: 258 }
|
||||
],
|
||||
selectedDate: '',
|
||||
selectedTime: '',
|
||||
selectedService: null,
|
||||
timeSlots: ['09:00', '10:00', '11:00', '13:00', '14:00', '15:00', '16:00', '17:00'],
|
||||
currentDate: '',
|
||||
dateList: []
|
||||
},
|
||||
|
||||
onLoad: function (options) {
|
||||
this.generateDateList();
|
||||
this.setData({
|
||||
selectedDate: this.data.dateList[0].date,
|
||||
currentDate: this.data.dateList[0].date
|
||||
});
|
||||
|
||||
// 从本地存储获取预约列表
|
||||
const appointmentList = wx.getStorageSync('appointmentList') || [];
|
||||
this.setData({ appointmentList });
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
|
||||
// 刷新预约列表
|
||||
const appointmentList = wx.getStorageSync('appointmentList') || [];
|
||||
this.setData({ appointmentList });
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
onPullDownRefresh: function() {
|
||||
// 刷新预约列表
|
||||
const appointmentList = wx.getStorageSync('appointmentList') || [];
|
||||
this.setData({ appointmentList }, () => {
|
||||
wx.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
|
||||
// 生成未来7天的日期列表
|
||||
generateDateList: function() {
|
||||
const dateList = [];
|
||||
const today = new Date();
|
||||
|
||||
for (let i = 0; i < 7; i++) {
|
||||
const date = new Date(today);
|
||||
date.setDate(today.getDate() + i);
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
const weekday = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'][date.getDay()];
|
||||
|
||||
dateList.push({
|
||||
date: `${year}-${month}-${day}`,
|
||||
day: day,
|
||||
weekday: weekday
|
||||
});
|
||||
}
|
||||
|
||||
this.setData({ dateList });
|
||||
},
|
||||
|
||||
// 选择日期
|
||||
selectDate: function(e) {
|
||||
const date = e.currentTarget.dataset.date;
|
||||
this.setData({ selectedDate: date });
|
||||
},
|
||||
|
||||
// 选择时间
|
||||
selectTime: function(e) {
|
||||
const time = e.currentTarget.dataset.time;
|
||||
this.setData({ selectedTime: time });
|
||||
},
|
||||
|
||||
// 选择服务
|
||||
selectService: function(e) {
|
||||
const serviceId = e.currentTarget.dataset.id;
|
||||
const service = this.data.services.find(item => item.id === serviceId);
|
||||
this.setData({ selectedService: service });
|
||||
},
|
||||
|
||||
// 提交预约
|
||||
submitAppointment: function() {
|
||||
const { selectedDate, selectedTime, selectedService } = this.data;
|
||||
|
||||
if (!selectedDate || !selectedTime || !selectedService) {
|
||||
wx.showToast({
|
||||
title: '请完成所有选择',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建新预约
|
||||
const newAppointment = {
|
||||
id: Date.now(),
|
||||
date: selectedDate,
|
||||
time: selectedTime,
|
||||
service: selectedService,
|
||||
status: '待确认'
|
||||
};
|
||||
|
||||
// 更新预约列表
|
||||
const appointmentList = [...this.data.appointmentList, newAppointment];
|
||||
|
||||
// 保存到本地存储
|
||||
wx.setStorageSync('appointmentList', appointmentList);
|
||||
|
||||
this.setData({
|
||||
appointmentList,
|
||||
selectedTime: '',
|
||||
selectedService: null
|
||||
});
|
||||
|
||||
wx.showToast({
|
||||
title: '预约成功',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
|
||||
// 取消预约
|
||||
cancelAppointment: function(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
const appointmentList = this.data.appointmentList.filter(item => item.id !== id);
|
||||
|
||||
// 更新本地存储
|
||||
wx.setStorageSync('appointmentList', appointmentList);
|
||||
|
||||
this.setData({ appointmentList });
|
||||
|
||||
wx.showToast({
|
||||
title: '已取消预约',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
})
|
||||
9
pages/appointment/index.json
Normal file
9
pages/appointment/index.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"t-button": "tdesign-miniprogram/button/button",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-empty": "tdesign-miniprogram/empty/empty",
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar"
|
||||
},
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
92
pages/appointment/index.wxml
Normal file
92
pages/appointment/index.wxml
Normal file
@@ -0,0 +1,92 @@
|
||||
<!--pages/appointment/index.wxml-->
|
||||
<navigation-bar title="预约服务" back="{{false}}" color="black" background="#FFF"></navigation-bar>
|
||||
|
||||
<view class="appointment-container">
|
||||
<!-- 日期选择 -->
|
||||
<view class="section date-section">
|
||||
<view class="section-title">选择日期</view>
|
||||
<scroll-view scroll-x class="date-scroll">
|
||||
<view class="date-list">
|
||||
<view
|
||||
wx:for="{{dateList}}"
|
||||
wx:key="date"
|
||||
class="date-item {{selectedDate === item.date ? 'active' : ''}}"
|
||||
bindtap="selectDate"
|
||||
data-date="{{item.date}}"
|
||||
>
|
||||
<view class="date-weekday">{{item.weekday}}</view>
|
||||
<view class="date-day">{{item.day}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 时间选择 -->
|
||||
<view class="section time-section">
|
||||
<view class="section-title">选择时间</view>
|
||||
<view class="time-list">
|
||||
<view
|
||||
wx:for="{{timeSlots}}"
|
||||
wx:key="*this"
|
||||
class="time-item {{selectedTime === item ? 'active' : ''}}"
|
||||
bindtap="selectTime"
|
||||
data-time="{{item}}"
|
||||
>
|
||||
{{item}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务选择 -->
|
||||
<view class="section service-section">
|
||||
<view class="section-title">选择服务</view>
|
||||
<view class="service-list">
|
||||
<view
|
||||
wx:for="{{services}}"
|
||||
wx:key="id"
|
||||
class="service-item {{selectedService.id === item.id ? 'active' : ''}}"
|
||||
bindtap="selectService"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
<view class="service-name">{{item.name}}</view>
|
||||
<view class="service-info">
|
||||
<text class="service-duration">{{item.duration}}分钟</text>
|
||||
<text class="service-price">¥{{item.price}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<view class="submit-section">
|
||||
<t-button theme="primary" size="large" block bindtap="submitAppointment">提交预约</t-button>
|
||||
</view>
|
||||
|
||||
<!-- 我的预约列表 -->
|
||||
<view class="section my-appointments" wx:if="{{appointmentList.length > 0}}">
|
||||
<view class="section-title">我的预约</view>
|
||||
<view class="appointment-list">
|
||||
<view wx:for="{{appointmentList}}" wx:key="id" class="appointment-card">
|
||||
<view class="appointment-header">
|
||||
<view class="appointment-service">{{item.service.name}}</view>
|
||||
<view class="appointment-status {{item.status === '已确认' ? 'confirmed' : ''}}">{{item.status}}</view>
|
||||
</view>
|
||||
<view class="appointment-info">
|
||||
<view class="appointment-time">
|
||||
<t-icon name="time" size="40rpx" />
|
||||
<text>{{item.date}} {{item.time}}</text>
|
||||
</view>
|
||||
<view class="appointment-price">¥{{item.service.price}}</view>
|
||||
</view>
|
||||
<view class="appointment-actions">
|
||||
<t-button size="small" variant="outline" bindtap="cancelAppointment" data-id="{{item.id}}">取消预约</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 无预约提示 -->
|
||||
<view class="empty-appointments" wx:if="{{appointmentList.length === 0}}">
|
||||
<t-empty icon="info-circle-filled" description="暂无预约记录" />
|
||||
</view>
|
||||
</view>
|
||||
196
pages/appointment/index.wxss
Normal file
196
pages/appointment/index.wxss
Normal file
@@ -0,0 +1,196 @@
|
||||
/* pages/appointment/index.wxss */
|
||||
.appointment-container {
|
||||
padding: 30rpx;
|
||||
padding-bottom: 130rpx !important; /* 为底部标签栏留出空间 */
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 40rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
margin-bottom: 20rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 日期选择样式 */
|
||||
.date-scroll {
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date-list {
|
||||
display: flex;
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.date-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
margin-right: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #f8f8f8;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.date-item.active {
|
||||
background-color: #FF5F15;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.date-weekday {
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.date-day {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 时间选择样式 */
|
||||
.time-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.time-item {
|
||||
width: 150rpx;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
text-align: center;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 8rpx;
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.time-item.active {
|
||||
background-color: #FF5F15;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 服务选择样式 */
|
||||
.service-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.service-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 30rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #f8f8f8;
|
||||
margin-bottom: 20rpx;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.service-item.active {
|
||||
background-color: #FFF0E6;
|
||||
border: 2rpx solid #FF5F15;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.service-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.service-price {
|
||||
color: #FF5F15;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 提交按钮样式 */
|
||||
.submit-section {
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
/* 预约列表样式 */
|
||||
.appointment-card {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.appointment-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.appointment-service {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.appointment-status {
|
||||
font-size: 24rpx;
|
||||
color: #FF9500;
|
||||
background-color: #FFF5E5;
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.appointment-status.confirmed {
|
||||
color: #07C160;
|
||||
background-color: #E8F8F0;
|
||||
}
|
||||
|
||||
.appointment-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.appointment-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.appointment-time text {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.appointment-price {
|
||||
font-size: 32rpx;
|
||||
color: #FF5F15;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.appointment-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* 空状态样式 */
|
||||
.empty-appointments {
|
||||
padding: 60rpx 0;
|
||||
}
|
||||
71
pages/cart/index.js
Normal file
71
pages/cart/index.js
Normal file
@@ -0,0 +1,71 @@
|
||||
// pages/cart/index.js
|
||||
Page({
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady() {
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
|
||||
},
|
||||
|
||||
// 跳转到预约页面
|
||||
goToAppointment() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/appointment/index'
|
||||
});
|
||||
}
|
||||
})
|
||||
7
pages/cart/index.json
Normal file
7
pages/cart/index.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"t-button": "tdesign-miniprogram/button/button",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar"
|
||||
}
|
||||
}
|
||||
11
pages/cart/index.wxml
Normal file
11
pages/cart/index.wxml
Normal file
@@ -0,0 +1,11 @@
|
||||
<!--pages/cart/index.wxml-->
|
||||
<navigation-bar title="预约服务" back="{{false}}" color="black" background="#FFF"></navigation-bar>
|
||||
|
||||
<view class="appointment-redirect">
|
||||
<view class="redirect-content">
|
||||
<t-icon name="calendar" size="160rpx" color="#FF5F15" />
|
||||
<view class="redirect-title">美容服务预约</view>
|
||||
<view class="redirect-desc">在这里您可以预约我们的美容服务</view>
|
||||
<t-button theme="primary" size="large" bindtap="goToAppointment">立即预约</t-button>
|
||||
</view>
|
||||
</view>
|
||||
30
pages/cart/index.wxss
Normal file
30
pages/cart/index.wxss
Normal file
@@ -0,0 +1,30 @@
|
||||
/* pages/cart/index.wxss */
|
||||
.appointment-redirect {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
padding: 0 40rpx;
|
||||
}
|
||||
|
||||
.redirect-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.redirect-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
margin: 30rpx 0 20rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.redirect-desc {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 60rpx;
|
||||
text-align: center;
|
||||
}
|
||||
237
pages/category/index.js
Normal file
237
pages/category/index.js
Normal file
@@ -0,0 +1,237 @@
|
||||
// pages/category/index.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
// 当前选中的分类
|
||||
activeCategory: 0,
|
||||
|
||||
// 分类列表
|
||||
categories: [
|
||||
{ id: 0, name: '全部' },
|
||||
{ id: 1, name: '面部护理' },
|
||||
{ id: 2, name: '身体按摩' },
|
||||
{ id: 3, name: '美甲服务' },
|
||||
{ id: 4, name: '美发造型' },
|
||||
{ id: 5, name: '眼部护理' },
|
||||
{ id: 6, name: '身体护理' },
|
||||
{ id: 7, name: '特色项目' }
|
||||
],
|
||||
|
||||
// 服务列表
|
||||
serviceList: [
|
||||
// 面部护理
|
||||
{
|
||||
id: 101,
|
||||
categoryId: 1,
|
||||
name: '深层清洁面部护理',
|
||||
desc: '去除老化角质,深层清洁毛孔',
|
||||
price: 298,
|
||||
originalPrice: 398,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 256
|
||||
},
|
||||
{
|
||||
id: 102,
|
||||
categoryId: 1,
|
||||
name: '补水保湿面膜',
|
||||
desc: '深层补水,改善干燥缺水',
|
||||
price: 198,
|
||||
originalPrice: 258,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 312
|
||||
},
|
||||
{
|
||||
id: 103,
|
||||
categoryId: 1,
|
||||
name: '美白淡斑护理',
|
||||
desc: '改善肤色不均,淡化色斑',
|
||||
price: 358,
|
||||
originalPrice: 458,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 186
|
||||
},
|
||||
|
||||
// 身体按摩
|
||||
{
|
||||
id: 201,
|
||||
categoryId: 2,
|
||||
name: '精油SPA按摩',
|
||||
desc: '舒缓压力,放松身心',
|
||||
price: 398,
|
||||
originalPrice: 498,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 198
|
||||
},
|
||||
{
|
||||
id: 202,
|
||||
categoryId: 2,
|
||||
name: '中式推拿',
|
||||
desc: '疏通经络,缓解疲劳',
|
||||
price: 328,
|
||||
originalPrice: 428,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 156
|
||||
},
|
||||
|
||||
// 美甲服务
|
||||
{
|
||||
id: 301,
|
||||
categoryId: 3,
|
||||
name: '日式美甲套餐',
|
||||
desc: '多款式选择,持久显色',
|
||||
price: 158,
|
||||
originalPrice: 258,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 312
|
||||
},
|
||||
{
|
||||
id: 302,
|
||||
categoryId: 3,
|
||||
name: '手部护理+美甲',
|
||||
desc: '滋润双手,美甲造型',
|
||||
price: 218,
|
||||
originalPrice: 298,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 178
|
||||
},
|
||||
|
||||
// 美发造型
|
||||
{
|
||||
id: 401,
|
||||
categoryId: 4,
|
||||
name: '剪发+造型',
|
||||
desc: '专业设计,打造个性发型',
|
||||
price: 128,
|
||||
originalPrice: 168,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 345
|
||||
},
|
||||
{
|
||||
id: 402,
|
||||
categoryId: 4,
|
||||
name: '烫发套餐',
|
||||
desc: '时尚卷发,塑造立体感',
|
||||
price: 598,
|
||||
originalPrice: 698,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 132
|
||||
}
|
||||
],
|
||||
|
||||
// 当前显示的服务列表
|
||||
currentServices: []
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 如果有传入的分类ID,则设置为当前选中分类
|
||||
if (options && options.categoryId) {
|
||||
this.setData({
|
||||
activeCategory: parseInt(options.categoryId)
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化服务列表
|
||||
this.filterServices();
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换分类
|
||||
*/
|
||||
switchCategory(e) {
|
||||
const categoryId = e.currentTarget.dataset.id;
|
||||
this.setData({
|
||||
activeCategory: categoryId
|
||||
});
|
||||
|
||||
// 过滤服务列表
|
||||
this.filterServices();
|
||||
},
|
||||
|
||||
/**
|
||||
* 根据当前选中的分类过滤服务列表
|
||||
*/
|
||||
filterServices() {
|
||||
const { activeCategory, serviceList } = this.data;
|
||||
|
||||
// 如果是"全部"分类,则显示所有服务
|
||||
if (activeCategory === 0) {
|
||||
this.setData({
|
||||
currentServices: serviceList
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 否则,根据分类ID过滤服务
|
||||
const filteredServices = serviceList.filter(service => service.categoryId === activeCategory);
|
||||
this.setData({
|
||||
currentServices: filteredServices
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 跳转到服务详情页
|
||||
*/
|
||||
goToServiceDetail(e) {
|
||||
const serviceId = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/appointment/index?serviceId=${serviceId}`
|
||||
});
|
||||
}
|
||||
})
|
||||
7
pages/category/index.json
Normal file
7
pages/category/index.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar",
|
||||
"t-button": "tdesign-miniprogram/button/button",
|
||||
"t-empty": "tdesign-miniprogram/empty/empty"
|
||||
}
|
||||
}
|
||||
58
pages/category/index.wxml
Normal file
58
pages/category/index.wxml
Normal file
@@ -0,0 +1,58 @@
|
||||
<!--pages/category/index.wxml-->
|
||||
<navigation-bar title="服务分类" back="{{false}}" color="black" background="#FFF"></navigation-bar>
|
||||
|
||||
<view class="category-container">
|
||||
<!-- 左侧分类导航 -->
|
||||
<scroll-view scroll-y class="category-sidebar">
|
||||
<view
|
||||
wx:for="{{categories}}"
|
||||
wx:key="id"
|
||||
class="category-item {{activeCategory === item.id ? 'active' : ''}}"
|
||||
bindtap="switchCategory"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
{{item.name}}
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右侧服务列表 -->
|
||||
<scroll-view scroll-y class="service-content">
|
||||
<!-- 分类标题 -->
|
||||
<view class="category-title">
|
||||
{{categories[activeCategory].name}}
|
||||
<text class="category-count">{{currentServices.length}}个项目</text>
|
||||
</view>
|
||||
|
||||
<!-- 服务列表 -->
|
||||
<view class="service-list" wx:if="{{currentServices.length > 0}}">
|
||||
<view
|
||||
wx:for="{{currentServices}}"
|
||||
wx:key="id"
|
||||
class="service-card"
|
||||
bindtap="goToServiceDetail"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
<image src="{{item.image}}" mode="aspectFill" class="service-image"></image>
|
||||
<view class="service-info">
|
||||
<view class="service-name">{{item.name}}</view>
|
||||
<view class="service-desc">{{item.desc}}</view>
|
||||
<view class="service-price-row">
|
||||
<view class="service-price">
|
||||
<text class="price">¥{{item.price}}</text>
|
||||
<text class="original-price">¥{{item.originalPrice}}</text>
|
||||
</view>
|
||||
<view class="service-sales">已售{{item.sales}}</view>
|
||||
</view>
|
||||
<view class="service-btn">
|
||||
<t-button theme="primary" size="small">立即预约</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" wx:if="{{currentServices.length === 0}}">
|
||||
<t-empty icon="info-circle-filled" description="暂无相关服务" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
146
pages/category/index.wxss
Normal file
146
pages/category/index.wxss
Normal file
@@ -0,0 +1,146 @@
|
||||
/* pages/category/index.wxss */
|
||||
.category-container {
|
||||
display: flex;
|
||||
height: calc(100vh - 280rpx);
|
||||
background-color: #fff;
|
||||
/* padding-bottom: 10rpx !important; */
|
||||
/* box-sizing: border-box !important; */
|
||||
}
|
||||
|
||||
/* 左侧分类导航样式 */
|
||||
.category-sidebar {
|
||||
width: 180rpx;
|
||||
height: 100%;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.category-item.active {
|
||||
color: #FF5F15;
|
||||
font-weight: 500;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.category-item.active::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8rpx;
|
||||
height: 32rpx;
|
||||
background-color: #FF5F15;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
/* 右侧服务列表样式 */
|
||||
.service-content {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
padding: 30rpx 0;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.category-count {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
/* 服务卡片样式 */
|
||||
.service-list {
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
display: flex;
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.service-image {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 12rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.service-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.service-desc {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.service-price-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.service-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #FF5F15;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.service-sales {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.service-btn {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* 空状态样式 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60%;
|
||||
}
|
||||
178
pages/index/index.js
Normal file
178
pages/index/index.js
Normal file
@@ -0,0 +1,178 @@
|
||||
// index.js
|
||||
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
|
||||
|
||||
Component({
|
||||
data: {
|
||||
userInfo: {
|
||||
avatarUrl: defaultAvatarUrl,
|
||||
nickName: '',
|
||||
},
|
||||
hasUserInfo: false,
|
||||
canIUseGetUserProfile: wx.canIUse('getUserProfile'),
|
||||
canIUseNicknameComp: wx.canIUse('input.type.nickname'),
|
||||
|
||||
// 轮播图数据
|
||||
swiperList: [
|
||||
{ id: 1, image: 'https://img.yzcdn.cn/vant/cat.jpeg', title: '夏季护肤特惠' },
|
||||
{ id: 2, image: 'https://img.yzcdn.cn/vant/cat.jpeg', title: '面部SPA体验' },
|
||||
{ id: 3, image: 'https://img.yzcdn.cn/vant/cat.jpeg', title: '新客专享优惠' }
|
||||
],
|
||||
|
||||
// 热门服务
|
||||
hotServices: [
|
||||
{ id: 1, name: '面部护理', icon: 'help', color: '#FF5F15' },
|
||||
{ id: 2, name: '身体按摩', icon: 'time', color: '#07C160' },
|
||||
{ id: 3, name: '美甲服务', icon: 'image', color: '#FF9500' },
|
||||
{ id: 4, name: '美发造型', icon: 'shop', color: '#2878FF' }
|
||||
],
|
||||
|
||||
// 推荐项目
|
||||
recommendServices: [
|
||||
{
|
||||
id: 1,
|
||||
name: '深层清洁面部护理',
|
||||
desc: '去除老化角质,深层清洁毛孔',
|
||||
price: 298,
|
||||
originalPrice: 398,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 256
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '精油SPA按摩',
|
||||
desc: '舒缓压力,放松身心',
|
||||
price: 398,
|
||||
originalPrice: 498,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 198
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '日式美甲套餐',
|
||||
desc: '多款式选择,持久显色',
|
||||
price: 158,
|
||||
originalPrice: 258,
|
||||
image: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
sales: 312
|
||||
}
|
||||
],
|
||||
|
||||
// 美容师推荐
|
||||
beauticians: [
|
||||
{
|
||||
id: 1,
|
||||
name: '王美丽',
|
||||
title: '高级美容师',
|
||||
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
experience: '8年经验',
|
||||
specialty: '面部护理、身体SPA'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '李专家',
|
||||
title: '资深美容顾问',
|
||||
avatar: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
experience: '10年经验',
|
||||
specialty: '皮肤管理、抗衰老'
|
||||
}
|
||||
]
|
||||
},
|
||||
methods: {
|
||||
// 事件处理函数
|
||||
bindViewTap() {
|
||||
wx.navigateTo({
|
||||
url: '../logs/logs'
|
||||
})
|
||||
},
|
||||
|
||||
onChooseAvatar(e) {
|
||||
const { avatarUrl } = e.detail
|
||||
const { nickName } = this.data.userInfo
|
||||
this.setData({
|
||||
"userInfo.avatarUrl": avatarUrl,
|
||||
hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl,
|
||||
})
|
||||
},
|
||||
|
||||
onInputChange(e) {
|
||||
const nickName = e.detail.value
|
||||
const { avatarUrl } = this.data.userInfo
|
||||
this.setData({
|
||||
"userInfo.nickName": nickName,
|
||||
hasUserInfo: nickName && avatarUrl && avatarUrl !== defaultAvatarUrl,
|
||||
})
|
||||
},
|
||||
|
||||
getUserProfile(e) {
|
||||
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
|
||||
wx.getUserProfile({
|
||||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
this.setData({
|
||||
userInfo: res.userInfo,
|
||||
hasUserInfo: true
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转到服务详情
|
||||
goToServiceDetail(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/appointment/index?serviceId=${id}`
|
||||
});
|
||||
},
|
||||
|
||||
// 跳转到分类页面
|
||||
goToCategory(e) {
|
||||
const categoryId = e.currentTarget.dataset.id;
|
||||
wx.switchTab({
|
||||
url: '/pages/category/index',
|
||||
success: () => {
|
||||
// 可以通过页面栈获取分类页面实例,并设置选中的分类
|
||||
const pages = getCurrentPages();
|
||||
const categoryPage = pages[pages.length - 1];
|
||||
if (categoryPage && categoryPage.route === 'pages/category/index') {
|
||||
categoryPage.setData({
|
||||
activeCategory: categoryId
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 跳转到美容师详情
|
||||
goToBeauticianDetail(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/appointment/index?beauticianId=${id}`
|
||||
});
|
||||
},
|
||||
|
||||
// 页面显示时,初始化底部标签栏
|
||||
pageShow() {
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
// 页面创建时执行
|
||||
},
|
||||
|
||||
detached() {
|
||||
// 页面销毁时执行
|
||||
}
|
||||
},
|
||||
|
||||
pageLifetimes: {
|
||||
show() {
|
||||
// 页面显示时执行
|
||||
this.pageShow();
|
||||
}
|
||||
}
|
||||
})
|
||||
7
pages/index/index.json
Normal file
7
pages/index/index.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon",
|
||||
"t-button": "tdesign-miniprogram/button/button"
|
||||
}
|
||||
}
|
||||
95
pages/index/index.wxml
Normal file
95
pages/index/index.wxml
Normal file
@@ -0,0 +1,95 @@
|
||||
<!--index.wxml-->
|
||||
<navigation-bar title="美丽护肤" back="{{false}}" color="black" background="#FFF"></navigation-bar>
|
||||
|
||||
<scroll-view class="scrollarea" scroll-y type="list">
|
||||
<!-- 轮播图 -->
|
||||
<swiper class="banner-swiper" indicator-dots autoplay circular>
|
||||
<swiper-item wx:for="{{swiperList}}" wx:key="id">
|
||||
<view class="banner-item">
|
||||
<image src="{{item.image}}" mode="aspectFill" class="banner-image"></image>
|
||||
<view class="banner-title">{{item.title}}</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<!-- 服务分类导航 -->
|
||||
<view class="service-nav">
|
||||
<view class="service-nav-item" wx:for="{{hotServices}}" wx:key="id" bindtap="goToCategory" data-id="{{item.id}}">
|
||||
<view class="service-nav-icon" style="background-color: {{item.color}}">
|
||||
<t-icon name="{{item.icon}}" size="48rpx" color="#fff" />
|
||||
</view>
|
||||
<view class="service-nav-name">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 推荐服务 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">热门项目</text>
|
||||
<view class="section-more" bindtap="goToCategory">
|
||||
<text>查看更多</text>
|
||||
<t-icon name="chevron-right" size="32rpx" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="service-list">
|
||||
<view class="service-card" wx:for="{{recommendServices}}" wx:key="id" bindtap="goToServiceDetail" data-id="{{item.id}}">
|
||||
<image src="{{item.image}}" mode="aspectFill" class="service-image"></image>
|
||||
<view class="service-content">
|
||||
<view class="service-name">{{item.name}}</view>
|
||||
<view class="service-desc">{{item.desc}}</view>
|
||||
<view class="service-footer">
|
||||
<view class="service-price">
|
||||
<text class="price">¥{{item.price}}</text>
|
||||
<text class="original-price">¥{{item.originalPrice}}</text>
|
||||
</view>
|
||||
<view class="service-sales">已售{{item.sales}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 美容师推荐 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">美容师推荐</text>
|
||||
<view class="section-more">
|
||||
<text>查看全部</text>
|
||||
<t-icon name="chevron-right" size="32rpx" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="beautician-list">
|
||||
<view class="beautician-card" wx:for="{{beauticians}}" wx:key="id" bindtap="goToBeauticianDetail" data-id="{{item.id}}">
|
||||
<image src="{{item.avatar}}" mode="aspectFill" class="beautician-avatar"></image>
|
||||
<view class="beautician-info">
|
||||
<view class="beautician-name">{{item.name}}</view>
|
||||
<view class="beautician-title">{{item.title}}</view>
|
||||
<view class="beautician-exp">{{item.experience}} | {{item.specialty}}</view>
|
||||
</view>
|
||||
<t-button theme="primary" size="small" variant="outline" class="beautician-btn">预约</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 品牌介绍 -->
|
||||
<view class="brand-intro">
|
||||
<view class="brand-title">关于我们</view>
|
||||
<view class="brand-desc">我们致力于为您提供高品质的美容服务,让每一位顾客都能享受专业的美丽体验。</view>
|
||||
<view class="brand-contact">
|
||||
<view class="contact-item">
|
||||
<t-icon name="location" size="32rpx" color="#666" />
|
||||
<text>地址:美丽大道123号</text>
|
||||
</view>
|
||||
<view class="contact-item">
|
||||
<t-icon name="call" size="32rpx" color="#666" />
|
||||
<text>电话:123-4567-8910</text>
|
||||
</view>
|
||||
<view class="contact-item">
|
||||
<t-icon name="time" size="32rpx" color="#666" />
|
||||
<text>营业时间:10:00-21:00</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
424
pages/index/index.wxss
Normal file
424
pages/index/index.wxss
Normal file
@@ -0,0 +1,424 @@
|
||||
/**index.wxss**/
|
||||
page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--gray-1);
|
||||
/* padding-bottom: 200rpx !important; */
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.scrollarea {
|
||||
flex: 1;
|
||||
overflow-y: hidden;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* 轮播图样式 */
|
||||
.banner-swiper {
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
border-radius: 0 0 24rpx 24rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-1);
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.banner-item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: transform 0.6s ease;
|
||||
}
|
||||
|
||||
.banner-item:hover .banner-image {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
position: absolute;
|
||||
bottom: 30rpx;
|
||||
left: 30rpx;
|
||||
color: #fff;
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: bold;
|
||||
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
|
||||
background: linear-gradient(90deg, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0) 100%);
|
||||
padding: 10rpx 30rpx 10rpx 20rpx;
|
||||
border-radius: 0 var(--radius-large) var(--radius-large) 0;
|
||||
max-width: 80%;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
/* 服务导航样式 */
|
||||
.service-nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
margin: 0 20rpx 20rpx;
|
||||
border-radius: var(--radius-default);
|
||||
box-shadow: var(--shadow-1);
|
||||
}
|
||||
|
||||
.service-nav-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 25%;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.service-nav-item:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.service-nav-icon {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.service-nav-name {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--gray-10);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.service-nav-item:active .service-nav-icon {
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 通用区块样式 */
|
||||
.section {
|
||||
margin: 0 20rpx 20rpx;
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: var(--radius-default);
|
||||
box-shadow: var(--shadow-1);
|
||||
transition: var(--transition-base);
|
||||
}
|
||||
|
||||
.section:active {
|
||||
transform: translateY(2rpx);
|
||||
box-shadow: var(--shadow-1);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: bold;
|
||||
color: var(--gray-10);
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 6rpx;
|
||||
width: 8rpx;
|
||||
height: 34rpx;
|
||||
background: var(--primary-gradient);
|
||||
border-radius: var(--radius-small);
|
||||
transition: height 0.3s ease;
|
||||
}
|
||||
|
||||
.section:hover .section-title::before {
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.section-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--gray-8);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.section-more:active {
|
||||
color: var(--primary-color);
|
||||
transform: translateX(4rpx);
|
||||
}
|
||||
|
||||
/* 服务卡片样式 */
|
||||
.service-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
display: flex;
|
||||
margin-bottom: 30rpx;
|
||||
padding-bottom: 30rpx;
|
||||
border-bottom: 1rpx solid var(--gray-2);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.service-card:active {
|
||||
transform: translateX(6rpx);
|
||||
background-color: var(--gray-1);
|
||||
border-radius: var(--radius-default);
|
||||
}
|
||||
|
||||
.service-card:last-child {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.service-image {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: var(--radius-default);
|
||||
margin-right: 20rpx;
|
||||
box-shadow: var(--shadow-1);
|
||||
transition: all 0.3s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.service-card:active .service-image {
|
||||
transform: scale(0.98);
|
||||
box-shadow: var(--shadow-1);
|
||||
}
|
||||
|
||||
.service-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: 600;
|
||||
color: var(--gray-10);
|
||||
margin-bottom: 10rpx;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.service-card:active .service-name {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.service-desc {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--gray-8);
|
||||
margin-bottom: 20rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.service-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.service-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: bold;
|
||||
color: var(--primary-color);
|
||||
margin-right: 10rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.service-card:active .price {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--gray-7);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.service-sales {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--gray-7);
|
||||
background-color: var(--gray-2);
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: var(--radius-small);
|
||||
}
|
||||
|
||||
/* 美容师卡片样式 */
|
||||
.beautician-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.beautician-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid var(--gray-2);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.beautician-card:active {
|
||||
transform: translateX(6rpx);
|
||||
background-color: var(--gray-1);
|
||||
border-radius: var(--radius-default);
|
||||
}
|
||||
|
||||
.beautician-card:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.beautician-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
border: 3rpx solid #fff;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.beautician-card:active .beautician-avatar {
|
||||
transform: scale(0.95);
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.beautician-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.beautician-name {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: 600;
|
||||
color: var(--gray-10);
|
||||
margin-bottom: 6rpx;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.beautician-card:active .beautician-name {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.beautician-title {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--primary-color);
|
||||
margin-bottom: 6rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.beautician-exp {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--gray-7);
|
||||
background-color: var(--gray-2);
|
||||
display: inline-block;
|
||||
padding: 2rpx 12rpx;
|
||||
border-radius: var(--radius-small);
|
||||
}
|
||||
|
||||
.beautician-btn {
|
||||
margin-left: 20rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.beautician-card:active .beautician-btn {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* 品牌介绍样式 */
|
||||
.brand-intro {
|
||||
background-color: #fff;
|
||||
padding: 40rpx 30rpx;
|
||||
margin: 0 20rpx 30rpx;
|
||||
border-radius: var(--radius-default);
|
||||
box-shadow: var(--shadow-1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.brand-intro::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 6rpx;
|
||||
background: var(--primary-gradient);
|
||||
}
|
||||
|
||||
.brand-title {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: bold;
|
||||
color: var(--gray-10);
|
||||
margin-bottom: 20rpx;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.brand-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10rpx;
|
||||
left: 25%;
|
||||
width: 50%;
|
||||
height: 4rpx;
|
||||
background: var(--primary-gradient);
|
||||
border-radius: var(--radius-small);
|
||||
}
|
||||
|
||||
.brand-desc {
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--gray-9);
|
||||
line-height: 1.8;
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.brand-contact {
|
||||
border-top: 1rpx solid var(--gray-2);
|
||||
padding-top: 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--gray-8);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.contact-item:active {
|
||||
transform: translateX(6rpx);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.contact-item text {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
20
pages/logs/logs.js
Normal file
20
pages/logs/logs.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// logs.js
|
||||
const util = require('../../utils/util.js')
|
||||
|
||||
Component({
|
||||
data: {
|
||||
logs: []
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
this.setData({
|
||||
logs: (wx.getStorageSync('logs') || []).map(log => {
|
||||
return {
|
||||
date: util.formatTime(new Date(log)),
|
||||
timeStamp: log
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
5
pages/logs/logs.json
Normal file
5
pages/logs/logs.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar"
|
||||
}
|
||||
}
|
||||
7
pages/logs/logs.wxml
Normal file
7
pages/logs/logs.wxml
Normal file
@@ -0,0 +1,7 @@
|
||||
<!--logs.wxml-->
|
||||
<navigation-bar title="查看启动日志" back="{{true}}" color="black" background="#FFF"></navigation-bar>
|
||||
<scroll-view class="scrollarea" scroll-y type="list">
|
||||
<block wx:for="{{logs}}" wx:key="timeStamp" wx:for-item="log">
|
||||
<view class="log-item">{{index + 1}}. {{log.date}}</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
16
pages/logs/logs.wxss
Normal file
16
pages/logs/logs.wxss
Normal file
@@ -0,0 +1,16 @@
|
||||
page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.scrollarea {
|
||||
flex: 1;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.log-item {
|
||||
margin-top: 20rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.log-item:last-child {
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
160
pages/usercenter/index.js
Normal file
160
pages/usercenter/index.js
Normal file
@@ -0,0 +1,160 @@
|
||||
// pages/usercenter/index.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
userInfo: {
|
||||
avatarUrl: 'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||
nickName: '美丽用户',
|
||||
phone: '138****8888',
|
||||
level: '黄金会员',
|
||||
points: 520
|
||||
},
|
||||
|
||||
// 我的预约
|
||||
appointmentList: [],
|
||||
|
||||
// 功能列表
|
||||
functionList: [
|
||||
{ id: 1, name: '我的预约', icon: 'calendar', url: '/pages/appointment/index' },
|
||||
{ id: 2, name: '会员卡', icon: 'card', url: '/pages/member/index' },
|
||||
{ id: 3, name: '优惠券', icon: 'discount', url: '/pages/coupon/index' },
|
||||
{ id: 4, name: '积分商城', icon: 'shop', url: '/pages/points/index' }
|
||||
],
|
||||
|
||||
// 服务列表
|
||||
serviceList: [
|
||||
{ id: 1, name: '联系客服', icon: 'service', type: 'contact' },
|
||||
{ id: 2, name: '意见反馈', icon: 'chat', url: '/pages/feedback/index' },
|
||||
{ id: 3, name: '关于我们', icon: 'info-circle', url: '/pages/about/index' },
|
||||
{ id: 4, name: '设置', icon: 'setting', url: '/pages/settings/index' }
|
||||
]
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
// 获取用户信息
|
||||
const userInfo = wx.getStorageSync('userInfo');
|
||||
if (userInfo) {
|
||||
this.setData({
|
||||
'userInfo.nickName': userInfo.nickName,
|
||||
'userInfo.avatarUrl': userInfo.avatarUrl
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
|
||||
this.getTabBar().init();
|
||||
}
|
||||
|
||||
// 获取预约列表
|
||||
const appointmentList = wx.getStorageSync('appointmentList') || [];
|
||||
this.setData({ appointmentList });
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 跳转到功能页面
|
||||
*/
|
||||
goToFunction(e) {
|
||||
const url = e.currentTarget.dataset.url;
|
||||
const type = e.currentTarget.dataset.type;
|
||||
|
||||
if (type === 'contact') {
|
||||
this.contactCustomerService();
|
||||
return;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
wx.navigateTo({
|
||||
url: url
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 联系客服
|
||||
*/
|
||||
contactCustomerService() {
|
||||
wx.makePhoneCall({
|
||||
phoneNumber: '400-123-4567'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 查看预约详情
|
||||
*/
|
||||
viewAppointmentDetail(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/appointment/index?appointmentId=${id}`
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消预约
|
||||
*/
|
||||
cancelAppointment(e) {
|
||||
const id = e.currentTarget.dataset.id;
|
||||
const appointmentList = this.data.appointmentList.filter(item => item.id !== id);
|
||||
|
||||
// 更新本地存储
|
||||
wx.setStorageSync('appointmentList', appointmentList);
|
||||
|
||||
this.setData({ appointmentList });
|
||||
|
||||
wx.showToast({
|
||||
title: '已取消预约',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
})
|
||||
7
pages/usercenter/index.json
Normal file
7
pages/usercenter/index.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar",
|
||||
"t-button": "tdesign-miniprogram/button/button",
|
||||
"t-icon": "tdesign-miniprogram/icon/icon"
|
||||
}
|
||||
}
|
||||
91
pages/usercenter/index.wxml
Normal file
91
pages/usercenter/index.wxml
Normal file
@@ -0,0 +1,91 @@
|
||||
<!--pages/usercenter/index.wxml-->
|
||||
<navigation-bar title="个人中心" back="{{false}}" color="black" background="#FFF"></navigation-bar>
|
||||
|
||||
<scroll-view class="usercenter-container" scroll-y>
|
||||
<!-- 用户信息 -->
|
||||
<view class="user-info">
|
||||
<image src="{{userInfo.avatarUrl}}" mode="aspectFill" class="user-avatar"></image>
|
||||
<view class="user-detail">
|
||||
<view class="user-name">{{userInfo.nickName}}</view>
|
||||
<view class="user-level">{{userInfo.level}}</view>
|
||||
<view class="user-phone">{{userInfo.phone}}</view>
|
||||
</view>
|
||||
<view class="user-points">
|
||||
<text class="points-value">{{userInfo.points}}</text>
|
||||
<text class="points-label">积分</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 我的预约 -->
|
||||
<view class="section my-appointments" wx:if="{{appointmentList.length > 0}}">
|
||||
<view class="section-header">
|
||||
<text class="section-title">我的预约</text>
|
||||
<view class="section-more" bindtap="goToFunction" data-url="/pages/appointment/index">
|
||||
<text>查看全部</text>
|
||||
<t-icon name="chevron-right" size="32rpx" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="appointment-list">
|
||||
<view wx:for="{{appointmentList.slice(0, 2)}}" wx:key="id" class="appointment-card">
|
||||
<view class="appointment-header">
|
||||
<view class="appointment-service">{{item.service.name}}</view>
|
||||
<view class="appointment-status {{item.status === '已确认' ? 'confirmed' : ''}}">{{item.status}}</view>
|
||||
</view>
|
||||
<view class="appointment-info">
|
||||
<view class="appointment-time">
|
||||
<t-icon name="time" size="40rpx" />
|
||||
<text>{{item.date}} {{item.time}}</text>
|
||||
</view>
|
||||
<view class="appointment-price">¥{{item.service.price}}</view>
|
||||
</view>
|
||||
<view class="appointment-actions">
|
||||
<t-button size="small" variant="outline" bindtap="cancelAppointment" data-id="{{item.id}}">取消预约</t-button>
|
||||
<t-button size="small" bindtap="viewAppointmentDetail" data-id="{{item.id}}">查看详情</t-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能列表 -->
|
||||
<view class="section function-list">
|
||||
<view class="section-header">
|
||||
<text class="section-title">我的服务</text>
|
||||
</view>
|
||||
|
||||
<view class="function-grid">
|
||||
<view
|
||||
wx:for="{{functionList}}"
|
||||
wx:key="id"
|
||||
class="function-item"
|
||||
bindtap="goToFunction"
|
||||
data-url="{{item.url}}"
|
||||
>
|
||||
<t-icon name="{{item.icon}}" size="48rpx" color="#FF5F15" />
|
||||
<view class="function-name">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务列表 -->
|
||||
<view class="section service-list">
|
||||
<view class="section-header">
|
||||
<text class="section-title">服务与设置</text>
|
||||
</view>
|
||||
|
||||
<view class="service-items">
|
||||
<view
|
||||
wx:for="{{serviceList}}"
|
||||
wx:key="id"
|
||||
class="service-item"
|
||||
bindtap="goToFunction"
|
||||
data-url="{{item.url}}"
|
||||
data-type="{{item.type}}"
|
||||
>
|
||||
<t-icon name="{{item.icon}}" size="40rpx" color="#666" />
|
||||
<view class="service-name">{{item.name}}</view>
|
||||
<t-icon name="chevron-right" size="40rpx" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
229
pages/usercenter/index.wxss
Normal file
229
pages/usercenter/index.wxss
Normal file
@@ -0,0 +1,229 @@
|
||||
/* pages/usercenter/index.wxss */
|
||||
.usercenter-container {
|
||||
/* height: calc(100vh - 300rpx); */
|
||||
background-color: #f8f8f8;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
/* 用户信息样式 */
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.user-detail {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.user-level {
|
||||
font-size: 24rpx;
|
||||
color: #FF9500;
|
||||
background-color: #FFF5E5;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 20rpx;
|
||||
display: inline-block;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.user-phone {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.user-points {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #FF5F15;
|
||||
color: #fff;
|
||||
padding: 20rpx 30rpx;
|
||||
border-radius: 12rpx;
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.points-value {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.points-label {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
/* 通用区块样式 */
|
||||
.section {
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #fff;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 6rpx;
|
||||
width: 8rpx;
|
||||
height: 34rpx;
|
||||
background-color: #FF5F15;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.section-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 预约列表样式 */
|
||||
.appointment-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.appointment-card {
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.appointment-card:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.appointment-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.appointment-service {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.appointment-status {
|
||||
font-size: 24rpx;
|
||||
color: #FF9500;
|
||||
background-color: #FFF5E5;
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.appointment-status.confirmed {
|
||||
color: #07C160;
|
||||
background-color: #E8F8F0;
|
||||
}
|
||||
|
||||
.appointment-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.appointment-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.appointment-time text {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.appointment-price {
|
||||
font-size: 32rpx;
|
||||
color: #FF5F15;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.appointment-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.appointment-actions t-button {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
/* 功能网格样式 */
|
||||
.function-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.function-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 30rpx 0;
|
||||
}
|
||||
|
||||
.function-name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
/* 服务列表样式 */
|
||||
.service-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.service-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.service-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
flex: 1;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user