119 lines
3.9 KiB
Vue
119 lines
3.9 KiB
Vue
<template>
|
||
<view class="page">
|
||
<fy-header title="修改密码" back />
|
||
<view class="body">
|
||
<view class="hero">
|
||
<view class="mark">
|
||
<wd-icon name="lock-on" size="44rpx" color="#1677FF" />
|
||
</view>
|
||
<text class="title">设置新密码</text>
|
||
<text class="hint">首次登录或管理员要求改密时,请设置新密码后继续使用。</text>
|
||
</view>
|
||
<view class="card group">
|
||
<view class="field">
|
||
<text class="lab">新密码</text>
|
||
<view class="box">
|
||
<input v-model="next" :password="!showNext" placeholder="至少 6 位" placeholder-class="ph" />
|
||
<text class="eye" @click="showNext = !showNext">{{ showNext ? '隐藏' : '显示' }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="field">
|
||
<text class="lab">确认新密码</text>
|
||
<view class="box" :class="{ bad: mismatch }">
|
||
<input v-model="confirm" :password="!showConfirm" placeholder="再输入一次" placeholder-class="ph" />
|
||
<text class="eye" @click="showConfirm = !showConfirm">{{ showConfirm ? '隐藏' : '显示' }}</text>
|
||
</view>
|
||
<text v-if="mismatch" class="tip">两次输入不一致</text>
|
||
</view>
|
||
</view>
|
||
<wd-button type="primary" block size="large" @click="ok">确认修改</wd-button>
|
||
<text v-if="error" class="err">{{ error }}</text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import FyHeader from '../../components/fy-header.vue'
|
||
import { store } from '../../utils/store.js'
|
||
import { toast } from '../../utils/format.js'
|
||
|
||
export default {
|
||
components: { FyHeader },
|
||
computed: {
|
||
mismatch() {
|
||
return this.confirm.length > 0 && this.next !== this.confirm
|
||
}
|
||
},
|
||
data() {
|
||
return { next: '', confirm: '', error: '', off: null, left: false, waiting: false, showNext: false, showConfirm: false }
|
||
},
|
||
onShow() {
|
||
if (this.off) this.off()
|
||
this.off = store.on(() => {
|
||
this.error = store.error
|
||
if (this.left || !this.waiting || store.phase !== 'app') return
|
||
this.leave()
|
||
})
|
||
},
|
||
onHide() {
|
||
this.drop()
|
||
},
|
||
onUnload() {
|
||
this.drop()
|
||
},
|
||
methods: {
|
||
drop() {
|
||
if (this.off) this.off()
|
||
this.off = null
|
||
},
|
||
leave() {
|
||
this.left = true
|
||
this.waiting = false
|
||
uni.switchTab({ url: '/pages/tabs/messages' })
|
||
},
|
||
async ok() {
|
||
if (!this.next || this.next.length < 6) return toast('密码至少 6 位')
|
||
if (this.next !== this.confirm) return toast('两次密码不一致')
|
||
this.waiting = true
|
||
await store.changePassword(this.next, this.confirm)
|
||
if (store.error) this.waiting = false
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.body { padding: 32rpx 32rpx 48rpx; }
|
||
.hero { display: flex; flex-direction: column; align-items: center; margin: 16rpx 0 36rpx; }
|
||
.mark {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
border-radius: 28rpx;
|
||
background: #E8F1FF;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.title { font-size: 36rpx; font-weight: 650; color: #111827; }
|
||
.hint { margin-top: 10rpx; font-size: 24rpx; color: #6B7280; line-height: 1.55; text-align: center; }
|
||
.group { padding: 8rpx 28rpx 28rpx; margin-bottom: 32rpx; }
|
||
.field { margin-top: 24rpx; }
|
||
.lab { font-size: 26rpx; color: #374151; display: block; margin-bottom: 12rpx; }
|
||
.box {
|
||
height: 96rpx;
|
||
background: #F5F7FA;
|
||
border-radius: 16rpx;
|
||
padding: 0 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
border: 1rpx solid transparent;
|
||
}
|
||
.box.bad { border-color: #FECACA; background: #FEF2F2; }
|
||
.box input { flex: 1; font-size: 30rpx; color: #111827; }
|
||
.ph { color: #9CA3AF; }
|
||
.eye { font-size: 26rpx; color: #1677FF; padding-left: 16rpx; }
|
||
.tip { display: block; margin-top: 10rpx; font-size: 22rpx; color: #DC2626; }
|
||
.err { color: #DC2626; font-size: 26rpx; margin-top: 20rpx; display: block; text-align: center; }
|
||
</style>
|