Browse Source

首页登录调整

master
ZhaoYang 4 weeks ago
parent
commit
0acae99616
  1. 5
      pages/home/home.js
  2. 2
      pages/home/home.wxml
  3. BIN
      pages/images/mm.png
  4. BIN
      pages/images/zh.png
  5. 345
      pages/login/login.js
  6. 88
      pages/login/login.wxml
  7. 467
      pages/login/login.wxss
  8. 2
      project.private.config.json
  9. 2
      utils/api.js

5
pages/home/home.js

@ -169,11 +169,6 @@ Page({
// 查看所有问题
viewAllQuestions() {
this.bindwdlist()
},
// 获取当前位置信息 // 获取当前位置信息
getLocation() { getLocation() {
let that = this; let that = this;

2
pages/home/home.wxml

@ -87,7 +87,7 @@
<view class="title-text">在线问答</view> <view class="title-text">在线问答</view>
<view class="title-sub">看看其他养殖户遇到的问题</view> <view class="title-sub">看看其他养殖户遇到的问题</view>
</view> </view>
<view class="view-all" bindtap="viewAllQuestions">
<view class="view-all">
查看全部 查看全部
</view> </view>
</view> </view>

BIN
pages/images/mm.png

After

Width: 200  |  Height: 200  |  Size: 4.0 KiB

BIN
pages/images/zh.png

After

Width: 200  |  Height: 200  |  Size: 3.3 KiB

345
pages/login/login.js

@ -1,199 +1,288 @@
import http from '../../utils/api' import http from '../../utils/api'
Page({ Page({
data: { data: {
isAgree: true, // 是否同意协议
showAgreementModal: false, // 是否显示协议弹窗
modalTitle: '', // 弹窗标题
modalContent: '', // 弹窗内容
isLoading: false, // 是否显示加载中,
phoneData: {},
// 账号密码
account: '',
password: '',
accountFocus: false,
passwordFocus: false,
passwordVisible: false,
// 协议相关
isAgree: true,
showAgreementModal: false,
modalTitle: '',
modalContent: '',
// 加载状态
isLoading: false,
// 登录状态
canLogin: false
}, },
onLoad() { onLoad() {
this.login()
// 检查登录状态
// this.checkLoginStatus()
}, },
// 检查登录状态
// checkLoginStatus() {
// const token = wx.getStorageSync('token')
// if (token) {
// // 已登录,跳转到首页
// wx.switchTab({
// url: '/pages/home/home'
// })
// }
// },
// 登录获取
login() {
// 小程序接口
var that = this
wx.login({
success(res) {
//登录接口
http.login({
data: {
code: res.code,
clientType: 'vet-app'
},
success: function (res) {
console.log(111111,res);
if (res.data) {
that.setData({
phoneData: res.data
// 账号输入
onAccountInput(e) {
this.setData({
account: e.detail.value
}, () => {
this.checkCanLogin()
}) })
wx.showToast({
title: res.data.message,
icon: 'none',
duration: 2000
});
}
},
if (res.data.token) {
wx.setStorageSync('token', res.data.token)
wx.switchTab({
url: '/pages/home/home'
});
}
// 密码输入
onPasswordInput(e) {
this.setData({
password: e.detail.value
}, () => {
this.checkCanLogin()
})
}, },
// 检查是否可以登录
checkCanLogin() {
const { account, password, isAgree } = this.data
this.setData({
canLogin: account.length >= 4 && password.length >= 6 && isAgree
}) })
}, },
fail: (error) => {
console.log('登录失败!' + error);
// 账号焦点
onAccountFocus() {
this.setData({ accountFocus: true })
},
onAccountBlur() {
this.setData({ accountFocus: false })
},
// 密码焦点
onPasswordFocus() {
this.setData({ passwordFocus: true })
},
onPasswordBlur() {
this.setData({ passwordFocus: false })
},
// 聚焦密码输入框
focusPassword() {
this.setData({ passwordFocus: true })
},
// 切换密码可见性 - 修复版
togglePasswordVisible(e) {
// 阻止事件冒泡
if (e && e.stopPropagation) {
e.stopPropagation()
} }
this.setData({
passwordVisible: !this.data.passwordVisible
})
},
// 切换协议同意状态
toggleAgreement() {
this.setData({
isAgree: !this.data.isAgree
}, () => {
this.checkCanLogin()
}) })
}, },
// 处理登录
handleLogin() {
const { account, password, isAgree } = this.data
if (!isAgree) {
wx.showToast({
title: '请先同意用户协议',
icon: 'none',
duration: 2000
})
return
}
if (!account || !password) {
wx.showToast({
title: '请输入账号和密码',
icon: 'none',
duration: 2000
})
return
}
if (account.length < 4) {
wx.showToast({
title: '账号长度不能小于4位',
icon: 'none',
duration: 2000
})
return
}
// 获取用户手机号
getPhoneNumber(e) {
if (!this.data.isAgree) {
if (password.length < 6) {
wx.showToast({ wx.showToast({
title: '请先同意协议',
title: '密码长度不能小于6位',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
});
return;
})
return
} }
// 显示加载中 // 显示加载中
this.setData({
isLoading: true
});
// 检查是否获取到手机号
if (e.detail.errMsg === "getPhoneNumber:ok") {
// 这里应该将加密数据发送到后端进行解密
this.data.phoneData.encryptedData = e.detail.encryptedData
this.data.phoneData.iv = e.detail.iv
http.getPhoneNumber({
data: this.data.phoneData,
success: res => {
if (res.code == 200) {
this.setData({ isLoading: true })
// 调用登录接口
http.login({
data: {
phone: account,
password: password,
clientType:'wechat_vet'
},
success: (res) => {
this.setData({ isLoading: false })
if (res.code === 200 && res.token) {
// 保存token
wx.setStorageSync('token', res.token) wx.setStorageSync('token', res.token)
wx.showToast({
title: '登录成功',
icon: 'success',
duration: 1500,
success: () => {
setTimeout(() => { setTimeout(() => {
wx.switchTab({ wx.switchTab({
url: '/pages/home/home' url: '/pages/home/home'
});
}, 1500);
this.setData({
isLoading: false
}) })
wx.showToast({
title: '登录成功',
icon: 'success',
duration: 2000
});
}, 1500)
}
})
} else { } else {
wx.showToast({ wx.showToast({
title: res.msg,
title: res.msg || '登录失败,请检查账号密码',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
});
this.setData({
isLoading:false
}) })
} }
}
})
} else {
// 用户拒绝授权
this.setData({
isLoading: false
});
},
fail: (error) => {
this.setData({ isLoading: false })
wx.showToast({ wx.showToast({
title: '需要手机号授权才能登录',
title: '网络错误,请稍后重试',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
});
})
console.error('登录失败:', error)
} }
})
}, },
// 切换协议同意状态
toggleAgreement() {
this.setData({
isAgree: !this.data.isAgree
});
},
// 显示用户协议 // 显示用户协议
showAgreement() { showAgreement() {
const content = `欢迎您使用与牧同行服务!
const content = `兽医助手用户协议
欢迎使用兽医助手
服务说明 服务说明
与牧同行为您提供智慧放牧管理牲畜追踪草场监测等服务通过我们的平台您可以更高效地管理牧场资源提升放牧效率
账号注册
1. 您需要使用手机号完成注册
2. 您应保证提供的信息真实准确完整
3. 您对账号安全负全部责任
使用规范
1. 不得利用本服务从事任何违法违规活动
2. 不得干扰或破坏本服务的正常运行
3. 遵守相关法律法规和平台规则
服务变更与终止
我们可能根据需要变更服务内容如您不同意变更可停止使用本服务
免责声明
对于不可抗力网络问题等导致的服务中断我们不承担相应责任
法律适用
本协议受中华人民共和国法律管辖
感谢您选择与牧同行`;
兽医助手是为兽医专业人士提供的工作辅助平台包括病例管理诊疗记录药品查询等功能
账号使用
1. 您需要使用真实信息注册账号
2. 账号仅限本人使用不得转借他人
3. 您对账号下的所有行为负责
信息规范
1. 请确保录入的诊疗信息真实准确
2. 尊重动物主人隐私不得泄露客户信息
3. 遵守医疗行业规范和职业道德
责任声明
1. 本平台提供的诊疗建议仅供参考
2. 最终诊疗方案由执业兽医自行判断
3. 平台不承担任何医疗责任
服务变更
我们保留修改服务条款的权利修改后会通过公告通知
感谢您使用兽医助手`
this.setData({ this.setData({
showAgreementModal: true, showAgreementModal: true,
modalTitle: '用户协议', modalTitle: '用户协议',
modalContent: content modalContent: content
});
})
}, },
// 显示隐私政策 // 显示隐私政策
showPrivacy() { showPrivacy() {
const content = `与牧同行隐私政策
我们深知个人信息对您的重要性并会尽全力保护您的个人信息安全可靠我们致力于维持您对我们的信任恪守以下原则保护您的个人信息权责一致原则目的明确原则选择同意原则最少够用原则确保安全原则主体参与原则公开透明原则等
我们如何收集和使用您的个人信息
我们仅会出于本政策所述的以下目的收集和使用您的个人信息
1. 账号注册手机号
2. 服务提供位置信息设备信息
3. 安全保障登录日志操作记录
我们如何共享转让公开披露您的个人信息
1. 我们不会与任何公司组织和个人共享您的个人信息
2. 我们不会将您的个人信息转让给任何公司组织和个人
3. 我们仅会在法律要求的情况下公开披露您的个人信息
我们如何保护您的个人信息
1. 我们已使用符合业界标准的安全防护措施保护您提供的个人信息
2. 我们会采取合理可行的措施确保未收集无关的个人信息
您的权利
您有权访问更正删除您的个人信息以及改变您授权同意的范围或撤回授权
我们如何处理儿童的个人信息
我们的服务主要面向成人如果没有父母或监护人的同意儿童不应创建自己的个人信息主体账户
本政策如何更新
我们可能适时修订本政策内容并通过公告等方式通知您
如有任何疑问请通过客服渠道联系我们`;
const content = `兽医助手隐私政策
我们重视您的隐私保护
信息收集
我们收集以下必要信息
1. 账号信息手机号姓名执业证书编号
2. 使用信息登录日志操作记录
3. 设备信息设备型号系统版本
信息使用
1. 用于提供兽医诊疗辅助服务
2. 优化和改进服务质量
3. 保障账号安全
信息保护
1. 采用加密技术保护数据
2. 严格控制访问权限
3. 定期进行安全审计
信息共享
1. 未经您同意不向第三方共享信息
2. 法律要求的情况除外
3. 可能用于统计分析匿名化处理
您的权利
1. 访问更正您的个人信息
2. 注销账号
3. 撤回授权
联系我们
如有疑问请通过客服渠道联系我们`
this.setData({ this.setData({
showAgreementModal: true, showAgreementModal: true,
modalTitle: '隐私政策', modalTitle: '隐私政策',
modalContent: content modalContent: content
});
})
}, },
// 隐藏弹窗 // 隐藏弹窗
hideModal() { hideModal() {
this.setData({ this.setData({
showAgreementModal: false showAgreementModal: false
});
})
} }
}) })

88
pages/login/login.wxml

@ -6,15 +6,14 @@
<view class="wave wave-3"></view> <view class="wave wave-3"></view>
</view> </view>
<!-- 装饰元素 -->
<!-- 装饰元素 - 兽医主题 -->
<view class="decorations"> <view class="decorations">
<view class="cloud cloud-1"></view> <view class="cloud cloud-1"></view>
<view class="cloud cloud-2"></view> <view class="cloud cloud-2"></view>
<view class="cloud cloud-3"></view> <view class="cloud cloud-3"></view>
<view class="grass grass-1"></view>
<view class="grass grass-2"></view>
<view class="grass grass-3"></view>
<view class="sheep"></view>
<view class="medical-icon icon-1">🐾</view>
<view class="medical-icon icon-2">💊</view>
<view class="medical-icon icon-3">🏥</view>
</view> </view>
<!-- 主要内容区域 --> <!-- 主要内容区域 -->
@ -28,24 +27,83 @@
</view> </view>
</view> </view>
</view> </view>
<text class="app-title">与牧同行</text>
<text class="app-title">牧医通</text>
<text class="app-subtitle">Veterinary Assistant</text>
</view> </view>
<!-- 登录区域 --> <!-- 登录区域 -->
<view class="login-section"> <view class="login-section">
<view class="welcome-text"> <view class="welcome-text">
<text class="welcome-main">欢迎回来</text>
<text class="welcome-desc">请使用手机号快捷登录</text>
<text class="welcome-main">欢迎登录</text>
<text class="welcome-desc">请输入您的手机号密码</text>
</view> </view>
<!-- 手机号登录按钮 -->
<button class="phone-login-btn" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" hover-class="phone-btn-hover">
<!-- 账号输入框 -->
<view class="input-group">
<view class="input-wrapper {{accountFocus ? 'input-focused' : ''}}">
<image class="input-icon" src="/pages/images/zh.png" mode=""/>
<input
type="text"
placeholder="请输入手机号"
placeholder-class="input-placeholder"
value="{{account}}"
bindinput="onAccountInput"
bindfocus="onAccountFocus"
bindblur="onAccountBlur"
maxlength="20"
confirm-type="next"
bindconfirm="focusPassword"
/>
</view>
<!-- 密码输入框 -->
<view class="input-wrapper {{passwordFocus ? 'input-focused' : ''}}">
<image class="input-icon" src="/pages/images/mm.png" mode=""/>
<input
type="{{passwordVisible ? 'text' : 'password'}}"
placeholder="请输入密码"
placeholder-class="input-placeholder"
value="{{password}}"
password="{{!passwordVisible}}"
bindinput="onPasswordInput"
bindfocus="onPasswordFocus"
bindblur="onPasswordBlur"
maxlength="20"
confirm-type="done"
bindconfirm="handleLogin"
/>
<view class="password-toggle" bindtap="togglePasswordVisible" data-stop="true">
<text wx:if="{{passwordVisible}}">👁️</text>
<text wx:else>👁️‍🗨️</text>
</view>
</view>
</view>
<!-- 登录按钮 -->
<button
class="login-btn {{canLogin ? '' : 'btn-disabled'}}"
hover-class="btn-hover"
bindtap="handleLogin"
disabled="{{!canLogin}}"
>
<view class="btn-inner"> <view class="btn-inner">
<image src="/pages/images/sjh.png" mode="" />
<text class="btn-text">手机号快捷登录</text>
<text class="btn-text">登录</text>
</view> </view>
</button> </button>
<!-- 其他选项 -->
<view class="options-section">
<view class="option-item" bindtap="showAgreement">
<text class="option-text">用户协议</text>
</view>
<view class="option-item" bindtap="showPrivacy">
<text class="option-text">隐私政策</text>
</view>
<view class="option-item" bindtap="forgotPassword">
<text class="option-text">忘记密码</text>
</view>
</view>
<!-- 协议确认 --> <!-- 协议确认 -->
<view class="agreement-section"> <view class="agreement-section">
<view class="agreement-checkbox {{isAgree ? 'checked' : ''}}" bindtap="toggleAgreement"> <view class="agreement-checkbox {{isAgree ? 'checked' : ''}}" bindtap="toggleAgreement">
@ -53,9 +111,9 @@
</view> </view>
<view class="agreement-text"> <view class="agreement-text">
我已阅读并同意 我已阅读并同意
<view class="link" bindtap="showAgreement">《用户协议》</view>
<text class="link" bindtap="showAgreement">《用户协议》</text>
<view class="link" bindtap="showPrivacy">《隐私政策》</view>
<text class="link" bindtap="showPrivacy">《隐私政策》</text>
</view> </view>
</view> </view>
</view> </view>
@ -66,7 +124,7 @@
<view class="bottom-wave"></view> <view class="bottom-wave"></view>
</view> </view>
<!-- 协议弹窗 -->
<!-- 协议弹窗(使用原样式) -->
<view class="agreement-modal" wx:if="{{showAgreementModal}}"> <view class="agreement-modal" wx:if="{{showAgreementModal}}">
<view class="modal-mask" bindtap="hideModal"></view> <view class="modal-mask" bindtap="hideModal"></view>
<view class="modal-content"> <view class="modal-content">

467
pages/login/login.wxss

@ -5,7 +5,7 @@
width: 100%; width: 100%;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
background: linear-gradient(180deg, #f8fafc 0%, #f0f9ff 100%);
background: linear-gradient(180deg, #f0f9ff 0%, #e6f3fe 100%);
} }
/* 波浪背景 */ /* 波浪背景 */
@ -14,7 +14,7 @@
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 400rpx;
height: 450rpx;
overflow: hidden; overflow: hidden;
} }
@ -23,39 +23,43 @@
bottom: 0; bottom: 0;
width: 200%; width: 200%;
height: 100%; height: 100%;
background: linear-gradient(90deg, #86D8D0 0%, #A8E6CF 100%);
background: linear-gradient(135deg, #4A90E2 0%, #67B26F 100%);
border-radius: 0 0 50% 50%; border-radius: 0 0 50% 50%;
animation: waveMove 15s linear infinite;
animation: waveMove 15s ease-in-out infinite;
} }
.wave-1 { .wave-1 {
opacity: 0.7;
opacity: 0.8;
animation-delay: 0s; animation-delay: 0s;
} }
.wave-2 { .wave-2 {
opacity: 0.5; opacity: 0.5;
animation-delay: 5s; animation-delay: 5s;
background: linear-gradient(90deg, #7ACCC4 0%, #98D6C6 100%);
background: linear-gradient(135deg, #5A9FE2 0%, #77C27F 100%);
} }
.wave-3 { .wave-3 {
opacity: 0.3; opacity: 0.3;
animation-delay: 10s; animation-delay: 10s;
background: linear-gradient(90deg, #6EC0B8 0%, #88C6BD 100%);
background: linear-gradient(135deg, #6AAFE2 0%, #87D28F 100%);
} }
@keyframes waveMove { @keyframes waveMove {
0% { 0% {
transform: translateX(0) rotate(0deg); transform: translateX(0) rotate(0deg);
} }
25% {
transform: translateX(-15%) rotate(1deg);
}
50% { 50% {
transform: translateX(-25%) rotate(1deg);
transform: translateX(-25%) rotate(0deg);
}
75% {
transform: translateX(-15%) rotate(-1deg);
} }
100% { 100% {
transform: translateX(-50%) rotate(0deg);
transform: translateX(0) rotate(0deg);
} }
} }
@ -69,108 +73,85 @@
.cloud { .cloud {
position: absolute; position: absolute;
background-color: rgba(255, 255, 255, 0.9);
background: rgba(255, 255, 255, 0.9);
border-radius: 100rpx; border-radius: 100rpx;
filter: blur(2rpx);
} }
.cloud-1 { .cloud-1 {
width: 120rpx;
height: 40rpx;
width: 140rpx;
height: 45rpx;
top: 120rpx; top: 120rpx;
left: 10%;
left: 8%;
box-shadow: box-shadow:
20rpx 0 0 0 rgba(255, 255, 255, 0.9),
40rpx 0 0 0 rgba(255, 255, 255, 0.9);
25rpx 0 0 0 rgba(255, 255, 255, 0.9),
50rpx 0 0 0 rgba(255, 255, 255, 0.9);
animation: floatCloud 20s infinite;
} }
.cloud-2 { .cloud-2 {
width: 90rpx;
height: 30rpx;
width: 100rpx;
height: 35rpx;
top: 80rpx; top: 80rpx;
right: 15%;
right: 12%;
box-shadow: box-shadow:
15rpx 0 0 0 rgba(255, 255, 255, 0.9),
30rpx 0 0 0 rgba(255, 255, 255, 0.9);
18rpx 0 0 0 rgba(255, 255, 255, 0.9),
36rpx 0 0 0 rgba(255, 255, 255, 0.9);
animation: floatCloud 25s infinite reverse;
} }
.cloud-3 { .cloud-3 {
width: 70rpx;
height: 25rpx;
width: 80rpx;
height: 28rpx;
top: 180rpx; top: 180rpx;
left: 70%;
left: 65%;
box-shadow: box-shadow:
12rpx 0 0 0 rgba(255, 255, 255, 0.9),
24rpx 0 0 0 rgba(255, 255, 255, 0.9);
14rpx 0 0 0 rgba(255, 255, 255, 0.9),
28rpx 0 0 0 rgba(255, 255, 255, 0.9);
animation: floatCloud 18s infinite;
} }
.grass {
position: absolute;
bottom: 0;
width: 8rpx;
background-color: #86D8D0;
border-radius: 4rpx 4rpx 0 0;
@keyframes floatCloud {
0%, 100% {
transform: translateX(0);
} }
.grass-1 {
height: 80rpx;
left: 20%;
}
.grass-2 {
height: 60rpx;
left: 35%;
50% {
transform: translateX(30rpx);
} }
.grass-3 {
height: 100rpx;
left: 50%;
} }
.grass:before,
.grass:after {
content: '';
.medical-icon {
position: absolute; position: absolute;
width: 8rpx;
background-color: #86D8D0;
border-radius: 4rpx;
font-size: 60rpx;
opacity: 0.2;
animation: floatIcon 6s ease-in-out infinite;
} }
.grass:before {
height: 40rpx;
transform: rotate(-30deg);
top: -20rpx;
left: -10rpx;
.icon-1 {
top: 200rpx;
left: 15%;
animation-delay: 0s;
} }
.grass:after {
height: 30rpx;
transform: rotate(30deg);
top: -15rpx;
right: -10rpx;
.icon-2 {
bottom: 200rpx;
right: 15%;
animation-delay: 1s;
} }
.sheep {
position: absolute;
bottom: 120rpx;
right: 20%;
width: 80rpx;
height: 50rpx;
background-color: white;
border-radius: 50%;
box-shadow:
-15rpx -10rpx 0 0 white,
15rpx -8rpx 0 0 white;
.icon-3 {
bottom: 300rpx;
left: 20%;
animation-delay: 2s;
} }
.sheep:before {
content: '';
position: absolute;
width: 20rpx;
height: 20rpx;
background-color: #333;
border-radius: 50%;
top: -5rpx;
left: 15rpx;
@keyframes floatIcon {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-20rpx) rotate(5deg);
}
} }
/* 主要内容区域 */ /* 主要内容区域 */
@ -181,7 +162,8 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0 60rpx; padding: 0 60rpx;
padding-top: 120rpx;
padding-top: 100rpx;
box-sizing: border-box;
} }
/* Logo区域 */ /* Logo区域 */
@ -189,24 +171,32 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
margin-bottom: 120rpx;
margin-bottom: 60rpx;
animation: logoAppear 1s ease-out;
} }
.logo-container {
margin-bottom: 40rpx;
@keyframes logoAppear {
0% {
opacity: 0;
transform: scale(0.8);
}
100% {
opacity: 1;
transform: scale(1);
}
} }
.logo-circle { .logo-circle {
width: 180rpx;
height: 180rpx;
width: 160rpx;
height: 160rpx;
border-radius: 50%; border-radius: 50%;
background: linear-gradient(135deg, #86D8D0 0%, #6BC4BC 100%);
background: linear-gradient(135deg, #4A90E2, #67B26F);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: box-shadow:
0 20rpx 40rpx rgba(134, 216, 208, 0.3),
inset 0 -4rpx 8rpx rgba(107, 196, 188, 0.4),
0 20rpx 40rpx rgba(74, 144, 226, 0.3),
inset 0 -4rpx 8rpx rgba(0, 0, 0, 0.1),
inset 0 4rpx 8rpx rgba(255, 255, 255, 0.8); inset 0 4rpx 8rpx rgba(255, 255, 255, 0.8);
position: relative; position: relative;
} }
@ -214,87 +204,173 @@
.logo-circle:before { .logo-circle:before {
content: ''; content: '';
position: absolute; position: absolute;
width: 160rpx;
height: 160rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%; border-radius: 50%;
border: 2rpx solid rgba(255, 255, 255, 0.3);
border: 2rpx solid rgba(255, 255, 255, 0.5);
} }
.logo-inner { .logo-inner {
width: 140rpx;
height: 140rpx;
width: 120rpx;
height: 120rpx;
border-radius: 50%; border-radius: 50%;
background: white; background: white;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow:
inset 0 4rpx 8rpx rgba(134, 216, 208, 0.2),
0 4rpx 8rpx rgba(0, 0, 0, 0.1);
box-shadow: inset 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
} }
.logo-text { .logo-text {
font-size: 64rpx;
font-size: 70rpx;
font-weight: bold; font-weight: bold;
color: #86D8D0;
letter-spacing: 4rpx;
line-height: 1;
} }
.app-title { .app-title {
font-size: 56rpx;
font-size: 48rpx;
font-weight: 700; font-weight: 700;
color: #333;
margin-bottom: 16rpx;
color: #2c3e50;
margin-bottom: 8rpx;
letter-spacing: 2rpx; letter-spacing: 2rpx;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
} }
.app-subtitle {
font-size: 24rpx;
color: #7f8c8d;
letter-spacing: 4rpx;
text-transform: uppercase;
}
/* 登录区域 */ /* 登录区域 */
.login-section { .login-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
flex: 1;
} }
.welcome-text { .welcome-text {
text-align: center; text-align: center;
margin-bottom: 80rpx;
margin-bottom: 60rpx;
animation: slideUp 0.8s ease-out;
}
@keyframes slideUp {
0% {
opacity: 0;
transform: translateY(30rpx);
}
100% {
opacity: 1;
transform: translateY(0);
}
} }
.welcome-main { .welcome-main {
display: block; display: block;
font-size: 44rpx;
font-size: 40rpx;
font-weight: 600; font-weight: 600;
color: #333;
margin-bottom: 16rpx;
color: #2c3e50;
margin-bottom: 12rpx;
} }
.welcome-desc { .welcome-desc {
display: block; display: block;
font-size: 26rpx;
color: #95a5a6;
}
/* 输入框组 */
.input-group {
width: 100%;
margin-bottom: 40rpx;
animation: slideUp 0.8s ease-out 0.1s both;
}
.input-wrapper {
display: flex;
align-items: center;
background: white;
border-radius: 60rpx;
padding: 0 30rpx;
margin-bottom: 30rpx;
transition: all 0.3s ease;
}
.input-wrapper.input-focused {
border-color: #4A90E2;
box-shadow: 0 8rpx 20rpx rgba(74, 144, 226, 0.15);
transform: translateY(-2rpx);
}
.input-icon {
margin-right: 20rpx;
opacity: 0.7;
width: 40rpx;
height: 40rpx;
}
.input-wrapper input {
flex: 1;
height: 90rpx;
font-size: 28rpx;
color: #2c3e50;
}
.input-placeholder {
color: #bdc3c7;
font-size: 28rpx; font-size: 28rpx;
color: #888;
font-weight: 300;
} }
/* 手机号登录按钮 */
.phone-login-btn {
.password-toggle {
padding: 20rpx;
font-size: 36rpx;
opacity: 0.6;
transition: opacity 0.3s ease;
/* 提高点击区域 */
min-width: 80rpx;
display: flex;
align-items: center;
justify-content: center;
/* 防止事件冒泡 */
z-index: 10;
}
.password-toggle:active {
opacity: 1;
transform: scale(1.1);
}
/* 登录按钮 */
.login-btn {
width: 100%; width: 100%;
height: 100rpx; height: 100rpx;
border-radius: 50rpx; border-radius: 50rpx;
background: linear-gradient(to right, #86D8D0, #6BC4BC);
box-shadow:
0 12rpx 24rpx rgba(134, 216, 208, 0.3),
0 4rpx 12rpx rgba(0, 0, 0, 0.08);
margin-bottom: 50rpx;
background: linear-gradient(135deg, #4A90E2, #67B26F);
box-shadow: 0 12rpx 30rpx rgba(74, 144, 226, 0.3);
margin-bottom: 40rpx;
transition: all 0.3s ease; transition: all 0.3s ease;
animation: slideUp 0.8s ease-out 0.2s both;
border: none;
padding: 0;
line-height: 100rpx;
}
.login-btn::after{
border: none;
} }
.phone-btn-hover {
transform: translateY(-4rpx);
box-shadow:
0 16rpx 32rpx rgba(134, 216, 208, 0.4),
0 6rpx 16rpx rgba(0, 0, 0, 0.12);
.login-btn.btn-disabled {
opacity: 0.5;
background: #bdc3c7;
box-shadow: none;
pointer-events: none;
}
.btn-hover {
transform: translateY(-4rpx) scale(1.02);
box-shadow: 0 16rpx 40rpx rgba(74, 144, 226, 0.4);
} }
.btn-inner { .btn-inner {
@ -302,20 +378,47 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
height: 100%; height: 100%;
width: 100%;
} }
.btn-inner image {
width: 45rpx;
height: 45rpx;
padding: 0 20rpx;
}
.btn-text { .btn-text {
color: white; color: white;
font-size: 34rpx; font-size: 34rpx;
font-weight: 500;
letter-spacing: 2rpx;
font-weight: 600;
letter-spacing: 4rpx;
}
/* 其他选项 */
.options-section {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 30rpx;
animation: slideUp 0.8s ease-out 0.3s both;
}
.option-item {
padding: 0 25rpx;
position: relative;
}
.option-item:not(:last-child):after {
content: '|';
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
color: #e0e0e0;
}
.option-text {
font-size: 26rpx;
color: #7f8c8d;
transition: color 0.3s ease;
}
.option-item:active .option-text {
color: #4A90E2;
} }
/* 协议确认 */ /* 协议确认 */
@ -323,13 +426,14 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
animation: slideUp 0.8s ease-out 0.4s both;
} }
.agreement-checkbox { .agreement-checkbox {
width: 30rpx;
height: 30rpx;
border: 2rpx solid #ccc;
border-radius: 6rpx;
width: 32rpx;
height: 32rpx;
border: 2rpx solid #bdc3c7;
border-radius: 8rpx;
margin-right: 16rpx; margin-right: 16rpx;
display: flex; display: flex;
align-items: center; align-items: center;
@ -338,8 +442,8 @@
} }
.agreement-checkbox.checked { .agreement-checkbox.checked {
background-color: #86D8D0;
border-color: #86D8D0;
background: linear-gradient(135deg, #4A90E2, #67B26F);
border-color: transparent;
} }
.checkmark { .checkmark {
@ -350,13 +454,17 @@
.agreement-text { .agreement-text {
font-size: 24rpx; font-size: 24rpx;
color: #888;
display: flex;
align-items: center;
color: #7f8c8d;
} }
.link { .link {
color: #86D8D0;
color: #4A90E2;
display: inline;
padding: 0 4rpx;
}
.link:active {
opacity: 0.7;
} }
/* 底部装饰 */ /* 底部装饰 */
@ -375,20 +483,19 @@
left: 0; left: 0;
width: 200%; width: 200%;
height: 200%; height: 200%;
background: linear-gradient(90deg, #86D8D0 0%, #A8E6CF 100%);
background: linear-gradient(90deg, #4A90E2, #67B26F);
border-radius: 50% 50% 0 0; border-radius: 50% 50% 0 0;
animation: bottomWave 20s linear infinite; animation: bottomWave 20s linear infinite;
opacity: 0.2;
} }
@keyframes bottomWave { @keyframes bottomWave {
0% { 0% {
transform: translateX(0) rotate(0deg); transform: translateX(0) rotate(0deg);
} }
50% { 50% {
transform: translateX(-25%) rotate(0.5deg); transform: translateX(-25%) rotate(0.5deg);
} }
100% { 100% {
transform: translateX(-50%) rotate(0deg); transform: translateX(-50%) rotate(0deg);
} }
@ -444,6 +551,11 @@
font-size: 48rpx; font-size: 48rpx;
color: #999; color: #999;
line-height: 1; line-height: 1;
padding: 0 20rpx;
}
.modal-close:active {
color: #666;
} }
.modal-body { .modal-body {
@ -457,6 +569,63 @@
color: #666; color: #666;
line-height: 1.8; line-height: 1.8;
padding: 20rpx 0; padding: 20rpx 0;
white-space: pre-line;
}
/* 忘记密码弹窗内容 */
.forgot-tip {
font-size: 32rpx;
color: #333;
font-weight: 500;
margin-bottom: 40rpx;
text-align: center;
}
.contact-info {
background: #f8f9fa;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 40rpx;
}
.contact-item {
display: flex;
justify-content: center;
margin-bottom: 20rpx;
font-size: 28rpx;
}
.contact-item:last-child {
margin-bottom: 0;
}
.contact-label {
color: #999;
margin-right: 20rpx;
}
.contact-value {
color: #333;
font-weight: 500;
}
.contact-btn {
width: 80%;
height: 80rpx;
border-radius: 40rpx;
background: linear-gradient(135deg, #4A90E2, #67B26F);
color: white;
font-size: 32rpx;
font-weight: 500;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
border: none;
}
.contact-btn:active {
opacity: 0.8;
} }
/* 加载提示 */ /* 加载提示 */
@ -482,8 +651,8 @@
.loading-spinner { .loading-spinner {
width: 80rpx; width: 80rpx;
height: 80rpx; height: 80rpx;
border: 6rpx solid rgba(134, 216, 208, 0.2);
border-top-color: #86D8D0;
border: 6rpx solid rgba(74, 144, 226, 0.2);
border-top-color: #4A90E2;
border-radius: 50%; border-radius: 50%;
animation: loadingSpin 1s linear infinite; animation: loadingSpin 1s linear infinite;
margin-bottom: 30rpx; margin-bottom: 30rpx;
@ -493,7 +662,6 @@
0% { 0% {
transform: rotate(0deg); transform: rotate(0deg);
} }
100% { 100% {
transform: rotate(360deg); transform: rotate(360deg);
} }
@ -502,5 +670,4 @@
.loading-text { .loading-text {
font-size: 28rpx; font-size: 28rpx;
color: #fff; color: #fff;
font-weight: 300;
} }

2
project.private.config.json

@ -4,7 +4,7 @@
"setting": { "setting": {
"compileHotReLoad": true, "compileHotReLoad": true,
"skylineRenderEnable": true, "skylineRenderEnable": true,
"urlCheck": false,
"urlCheck": true,
"coverView": true, "coverView": true,
"lazyloadPlaceholderEnable": false, "lazyloadPlaceholderEnable": false,
"preloadBackgroundData": false, "preloadBackgroundData": false,

2
utils/api.js

@ -3,7 +3,7 @@ import { http } from './http'; // 引入刚刚封装好的http模块,import属
// 授权登录接口 // 授权登录接口
function login(params) { function login(params) {
http('/auth/wechat/login', 'post', params)
http('/auth/phone/login', 'post', params)
} }
// 获取手机号接口 // 获取手机号接口

Loading…
Cancel
Save