306 lines
5.9 KiB
Vue
306 lines
5.9 KiB
Vue
<template>
|
||
<view class="change-password-container">
|
||
<view class="password-content">
|
||
<!-- 标题 -->
|
||
<view class="page-header">
|
||
<text class="header-title">修改密码</text>
|
||
<text class="header-subtitle">为了您的账号安全,请定期修改密码</text>
|
||
</view>
|
||
|
||
<!-- 表单 -->
|
||
<view class="form-section">
|
||
<!-- 旧密码 -->
|
||
<view class="form-item">
|
||
<view class="item-label">
|
||
<text class="label-icon">🔐</text>
|
||
<text class="label-text">旧密码</text>
|
||
</view>
|
||
<input
|
||
class="item-input"
|
||
type="password"
|
||
v-model="oldPassword"
|
||
placeholder="请输入旧密码"
|
||
placeholder-class="input-placeholder"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 新密码 -->
|
||
<view class="form-item">
|
||
<view class="item-label">
|
||
<text class="label-icon">🔑</text>
|
||
<text class="label-text">新密码</text>
|
||
</view>
|
||
<input
|
||
class="item-input"
|
||
type="password"
|
||
v-model="newPassword"
|
||
placeholder="请输入新密码(6-20位)"
|
||
placeholder-class="input-placeholder"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 确认密码 -->
|
||
<view class="form-item">
|
||
<view class="item-label">
|
||
<text class="label-icon">✅</text>
|
||
<text class="label-text">确认密码</text>
|
||
</view>
|
||
<input
|
||
class="item-input"
|
||
type="password"
|
||
v-model="confirmPassword"
|
||
placeholder="请再次输入新密码"
|
||
placeholder-class="input-placeholder"
|
||
/>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 提示信息 -->
|
||
<view class="tips-section">
|
||
<view class="tips-title">密码要求:</view>
|
||
<view class="tips-item">• 长度为6-20个字符</view>
|
||
<view class="tips-item">• 建议包含字母、数字和符号</view>
|
||
<view class="tips-item">• 不要使用过于简单的密码</view>
|
||
</view>
|
||
|
||
<!-- 提交按钮 -->
|
||
<view class="button-section">
|
||
<button class="submit-btn" @click="handleSubmit" :disabled="submitting">
|
||
{{ submitting ? '提交中...' : '确认修改' }}
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
oldPassword: '',
|
||
newPassword: '',
|
||
confirmPassword: '',
|
||
submitting: false
|
||
};
|
||
},
|
||
methods: {
|
||
validateForm() {
|
||
if (!this.oldPassword) {
|
||
uni.showToast({
|
||
title: '请输入旧密码',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (!this.newPassword) {
|
||
uni.showToast({
|
||
title: '请输入新密码',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (this.newPassword.length < 6 || this.newPassword.length > 20) {
|
||
uni.showToast({
|
||
title: '密码长度为6-20位',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (this.newPassword !== this.confirmPassword) {
|
||
uni.showToast({
|
||
title: '两次密码输入不一致',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (this.oldPassword === this.newPassword) {
|
||
uni.showToast({
|
||
title: '新密码不能与旧密码相同',
|
||
icon: 'none'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
async handleSubmit() {
|
||
if (!this.validateForm()) {
|
||
return;
|
||
}
|
||
|
||
this.submitting = true;
|
||
|
||
try {
|
||
// TODO: 调用后端API修改密码
|
||
// const res = await this.$http.post('/api/user/change-password', {
|
||
// oldPassword: this.oldPassword,
|
||
// newPassword: this.newPassword
|
||
// });
|
||
|
||
// 模拟API请求
|
||
await new Promise(resolve => setTimeout(resolve, 1500));
|
||
|
||
uni.showToast({
|
||
title: '密码修改成功',
|
||
icon: 'success',
|
||
duration: 2000
|
||
});
|
||
|
||
setTimeout(() => {
|
||
uni.navigateBack();
|
||
}, 2000);
|
||
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: error.message || '修改失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
} finally {
|
||
this.submitting = false;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.change-password-container {
|
||
min-height: 100vh;
|
||
background: linear-gradient(135deg, #FDF8F2 0%, #F5EDE0 100%);
|
||
}
|
||
|
||
.password-content {
|
||
padding: 40upx 30upx;
|
||
}
|
||
|
||
/* 页面标题 */
|
||
.page-header {
|
||
text-align: center;
|
||
margin-bottom: 60upx;
|
||
|
||
.header-title {
|
||
display: block;
|
||
font-size: 48upx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
margin-bottom: 20upx;
|
||
}
|
||
|
||
.header-subtitle {
|
||
display: block;
|
||
font-size: 26upx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
/* 表单区域 */
|
||
.form-section {
|
||
background: white;
|
||
border-radius: 30upx;
|
||
padding: 40upx 30upx;
|
||
margin-bottom: 40upx;
|
||
box-shadow: 0 8upx 40upx rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
.form-item {
|
||
margin-bottom: 40upx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.item-label {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 20upx;
|
||
|
||
.label-icon {
|
||
font-size: 32upx;
|
||
margin-right: 10upx;
|
||
}
|
||
|
||
.label-text {
|
||
font-size: 28upx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.item-input {
|
||
width: 100%;
|
||
max-width: 520upx; /* 限制输入框宽度,避免过长 */
|
||
margin: 0 auto;
|
||
padding: 24upx 30upx;
|
||
background: #F8F8F8;
|
||
border-radius: 20upx;
|
||
font-size: 28upx;
|
||
color: #333;
|
||
border: 2upx solid transparent;
|
||
transition: all 0.3s;
|
||
|
||
&:focus {
|
||
background: white;
|
||
border-color: #8B7355;
|
||
}
|
||
}
|
||
|
||
.input-placeholder {
|
||
color: #ccc;
|
||
}
|
||
}
|
||
|
||
/* 提示信息 */
|
||
.tips-section {
|
||
background: linear-gradient(135deg, #FFF9E6 0%, #FFF3D6 100%);
|
||
border-radius: 20upx;
|
||
padding: 30upx;
|
||
margin-bottom: 40upx;
|
||
border-left: 6upx solid #FFB800;
|
||
|
||
.tips-title {
|
||
font-size: 26upx;
|
||
font-weight: 600;
|
||
color: #FF9500;
|
||
margin-bottom: 15upx;
|
||
}
|
||
|
||
.tips-item {
|
||
font-size: 24upx;
|
||
color: #666;
|
||
line-height: 2;
|
||
}
|
||
}
|
||
|
||
/* 按钮区域 */
|
||
.button-section {
|
||
padding: 20upx 0;
|
||
}
|
||
|
||
.submit-btn {
|
||
width: 100%;
|
||
padding: 32upx;
|
||
background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%);
|
||
border-radius: 50upx;
|
||
color: white;
|
||
font-size: 32upx;
|
||
font-weight: 600;
|
||
box-shadow: 0 10upx 40upx rgba(139, 115, 85, 0.3);
|
||
border: none;
|
||
|
||
&:active {
|
||
opacity: 0.8;
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
&[disabled] {
|
||
opacity: 0.6;
|
||
background: #ccc;
|
||
}
|
||
}
|
||
</style>
|