1304 lines
30 KiB
Vue
1304 lines
30 KiB
Vue
<template>
|
||
<view class="device-detail">
|
||
<!-- 自定义导航栏 -->
|
||
<view class="tabback">
|
||
<view class="rtjt" @click="btnback">←</view>
|
||
<view class="name">{{ $t('editAccount') }}</view>
|
||
<view style="width: 36rpx;"></view>
|
||
</view>
|
||
|
||
<!-- 主要内容区域 -->
|
||
<view class="content">
|
||
<!-- 头像上传区域 -->
|
||
<view class="avatar-section">
|
||
<view class="avatar-container">
|
||
<view class="avatar-placeholder" v-if="userInfo.avatar" @click="btnimgava">
|
||
<image style="border-radius: 50%;" :src="userInfo.avatar" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="avatar-placeholder" v-else @click="btnimgava">
|
||
<image style="border-radius: 50%;" src="https://api.ccttiot.com/smartmeter/img/static/ugALV02cU3TX6aSoprJ8"
|
||
mode="aspectFill"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 用户信息表单 -->
|
||
<view class="form-section">
|
||
<!-- 用户名 -->
|
||
<view class="form-item">
|
||
<text class="label">{{ $t('username') }}</text>
|
||
<view class="input-container">
|
||
<input class="input-field" :value="userInfo.nickName" disabled />
|
||
<view class="edit-icon" @click="editUsername">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uDKe99jkjV2fPYGODK31"
|
||
mode="aspectFill"></image>️
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 电子邮件 -->
|
||
<view class="form-item">
|
||
<text class="label">{{ $t('email') }}</text>
|
||
<view class="input-container">
|
||
<input class="input-field" :value="userInfo.email" disabled />
|
||
<!-- <view class="edit-icon" @click="editEmail"><image src="https://api.ccttiot.com/smartmeter/img/static/uDKe99jkjV2fPYGODK31" mode="aspectFill"></image>️</view> -->
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 密码 -->
|
||
<!-- <view class="form-item">
|
||
<text class="label">{{ $t('password') }}</text>
|
||
<view class="input-container">
|
||
<input
|
||
class="input-field"
|
||
type="password"
|
||
value="........"
|
||
disabled
|
||
/>
|
||
<view class="edit-icon" @click="editPassword"><image src="https://api.ccttiot.com/smartmeter/img/static/uDKe99jkjV2fPYGODK31" mode="aspectFill"></image>️</view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- 手机号 -->
|
||
<!-- <view class="form-item">
|
||
<text class="label">{{ $t('phoneNumber') }}</text>
|
||
<view class="input-container">
|
||
<input
|
||
class="input-field"
|
||
:value="userInfo.phone"
|
||
disabled
|
||
/>
|
||
<view class="edit-icon" @click="editPhone"><image src="https://api.ccttiot.com/smartmeter/img/static/uDKe99jkjV2fPYGODK31" mode="aspectFill"></image></view>
|
||
</view>
|
||
</view> -->
|
||
|
||
<!-- PIN码 -->
|
||
<view class="form-item">
|
||
<text class="label">{{ $t('pin') }}</text>
|
||
<view class="pin-container">
|
||
<view class="pin-switch-container">
|
||
<text class="pin-switch-desc">{{ enablePin ? $t('pinEnabled') : $t('pinDisabled') }}</text>
|
||
<switch
|
||
:checked="enablePin"
|
||
@change="onPinSwitchChange"
|
||
color="#333"
|
||
class="pin-switch"
|
||
/>
|
||
</view>
|
||
<!-- 修改pin -->
|
||
<!-- <view class="pin-edit-container">
|
||
<input class="pin-display-field" value="••••" disabled />
|
||
<view class="edit-icon" @click="editPin">
|
||
<image src="https://api.ccttiot.com/smartmeter/img/static/uDKe99jkjV2fPYGODK31"
|
||
mode="aspectFill"></image>
|
||
</view>
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 删除账户按钮 -->
|
||
<!-- <view class="delete-section">
|
||
<button class="delete-btn" @click="deleteAccount">{{ $t('deleteAccount') }}</button>
|
||
</view> -->
|
||
|
||
<!-- 自定义底部选择弹窗 -->
|
||
<view class="action-sheet" v-if="showActionSheet" @click="hideActionSheet">
|
||
<view class="action-sheet-content" @click.stop>
|
||
<view class="action-sheet-item" @click="takePhoto">
|
||
<text class="action-sheet-text">{{ $i18n.t('takePhoto') }}</text>
|
||
</view>
|
||
<view class="action-sheet-item" @click="chooseFromAlbum">
|
||
<text class="action-sheet-text">{{ $i18n.t('chooseFromAlbum') }}</text>
|
||
</view>
|
||
<view class="action-sheet-cancel" @click="hideActionSheet">
|
||
<text class="action-sheet-text">{{ $i18n.t('actionSheetCancel') }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- PIN修改弹窗 -->
|
||
<view class="pin-modal" v-if="showPinModal" @click="hidePinModal">
|
||
<view class="pin-modal-content" @click.stop>
|
||
<view class="pin-modal-header">
|
||
<text class="pin-modal-title">{{ $t('editPinTitle') }}</text>
|
||
<view class="pin-modal-close" @click="hidePinModal">×</view>
|
||
</view>
|
||
<view class="pin-modal-body">
|
||
<!-- 旧PIN输入 -->
|
||
<view class="pin-input-group">
|
||
<text class="pin-input-label">{{ $t('oldPin') }}</text>
|
||
<input
|
||
class="pin-input"
|
||
type="password"
|
||
:placeholder="$t('oldPinPlaceholder')"
|
||
v-model="pinForm.oldPin"
|
||
maxlength="4"
|
||
/>
|
||
</view>
|
||
<!-- 新PIN输入 -->
|
||
<view class="pin-input-group">
|
||
<text class="pin-input-label">{{ $t('newPin') }}</text>
|
||
<input
|
||
class="pin-input"
|
||
type="password"
|
||
:placeholder="$t('newPinPlaceholder')"
|
||
v-model="pinForm.newPin"
|
||
maxlength="4"
|
||
/>
|
||
</view>
|
||
<!-- 确认新PIN输入 -->
|
||
<view class="pin-input-group">
|
||
<text class="pin-input-label">{{ $t('confirmNewPin') }}</text>
|
||
<input
|
||
class="pin-input"
|
||
type="password"
|
||
:placeholder="$t('confirmNewPinPlaceholder')"
|
||
v-model="pinForm.confirmNewPin"
|
||
maxlength="4"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="pin-modal-footer">
|
||
<button class="pin-btn pin-btn-cancel" @click="hidePinModal">{{ $t('modalCancel') }}</button>
|
||
<button class="pin-btn pin-btn-confirm" @click="confirmPinChange">{{ $t('modalConfirm') }}</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- PIN验证弹窗 -->
|
||
<view class="pin-modal" v-if="showPinVerifyModal" @click="hidePinVerifyModal">
|
||
<view class="pin-modal-content" @click.stop>
|
||
<view class="pin-modal-header">
|
||
<text class="pin-modal-title">{{ $t('verifyPin') }}</text>
|
||
<view class="pin-modal-close" @click="hidePinVerifyModal">×</view>
|
||
</view>
|
||
<view class="pin-modal-body">
|
||
<view class="pin-verify-tip">
|
||
<text class="pin-verify-tip-text">{{ pendingSwitchAction === 'enable' ? $t('verifyPinToEnable') : $t('verifyPinToDisable') }}</text>
|
||
</view>
|
||
<!-- PIN验证输入 -->
|
||
<view class="pin-input-group">
|
||
<text class="pin-input-label">{{ $t('pin') }}</text>
|
||
<input
|
||
class="pin-input"
|
||
type="password"
|
||
:placeholder="$t('verifyPinPlaceholder')"
|
||
v-model="pinVerifyForm.pin"
|
||
maxlength="4"
|
||
@confirm="confirmPinVerification"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="pin-modal-footer">
|
||
<button class="pin-btn pin-btn-cancel" @click="hidePinVerifyModal">{{ $t('modalCancel') }}</button>
|
||
<button class="pin-btn pin-btn-confirm" @click="confirmPinVerification">{{ $t('modalConfirm') }}</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 用户名编辑弹窗 -->
|
||
<view class="pin-modal" v-if="showUsernameModal" @click="hideUsernameModal">
|
||
<view class="pin-modal-content" @click.stop>
|
||
<view class="pin-modal-header">
|
||
<text class="pin-modal-title">{{ $t('editUsernameTitle') }}</text>
|
||
<view class="pin-modal-close" @click="hideUsernameModal">×</view>
|
||
</view>
|
||
<view class="pin-modal-body">
|
||
<view class="pin-input-group">
|
||
<text class="pin-input-label">{{ $t('username') }}</text>
|
||
<input
|
||
class="pin-input"
|
||
type="text"
|
||
:placeholder="$t('pleaseEnterUsername')"
|
||
v-model="usernameForm.nickName"
|
||
maxlength="20"
|
||
@confirm="confirmUsernameChange"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="pin-modal-footer">
|
||
<button class="pin-btn pin-btn-cancel" @click="hideUsernameModal">{{ $t('modalCancel') }}</button>
|
||
<button class="pin-btn pin-btn-confirm" @click="confirmUsernameChange">{{ $t('modalConfirm') }}</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import i18n from '@/common/i18n/index.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
userInfo: {},
|
||
showActionSheet: false,
|
||
userImgs: 'https://api.ccttiot.com/smartmeter/img/static/uKFO4XdQVUgGYJHt4gwn',
|
||
cropImageSrc: '',
|
||
kjid: '',
|
||
token: '',
|
||
showPinModal: false, // 显示PIN修改弹窗
|
||
pinForm: { // PIN表单数据
|
||
oldPin: '',
|
||
newPin: '',
|
||
confirmNewPin: ''
|
||
},
|
||
enablePin: false,
|
||
showPinVerifyModal: false, // 显示PIN验证弹窗
|
||
pinVerifyForm: { // PIN验证表单数据
|
||
pin: ''
|
||
},
|
||
pendingSwitchAction: null, // 待执行的开关操作
|
||
showUsernameModal: false, // 显示用户名编辑弹窗
|
||
usernameForm: { // 用户名表单数据
|
||
nickName: ''
|
||
}
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.getinfo()
|
||
this.getQiniuToken()
|
||
},
|
||
onShow() {
|
||
// 每次页面显示时重新加载安全设置,确保状态同步
|
||
},
|
||
methods: {
|
||
// 点击上传图片
|
||
btnimgava() {
|
||
this.showActionSheet = true
|
||
},
|
||
// 隐藏弹窗
|
||
hideActionSheet() {
|
||
this.showActionSheet = false
|
||
},
|
||
// 拍照
|
||
takePhoto() {
|
||
this.hideActionSheet()
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sizeType: ['compressed'],
|
||
sourceType: ['camera'],
|
||
success: (imgRes) => {
|
||
this.cropImageSrc = imgRes.tempFilePaths[0]
|
||
let _this = this
|
||
let math = 'static/' + _this.generateGuid(20)
|
||
// 上传裁剪后的图片到七牛云
|
||
uni.uploadFile({
|
||
url: 'https://up-z2.qiniup.com',
|
||
name: 'file',
|
||
filePath: _this.cropImageSrc,
|
||
formData: {
|
||
token: this.token, // 后端返回的token
|
||
key: 'smartmeter/img/' + math
|
||
},
|
||
success: function(res) {
|
||
uni.hideLoading()
|
||
let str = JSON.parse(res.data)
|
||
_this.userImgs = 'https://api.ccttiot.com/' + str.key
|
||
_this.userInfo.avatar = 'https://api.ccttiot.com/' + str.key
|
||
_this.getxiugaiinfo()
|
||
console.log('最终图片路径:', _this.userImgs)
|
||
uni.showToast({
|
||
title: _this.$i18n.t('imageSelectedSuccess'),
|
||
icon: 'success',
|
||
duration: 3000
|
||
})
|
||
|
||
},
|
||
fail: function(err) {
|
||
uni.hideLoading()
|
||
console.error('上传失败:', err)
|
||
uni.showToast({
|
||
title: _this.$i18n.t('uploadFailed'),
|
||
icon: 'none',
|
||
})
|
||
}
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('拍照失败:', err)
|
||
uni.showToast({
|
||
title: this.$i18n.t('imageOperationCancelled'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 从相册选择
|
||
chooseFromAlbum() {
|
||
this.hideActionSheet()
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sizeType: ['compressed'],
|
||
sourceType: ['album'],
|
||
success: (imgRes) => {
|
||
this.cropImageSrc = imgRes.tempFilePaths[0]
|
||
let _this = this
|
||
let math = 'static/' + _this.generateGuid(20)
|
||
// 上传裁剪后的图片到七牛云
|
||
uni.uploadFile({
|
||
url: 'https://up-z2.qiniup.com',
|
||
name: 'file',
|
||
filePath: _this.cropImageSrc,
|
||
formData: {
|
||
token: this.token, // 后端返回的token
|
||
key: 'smartmeter/img/' + math
|
||
},
|
||
success: function(res) {
|
||
uni.hideLoading()
|
||
let str = JSON.parse(res.data)
|
||
_this.userImgs = 'https://api.ccttiot.com/' + str.key
|
||
_this.userInfo.avatar = 'https://api.ccttiot.com/' + str.key
|
||
_this.getxiugaiinfo()
|
||
console.log('最终图片路径:', _this.userImgs)
|
||
uni.showToast({
|
||
title: _this.$i18n.t('imageSelectedSuccess'),
|
||
icon: 'success'
|
||
})
|
||
},
|
||
fail: function(err) {
|
||
uni.hideLoading()
|
||
console.error('上传失败:', err)
|
||
uni.showToast({
|
||
title: _this.$i18n.t('uploadFailed'),
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('选择图片失败:', err)
|
||
uni.showToast({
|
||
title: this.$i18n.t('imageOperationCancelled'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 生成随机字符串(替代$u.guid方法)
|
||
generateGuid(length) {
|
||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||
let result = ''
|
||
for (let i = 0; i < length; i++) {
|
||
result += chars.charAt(Math.floor(Math.random() * chars.length))
|
||
}
|
||
return result
|
||
},
|
||
// 获取上传七牛云token
|
||
getQiniuToken() {
|
||
this.$http.get("/common/qiniuToken").then((res) => {
|
||
if (res.code == 200) {
|
||
this.token = res.data
|
||
}
|
||
})
|
||
},
|
||
|
||
// 上传图片接口
|
||
getxiugaiinfo() {
|
||
let data = {
|
||
avatar: this.userImgs
|
||
}
|
||
this.$http.put(`/system/user/profile`, data).then(resp => {
|
||
if (resp.code == 200) {
|
||
uni.showToast({
|
||
title: resp.msg,
|
||
icon: 'success',
|
||
duration: 3000
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: resp.msg,
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
})
|
||
},
|
||
|
||
// 获取个人信息
|
||
getinfo() {
|
||
this.$http.get('/getInfo').then(res => {
|
||
if (res.code == 200) {
|
||
this.userInfo = res.user
|
||
this.enablePin = res.user.enablePin
|
||
uni.setStorageSync('user', res.user)
|
||
}
|
||
})
|
||
},
|
||
// 多语言翻译方法
|
||
$t(key) {
|
||
return i18n.t(key)
|
||
},
|
||
|
||
// 点击返回上一级
|
||
btnback() {
|
||
uni.navigateBack()
|
||
},
|
||
|
||
// 编辑用户名
|
||
editUsername() {
|
||
// 设置表单数据
|
||
this.usernameForm = {
|
||
nickName: this.userInfo.nickName || ''
|
||
}
|
||
// 显示自定义弹窗
|
||
this.showUsernameModal = true
|
||
},
|
||
|
||
// 隐藏用户名编辑弹窗
|
||
hideUsernameModal() {
|
||
this.showUsernameModal = false
|
||
// 重置表单数据
|
||
this.usernameForm = {
|
||
nickName: ''
|
||
}
|
||
},
|
||
|
||
// 确认用户名修改
|
||
confirmUsernameChange() {
|
||
// 验证用户名是否输入
|
||
if (!this.usernameForm.nickName.trim()) {
|
||
uni.showToast({
|
||
title: this.$t('pleaseEnterUsername'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
// 验证用户名长度
|
||
if (this.usernameForm.nickName.trim().length < 2) {
|
||
uni.showToast({
|
||
title: this.$t('usernameTooShort'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
// 如果用户名没有变化,直接关闭弹窗
|
||
if (this.usernameForm.nickName.trim() === this.userInfo.nickName) {
|
||
this.hideUsernameModal()
|
||
return
|
||
}
|
||
|
||
// 调用API更新用户名
|
||
this.updateUsername()
|
||
},
|
||
|
||
// 更新用户名
|
||
updateUsername() {
|
||
// 显示加载中
|
||
uni.showLoading({
|
||
title: this.$t('updating')
|
||
})
|
||
const data = {
|
||
nickName: this.usernameForm.nickName.trim()
|
||
}
|
||
this.$http.put('/system/user/profile', data).then(resp => {
|
||
uni.hideLoading()
|
||
if (resp.code == 200) {
|
||
// 更新本地用户信息
|
||
this.userInfo.nickName = data.nickName
|
||
uni.setStorageSync('user', this.userInfo)
|
||
uni.showToast({
|
||
title: this.$t('usernameUpdateSuccess'),
|
||
icon: 'success',
|
||
duration: 3000
|
||
})
|
||
// 关闭弹窗
|
||
this.hideUsernameModal()
|
||
} else {
|
||
uni.showToast({
|
||
title: resp.msg || this.$t('usernameUpdateFailed'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
uni.hideLoading()
|
||
console.error('更新用户名失败:', error)
|
||
uni.showToast({
|
||
title: this.$t('usernameUpdateFailed'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
})
|
||
},
|
||
|
||
// 编辑邮箱
|
||
// editEmail() {
|
||
// uni.showModal({
|
||
// title: this.$t('editEmailTitle'),
|
||
// content: this.userInfo.email,
|
||
// editable: true,
|
||
// placeholderText: this.userInfo.email,
|
||
// cancelText: this.$t('modalCancel'),
|
||
// confirmText: this.$t('modalConfirm'),
|
||
// success: (res) => {
|
||
// if (res.confirm && res.content) {
|
||
// this.userInfo.email = res.content
|
||
// uni.showToast({
|
||
// title: this.$t('emailUpdateSuccess'),
|
||
// icon: 'success'
|
||
// })
|
||
// }
|
||
// }
|
||
// })
|
||
// },
|
||
|
||
// 编辑密码
|
||
// editPassword() {
|
||
// uni.showModal({
|
||
// title: this.$t('editPasswordTitle'),
|
||
// content: '',
|
||
// editable: true,
|
||
// placeholderText: this.$t('editPasswordContent'),
|
||
// cancelText: this.$t('modalCancel'),
|
||
// confirmText: this.$t('modalConfirm'),
|
||
// success: (res) => {
|
||
// if (res.confirm && res.content) {
|
||
// // 这里应该调用修改密码的API
|
||
// uni.showToast({
|
||
// title: this.$t('passwordUpdateSuccess'),
|
||
// icon: 'success'
|
||
// })
|
||
// }
|
||
// }
|
||
// })
|
||
// },
|
||
|
||
// 编辑手机号
|
||
// editPhone() {
|
||
// uni.showModal({
|
||
// title: this.$t('editPhoneTitle'),
|
||
// content: this.userInfo.phone,
|
||
// editable: true,
|
||
// placeholderText: this.userInfo.phone,
|
||
// cancelText: this.$t('modalCancel'),
|
||
// confirmText: this.$t('modalConfirm'),
|
||
// success: (res) => {
|
||
// if (res.confirm && res.content) {
|
||
// this.userInfo.phone = res.content
|
||
// uni.showToast({
|
||
// title: this.$t('phoneUpdateSuccess'),
|
||
// icon: 'success'
|
||
// })
|
||
// }
|
||
// }
|
||
// })
|
||
// },
|
||
|
||
// 删除账户
|
||
deleteAccount() {
|
||
uni.showModal({
|
||
title: this.$t('deleteAccountTitle'),
|
||
content: this.$t('deleteAccountContent'),
|
||
confirmColor: '#ff4444',
|
||
cancelText: this.$t('modalCancel'),
|
||
confirmText: this.$t('modalConfirm'),
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 这里应该调用删除账户的API
|
||
uni.showToast({
|
||
title: this.$t('deleteAccountSuccess'),
|
||
icon: 'success'
|
||
})
|
||
// 删除成功后返回登录页面
|
||
setTimeout(() => {
|
||
uni.reLaunch({
|
||
url: '/pages/index/index'
|
||
})
|
||
}, 1500)
|
||
}
|
||
}
|
||
})
|
||
},
|
||
// 编辑PIN码
|
||
editPin() {
|
||
// 重置表单数据
|
||
this.pinForm = {
|
||
oldPin: '',
|
||
newPin: '',
|
||
confirmNewPin: ''
|
||
}
|
||
this.showPinModal = true
|
||
},
|
||
|
||
// 隐藏PIN修改弹窗
|
||
hidePinModal() {
|
||
this.showPinModal = false
|
||
console.log(2222);
|
||
// 重置表单数据
|
||
this.pinForm = {
|
||
oldPin: '',
|
||
newPin: '',
|
||
confirmNewPin: ''
|
||
}
|
||
},
|
||
|
||
// 确认修改PIN
|
||
confirmPinChange() {
|
||
// 验证旧PIN是否输入
|
||
if (!this.pinForm.oldPin) {
|
||
uni.showToast({
|
||
title: this.$t('pleaseEnterOldPin'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 验证新PIN是否输入
|
||
if (!this.pinForm.newPin) {
|
||
uni.showToast({
|
||
title: this.$t('pleaseEnterNewPin'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 验证确认PIN是否输入
|
||
if (!this.pinForm.confirmNewPin) {
|
||
uni.showToast({
|
||
title: this.$t('pleaseConfirmNewPin'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 验证PIN长度
|
||
if (this.pinForm.oldPin.length !== 4 || this.pinForm.newPin.length !== 4 || this.pinForm.confirmNewPin.length !== 4) {
|
||
uni.showToast({
|
||
title: this.$t('pinMustBe4Digits'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 验证新PIN是否一致
|
||
if (this.pinForm.newPin !== this.pinForm.confirmNewPin) {
|
||
uni.showToast({
|
||
title: this.$t('newPinsNotMatch'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 验证新PIN不能与旧PIN相同
|
||
if (this.pinForm.oldPin === this.pinForm.newPin) {
|
||
uni.showToast({
|
||
title: this.$t('newPinCannotBeSame'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 调用修改PIN的API
|
||
this.updatePin()
|
||
},
|
||
|
||
// 调用修改PIN的API
|
||
updatePin() {
|
||
// 显示加载中
|
||
uni.showLoading({
|
||
title: this.$t('updating')
|
||
})
|
||
// 这里需要根据实际API接口进行调用
|
||
// 假设API接口为 /system/user/updatePin
|
||
this.$http.put(`/system/user/profile/updatePin?oldPin=${this.pinForm.oldPin}&newPin=${this.pinForm.newPin}&enablePin=${this.enablePin}`).then(resp => {
|
||
uni.hideLoading()
|
||
if (resp.code == 200) {
|
||
uni.showToast({
|
||
title: this.$t('pinUpdateSuccess'),
|
||
icon: 'success',
|
||
duration: 3000
|
||
})
|
||
this.hidePinModal()
|
||
} else {
|
||
uni.showToast({
|
||
title: resp.msg || this.$t('pinUpdateFailed'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
uni.hideLoading()
|
||
console.error('修改PIN失败:', error)
|
||
uni.showToast({
|
||
title: this.$t('pinUpdateFailed'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
})
|
||
},
|
||
|
||
// PIN开关变化处理
|
||
onPinSwitchChange(e) {
|
||
const enabled = e.detail.value
|
||
this.enablePin = enabled
|
||
console.log('PIN开关变化:', enabled)
|
||
// 记录待执行的操作
|
||
this.pendingSwitchAction = enabled ? 'enable' : 'disable'
|
||
// 重置PIN验证表单
|
||
this.pinVerifyForm = {
|
||
pin: ''
|
||
}
|
||
// 显示PIN验证弹窗
|
||
this.showPinVerifyModal = true
|
||
},
|
||
|
||
// 隐藏PIN验证弹窗
|
||
hidePinVerifyModal() {
|
||
this.showPinVerifyModal = false
|
||
this.enablePin = this.userInfo.enablePin
|
||
// 重置表单数据
|
||
this.pinVerifyForm = {
|
||
pin: ''
|
||
}
|
||
this.pendingSwitchAction = null
|
||
},
|
||
// 确认PIN验证
|
||
confirmPinVerification() {
|
||
// 验证PIN是否输入
|
||
if (!this.pinVerifyForm.pin) {
|
||
uni.showToast({
|
||
title: this.$t('pleaseEnterOldPin'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 验证PIN长度
|
||
if (this.pinVerifyForm.pin.length !== 4) {
|
||
uni.showToast({
|
||
title: this.$t('pinMustBe4Digits'),
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 调用PIN验证API
|
||
this.verifyPin()
|
||
},
|
||
|
||
// 验证PIN码
|
||
verifyPin() {
|
||
// 显示加载中
|
||
uni.showLoading({
|
||
title: this.$t('verifying')
|
||
})
|
||
// 调用PIN验证API
|
||
this.$http.put(`/system/user/profile/updatePin?pin=${this.pinVerifyForm.pin}&enablePin=${this.enablePin}`).then(resp => {
|
||
uni.hideLoading()
|
||
if (resp.code == 200) {
|
||
// PIN验证成功,执行开关操作
|
||
uni.showToast({
|
||
title: this.$t('pinVerificationSuccess'),
|
||
icon: 'success',
|
||
duration: 1500
|
||
})
|
||
|
||
// 关闭验证弹窗
|
||
this.hidePinVerifyModal()
|
||
this.getinfo()
|
||
} else {
|
||
uni.showToast({
|
||
title: resp.msg || this.$t('pinVerificationFailed'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
uni.hideLoading()
|
||
console.error('PIN验证失败:', error)
|
||
uni.showToast({
|
||
title: this.$t('pinVerificationFailed'),
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
})
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
.tabback {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
width: 100%;
|
||
height: 160rpx;
|
||
padding: 0 20rpx;
|
||
padding-top: 80rpx;
|
||
box-sizing: border-box;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 999 !important;
|
||
background-color: #fff;
|
||
|
||
.rtjt {
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
.name {
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.device-detail {
|
||
padding-top: 150rpx;
|
||
min-height: 100vh;
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.content {
|
||
/* padding: 40rpx 30rpx; */
|
||
}
|
||
|
||
// 头像区域
|
||
.avatar-section {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-bottom: 104rpx;
|
||
margin-top: 104rpx;
|
||
|
||
.avatar-container {
|
||
position: relative;
|
||
|
||
.avatar-placeholder {
|
||
width: 250rpx;
|
||
height: 250rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background-color: #f8f8f8;
|
||
|
||
image {
|
||
width: 250rpx;
|
||
height: 250rpx;
|
||
}
|
||
|
||
.avatar-icon {
|
||
font-size: 80rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
.upload-btn {
|
||
position: absolute;
|
||
bottom: 0;
|
||
right: -24rpx;
|
||
width: 110rpx;
|
||
height: 68rpx;
|
||
border-radius: 8rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
image {
|
||
width: 110rpx;
|
||
height: 68rpx;
|
||
}
|
||
|
||
.upload-icon {
|
||
color: #fff;
|
||
font-size: 24rpx;
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.action-sheet {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
z-index: 9999;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
justify-content: center;
|
||
}
|
||
|
||
.action-sheet-content {
|
||
width: 100%;
|
||
background-color: #fff;
|
||
border-radius: 20rpx 20rpx 0 0;
|
||
padding-bottom: 40rpx;
|
||
animation: slideUp 0.3s ease-out;
|
||
}
|
||
|
||
@keyframes slideUp {
|
||
from {
|
||
transform: translateY(100%);
|
||
}
|
||
|
||
to {
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.action-sheet-item {
|
||
padding: 30rpx 40rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
text-align: center;
|
||
}
|
||
|
||
.action-sheet-item:active {
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.action-sheet-cancel {
|
||
padding: 30rpx 40rpx;
|
||
text-align: center;
|
||
margin-top: 20rpx;
|
||
background-color: #f8f8f8;
|
||
}
|
||
|
||
.action-sheet-cancel:active {
|
||
background-color: #e8e8e8;
|
||
}
|
||
|
||
.action-sheet-text {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.action-sheet-cancel .action-sheet-text {
|
||
color: #666;
|
||
}
|
||
|
||
// 表单区域
|
||
.form-section {
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx;
|
||
margin-bottom: 30rpx;
|
||
|
||
.form-item {
|
||
margin-bottom: 40rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.label {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 20rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.input-container {
|
||
display: flex;
|
||
align-items: center;
|
||
border-bottom: 1rpx solid #eee;
|
||
padding-bottom: 20rpx;
|
||
|
||
.input-field {
|
||
flex: 1;
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
|
||
&::placeholder {
|
||
color: #999;
|
||
}
|
||
|
||
&:disabled {
|
||
color: #666;
|
||
}
|
||
}
|
||
|
||
.edit-icon {
|
||
width: 52rpx;
|
||
height: 52rpx;
|
||
|
||
image {
|
||
width: 52rpx;
|
||
height: 52rpx;
|
||
}
|
||
|
||
margin-left: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 安全开关样式
|
||
.switch-container {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
border-bottom: 1rpx solid #eee;
|
||
padding-bottom: 20rpx;
|
||
|
||
.switch-desc {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.security-switch {
|
||
margin-left: 20rpx;
|
||
}
|
||
}
|
||
|
||
.debug-info {
|
||
margin-top: 20rpx;
|
||
padding: 20rpx;
|
||
background-color: #f8f8f8;
|
||
border-radius: 8rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
.debug-text {
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.debug-btn {
|
||
font-size: 24rpx;
|
||
padding: 10rpx 20rpx;
|
||
background-color: #333;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4rpx;
|
||
}
|
||
}
|
||
|
||
// 删除账户按钮
|
||
.delete-section {
|
||
display: flex;
|
||
justify-content: center;
|
||
|
||
.delete-btn {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
background-color: #fff;
|
||
border: none;
|
||
border-radius: 16rpx;
|
||
color: #ff4444;
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
|
||
&:active {
|
||
background-color: #f8f8f8;
|
||
}
|
||
}
|
||
}
|
||
|
||
// PIN容器样式
|
||
.pin-container {
|
||
.pin-switch-container {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
// border-bottom: 1rpx solid #eee;
|
||
// padding-bottom: 20rpx;
|
||
// margin-bottom: 20rpx;
|
||
|
||
.pin-switch-desc {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.pin-switch {
|
||
margin-left: 20rpx;
|
||
}
|
||
}
|
||
|
||
.pin-edit-container {
|
||
display: flex;
|
||
align-items: center;
|
||
border-bottom: 1rpx solid #eee;
|
||
padding-bottom: 20rpx;
|
||
|
||
.pin-display-field {
|
||
flex: 1;
|
||
font-size: 30rpx;
|
||
color: #666;
|
||
|
||
&:disabled {
|
||
color: #666;
|
||
}
|
||
}
|
||
|
||
.edit-icon {
|
||
width: 52rpx;
|
||
height: 52rpx;
|
||
margin-left: 20rpx;
|
||
|
||
image {
|
||
width: 52rpx;
|
||
height: 52rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// PIN修改弹窗样式
|
||
.pin-modal {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
z-index: 9999;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 40rpx;
|
||
|
||
.pin-modal-content {
|
||
width: 100%;
|
||
max-width: 600rpx;
|
||
background-color: #fff;
|
||
border-radius: 20rpx;
|
||
overflow: hidden;
|
||
animation: modalSlideIn 0.3s ease-out;
|
||
|
||
.pin-modal-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 40rpx 40rpx 20rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
|
||
.pin-modal-title {
|
||
font-size: 36rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.pin-modal-close {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 48rpx;
|
||
color: #999;
|
||
cursor: pointer;
|
||
|
||
&:active {
|
||
background-color: #f5f5f5;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
}
|
||
|
||
.pin-modal-body {
|
||
padding: 40rpx;
|
||
|
||
.pin-verify-tip {
|
||
background-color: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
padding: 24rpx;
|
||
margin-bottom: 32rpx;
|
||
border-left: 4rpx solid #333;
|
||
|
||
.pin-verify-tip-text {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
}
|
||
}
|
||
|
||
.pin-input-group {
|
||
margin-bottom: 40rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.pin-input-label {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 20rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.pin-input {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
padding: 0 24rpx;
|
||
border: 2rpx solid #e0e0e0;
|
||
border-radius: 12rpx;
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
background-color: #fff;
|
||
box-sizing: border-box;
|
||
|
||
&:focus {
|
||
border-color: #333;
|
||
outline: none;
|
||
}
|
||
|
||
&::placeholder {
|
||
color: #999;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.pin-modal-footer {
|
||
display: flex;
|
||
padding: 20rpx 40rpx 40rpx;
|
||
gap: 20rpx;
|
||
|
||
.pin-btn {
|
||
flex: 1;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
border: none;
|
||
border-radius: 12rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
|
||
&.pin-btn-cancel {
|
||
background-color: #f5f5f5;
|
||
color: #666;
|
||
|
||
&:active {
|
||
background-color: #e8e8e8;
|
||
}
|
||
}
|
||
|
||
&.pin-btn-confirm {
|
||
background-color: #333;
|
||
color: #fff;
|
||
|
||
&:active {
|
||
background-color: #0056b3;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes modalSlideIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: scale(0.9) translateY(-50rpx);
|
||
}
|
||
|
||
to {
|
||
opacity: 1;
|
||
transform: scale(1) translateY(0);
|
||
}
|
||
}
|
||
</style> |