Files
oa_app/pages/password/password.vue
T

119 lines
3.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>