first commit

This commit is contained in:
lingxiao865
2025-09-18 12:39:54 +08:00
parent b2e8461792
commit 6c6fe3d0d6
1898 changed files with 30918 additions and 0 deletions

178
pages/index/index.js Normal file
View 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
View 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
View 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
View 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;
}