Files
ss-tiku-manage-h5/src/pages/account/personal.vue
2026-01-30 14:08:23 +08:00

499 lines
11 KiB
Vue

<template>
<view class="personal-account-container">
<!-- 页面标题 -->
<view class="page-header">
<view class="header-left" @click="goBack">
<view class="back-icon"></view>
</view>
<view class="header-title">个人账号管理</view>
<view class="header-right" @click="saveChanges">
<view class="save-btn">保存</view>
</view>
</view>
<!-- 个人信息 -->
<view class="info-section">
<view class="section-title">个人信息</view>
<view class="info-card">
<view class="info-row">
<view class="info-item">
<view class="info-label">姓名</view>
<view class="info-control">
<input
v-model="userInfo.name"
class="info-input"
placeholder="请输入姓名"
maxlength="20"
/>
</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">手机号码</view>
<view class="info-control">
<input
v-model="userInfo.phone"
class="info-input"
placeholder="请输入手机号码"
maxlength="11"
type="number"
/>
</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">邮箱</view>
<view class="info-control">
<input
v-model="userInfo.email"
class="info-input"
placeholder="请输入邮箱"
maxlength="50"
type="email"
/>
</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">性别</view>
<view class="info-control">
<picker
:range="genders"
:value="genderIndex"
@change="onGenderChange"
class="picker"
>
<view class="picker-text">{{ userInfo.gender || '请选择性别' }}</view>
</picker>
</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">所属驾校</view>
<view class="info-control">
<view class="info-text">{{ userInfo.school || '顺达驾校' }}</view>
</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">职位</view>
<view class="info-control">
<input
v-model="userInfo.position"
class="info-input"
placeholder="请输入职位"
maxlength="20"
/>
</view>
</view>
</view>
</view>
</view>
<!-- 账号安全 -->
<view class="security-section">
<view class="section-title">账号安全</view>
<view class="security-card">
<view class="security-item" @click="goToPasswordChange">
<view class="security-label">修改登录密码</view>
<view class="security-arrow"></view>
</view>
<view class="security-item" @click="bindPhone">
<view class="security-label">绑定手机号</view>
<view class="security-status">{{ userInfo.phone ? '已绑定' : '未绑定' }}</view>
<view class="security-arrow"></view>
</view>
<view class="security-item" @click="bindEmail">
<view class="security-label">绑定邮箱</view>
<view class="security-status">{{ userInfo.email ? '已绑定' : '未绑定' }}</view>
<view class="security-arrow"></view>
</view>
</view>
</view>
<!-- 账号信息 -->
<view class="account-info-section">
<view class="section-title">账号信息</view>
<view class="info-card">
<view class="info-row">
<view class="info-item">
<view class="info-label">账号ID</view>
<view class="info-value">{{ userInfo.id || '10001' }}</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">账号类型</view>
<view class="info-value">{{ userInfo.role || '分销员' }}</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">注册时间</view>
<view class="info-value">{{ userInfo.registerTime || '2026-01-15' }}</view>
</view>
</view>
<view class="info-row">
<view class="info-item">
<view class="info-label">最后登录</view>
<view class="info-value">{{ userInfo.lastLogin || '2026-01-29 10:30:00' }}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from "vue"
// 性别选项
const genders = ['男', '女', '保密']
// 用户信息
const userInfo = ref({
id: '10001',
name: '张教练',
phone: '13800138000',
email: 'zhang@shunda.com',
gender: '男',
school: '顺达驾校',
position: '科目二教练',
role: '分销员',
registerTime: '2026-01-15',
lastLogin: '2026-01-29 10:30:00'
})
// 计算性别索引
const genderIndex = computed(() => {
return genders.indexOf(userInfo.value.gender)
})
onMounted(() => {
// 实际项目中应从接口获取用户信息
// loadUserInfo()
})
// 返回上一页
function goBack() {
uni.navigateBack({ delta: 1 })
}
// 保存修改
function saveChanges() {
uni.showModal({
title: '保存修改',
content: '确定要保存个人信息修改吗?',
success: function(res) {
if (res.confirm) {
uni.showLoading({ title: '保存中...' })
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '保存成功',
icon: 'success'
})
// 实际项目中应调用接口保存用户信息
// saveUserInfo()
}, 1500)
}
}
})
}
// 性别变更
function onGenderChange(e) {
const index = e.detail.value
userInfo.value.gender = genders[index]
}
// 跳转到修改密码页面
function goToPasswordChange() {
uni.navigateTo({
url: '/pages/mine/password-change'
})
}
// 绑定手机号
function bindPhone() {
uni.showToast({
title: '绑定手机号功能开发中',
icon: 'none'
})
}
// 绑定邮箱
function bindEmail() {
uni.showToast({
title: '绑定邮箱功能开发中',
icon: 'none'
})
}
</script>
<style lang="scss" scoped>
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #f5f7fa;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
.personal-account-container {
flex: 1;
display: flex;
flex-direction: column;
}
/* 页面头部 */
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 120rpx;
background-color: #fff;
padding: 0 32rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.header-left {
width: 60rpx;
}
.back-icon {
font-size: 40rpx;
color: #303133;
cursor: pointer;
}
.header-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
}
.header-right {
width: 60rpx;
text-align: right;
}
.save-btn {
font-size: 28rpx;
color: #409eff;
font-weight: 600;
cursor: pointer;
}
/* 通用部分样式 */
.info-section,
.security-section,
.account-info-section {
padding: 32rpx;
background-color: #fff;
margin: 0 16rpx 16rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #303133;
margin-bottom: 24rpx;
padding-left: 12rpx;
border-left: 8rpx solid #409eff;
line-height: 1.2;
}
/* 个人信息 */
.info-card {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.info-row {
display: flex;
}
.info-item {
flex: 1;
}
.info-label {
font-size: 24rpx;
color: #606266;
margin-bottom: 8rpx;
}
.info-control {
background-color: #f9f9f9;
border: 1rpx solid #dcdfe6;
border-radius: 8rpx;
padding: 16rpx;
}
.info-input {
font-size: 24rpx;
color: #303133;
width: 100%;
}
.info-text {
font-size: 24rpx;
color: #303133;
}
.info-value {
font-size: 24rpx;
color: #303133;
}
.picker {
display: flex;
justify-content: space-between;
align-items: center;
}
.picker-text {
font-size: 24rpx;
color: #303133;
}
/* 账号安全 */
.security-card {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.security-item {
display: flex;
align-items: center;
padding: 24rpx;
background-color: #f9f9f9;
border-radius: 12rpx;
cursor: pointer;
}
.security-label {
flex: 1;
font-size: 24rpx;
color: #303133;
}
.security-status {
font-size: 20rpx;
color: #67c23a;
margin-right: 16rpx;
}
.security-arrow {
font-size: 24rpx;
color: #909399;
}
/* 平板和大屏响应式 */
@media screen and (min-width: 768px) {
.personal-account-container {
max-width: 900px;
margin: 0 auto;
width: 100%;
}
.info-section,
.security-section,
.account-info-section {
margin: 0 32rpx 24rpx;
padding: 40rpx;
}
.section-title {
font-size: 36rpx;
margin-bottom: 32rpx;
}
.info-row {
flex-direction: row;
gap: 32rpx;
}
.info-item {
flex: 1;
}
.info-label {
font-size: 26rpx;
}
.info-input,
.info-text,
.info-value,
.picker-text {
font-size: 26rpx;
}
.info-control {
padding: 20rpx;
}
.security-item {
padding: 32rpx;
}
.security-label {
font-size: 26rpx;
}
.security-status {
font-size: 22rpx;
}
}
/* 大屏设备响应式 */
@media screen and (min-width: 1024px) {
.personal-account-container {
max-width: 1000px;
}
.info-section,
.security-section,
.account-info-section {
padding: 48rpx;
}
.section-title {
font-size: 40rpx;
}
.info-label {
font-size: 28rpx;
}
.info-input,
.info-text,
.info-value,
.picker-text {
font-size: 28rpx;
}
.security-label {
font-size: 28rpx;
}
}
</style>