439 lines
9.3 KiB
Plaintext
439 lines
9.3 KiB
Plaintext
<template>
|
||
<view class="profile-edit-container">
|
||
<!-- 顶部导航栏 -->
|
||
<view class="page-header">
|
||
<!-- 左上角:返回上一页按钮(箭头+文字 垂直排列) -->
|
||
<view class="nav-left" @click="goBack">
|
||
<text class="nav-icon">←</text>
|
||
<text class="nav-title">返回</text>
|
||
</view>
|
||
|
||
<!-- 页面标题居中 -->
|
||
<text class="page-title">编辑资料</text>
|
||
|
||
<!-- 右上角:保存按钮 -->
|
||
<view class="save-btn" @click="saveProfile">保存</view>
|
||
</view>
|
||
|
||
<!-- 编辑表单 -->
|
||
<view class="edit-form">
|
||
<!-- 头像上传 -->
|
||
<view class="form-item">
|
||
<text class="item-label">头像</text>
|
||
<view class="avatar-upload" @click="chooseAvatar">
|
||
<image :src="formData.avatar_url || '/static/default-avatar.png'" class="avatar-image" />
|
||
<text class="upload-text">点击更换</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 姓名 -->
|
||
<view class="form-item">
|
||
<text class="item-label">姓名</text>
|
||
<input class="item-input" v-model="formData.real_name" placeholder="请输入姓名" />
|
||
</view>
|
||
|
||
<!-- 身份证号 -->
|
||
<view class="form-item">
|
||
<text class="item-label">身份证号</text>
|
||
<input class="item-input" v-model="formData.id_card" placeholder="请输入身份证号" />
|
||
</view>
|
||
|
||
<!-- 驾驶证号 -->
|
||
<view class="form-item">
|
||
<text class="item-label">驾驶证号</text>
|
||
<input class="item-input" v-model="formData.driver_license" placeholder="请输入驾驶证号" />
|
||
</view>
|
||
|
||
<!-- 车辆类型 -->
|
||
<view class="form-item">
|
||
<text class="item-label">车辆类型</text>
|
||
<picker :value="vehicleTypeIndex" :range="vehicleTypes" @change="onVehicleTypeChange">
|
||
<view class="picker-view">{{ formData.vehicle_type ? vehicleTypes[vehicleTypeIndex] : '请选择车辆类型' }}</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 车牌号 -->
|
||
<view class="form-item">
|
||
<text class="item-label">车牌号</text>
|
||
<input class="item-input" v-model="formData.vehicle_number" placeholder="请输入车牌号" />
|
||
</view>
|
||
|
||
<!-- 服务区域 -->
|
||
<view class="form-item">
|
||
<text class="item-label">服务区域</text>
|
||
<view class="service-areas">
|
||
<view class="area-tag" v-for="(area, index) in formData.service_areas" :key="index">
|
||
<text class="area-text">{{ area }}</text>
|
||
<text class="remove-area" @click="removeArea(index)">×</text>
|
||
</view>
|
||
<view class="add-area" @click="showAddAreaModal">
|
||
<text class="add-icon">+</text>
|
||
<text class="add-text">添加区域</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 联系电话(可选) -->
|
||
<view class="form-item">
|
||
<text class="item-label">联系电话</text>
|
||
<input class="item-input" v-model="formData.phone" placeholder="请输入联系电话" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 添加服务区域弹窗 -->
|
||
<view v-if="showAreaModal" class="modal-overlay" @click="hideAddAreaModal">
|
||
<view class="modal-content" @click.stop="noop">
|
||
<text class="modal-title">添加服务区域</text>
|
||
<input class="modal-input" v-model="newAreaName" placeholder="输入区域名称" />
|
||
<view class="modal-actions">
|
||
<button class="modal-btn cancel" @click="hideAddAreaModal">取消</button>
|
||
<button class="modal-btn confirm" @click="addNewArea">确定</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import { ref, reactive, onMounted } from 'vue'
|
||
|
||
// 响应式数据
|
||
const formData = reactive({
|
||
id: '',
|
||
user_id: '',
|
||
real_name: '李师傅',
|
||
id_card: '110101199001011234',
|
||
driver_license: 'C1',
|
||
vehicle_type: 1,
|
||
vehicle_number: '京A12345',
|
||
phone: '13888888888',
|
||
service_areas: ['朝阳区', '东城区'],
|
||
avatar_url: ''
|
||
})
|
||
|
||
const vehicleTypeIndex = ref(0)
|
||
const showAreaModal = ref(false)
|
||
const newAreaName = ref('')
|
||
const vehicleTypes = ref(['摩托车', '电动自行车', '面包车', '小型货车'])
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
loadProfileData()
|
||
})
|
||
|
||
// 方法
|
||
function loadProfileData() {
|
||
// 模拟加载当前用户资料
|
||
// 实际项目中应从 API 获取
|
||
}
|
||
|
||
function chooseAvatar() {
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sizeType: ['compressed'],
|
||
sourceType: ['album', 'camera'],
|
||
success: (res) => {
|
||
formData.avatar_url = res.tempFilePaths[0]
|
||
}
|
||
})
|
||
}
|
||
|
||
function onVehicleTypeChange(e: UniEvent<HTMLInputElement>) {
|
||
const index = parseInt(e.detail.value)
|
||
vehicleTypeIndex.value = index
|
||
formData.vehicle_type = index + 1 // 假设后端从1开始
|
||
}
|
||
|
||
function showAddAreaModal() {
|
||
newAreaName.value = ''
|
||
showAreaModal.value = true
|
||
}
|
||
|
||
function hideAddAreaModal() {
|
||
showAreaModal.value = false
|
||
}
|
||
|
||
function addNewArea() {
|
||
if (newAreaName.value.trim()) {
|
||
if (!formData.service_areas.includes(newAreaName.value.trim())) {
|
||
formData.service_areas.push(newAreaName.value.trim())
|
||
}
|
||
newAreaName.value = ''
|
||
}
|
||
hideAddAreaModal()
|
||
}
|
||
|
||
function removeArea(index: number) {
|
||
formData.service_areas.splice(index, 1)
|
||
}
|
||
|
||
function saveProfile() {
|
||
// 模拟保存
|
||
uni.showLoading({
|
||
title: '保存中...'
|
||
})
|
||
|
||
setTimeout(() => {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: '保存成功',
|
||
icon: 'success'
|
||
})
|
||
// 保存成功后返回上一页
|
||
uni.navigateBack()
|
||
}, 1000)
|
||
|
||
// 实际项目中应调用 API 保存数据
|
||
console.log('保存的资料:', formData)
|
||
}
|
||
|
||
function goBack() {
|
||
uni.navigateBack()
|
||
}
|
||
|
||
function noop() {
|
||
// 阻止事件冒泡的空函数
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.profile-edit-container {
|
||
background-color: #f5f5f5;
|
||
min-height: 100vh;
|
||
padding: 20rpx 30rpx;
|
||
}
|
||
|
||
/* 导航栏样式 */
|
||
.page-header {
|
||
background-color: #fff;
|
||
padding: 20rpx 30rpx;
|
||
border-bottom: 1rpx solid #e9ecef;
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||
position: relative;
|
||
min-height: 80rpx;
|
||
}
|
||
|
||
.nav-left {
|
||
position: absolute;
|
||
top: 20rpx;
|
||
left: 30rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
padding: 10rpx;
|
||
border-radius: 8rpx;
|
||
transition: background-color 0.2s ease;
|
||
}
|
||
|
||
.nav-left:hover {
|
||
background-color: #f0f0f0;
|
||
}
|
||
|
||
.nav-left:active {
|
||
background-color: #e0e0e0;
|
||
}
|
||
|
||
.nav-icon {
|
||
font-size: 36rpx;
|
||
color: #333;
|
||
margin-bottom: 5rpx;
|
||
}
|
||
|
||
.nav-title {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
text-align: center;
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
text-align: center;
|
||
margin-top: 20rpx; /* 与 nav-left 保持一定距离 */
|
||
}
|
||
|
||
.save-btn {
|
||
position: absolute;
|
||
top: 20rpx;
|
||
right: 30rpx;
|
||
font-size: 28rpx;
|
||
color: #4CAF50;
|
||
font-weight: bold;
|
||
padding: 10rpx 20rpx;
|
||
background-color: #e8f5e8;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
/* 编辑表单 */
|
||
.edit-form {
|
||
margin-top: 20rpx;
|
||
}
|
||
|
||
.form-item {
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 20rpx 30rpx;
|
||
margin-bottom: 20rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.item-label {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
min-width: 120rpx;
|
||
}
|
||
|
||
.item-input {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
padding: 10rpx 0;
|
||
border: none;
|
||
outline: none;
|
||
text-align: right;
|
||
}
|
||
|
||
.picker-view {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
text-align: right;
|
||
padding: 10rpx 0;
|
||
}
|
||
|
||
/* 头像上传 */
|
||
.avatar-upload {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.avatar-image {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 60rpx;
|
||
border: 4rpx solid #ddd;
|
||
}
|
||
|
||
.upload-text {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
margin-top: 10rpx;
|
||
}
|
||
|
||
/* 服务区域 */
|
||
.service-areas {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 10rpx;
|
||
align-items: center;
|
||
}
|
||
|
||
.area-tag {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #e8f4fd;
|
||
padding: 8rpx 16rpx;
|
||
border-radius: 20rpx;
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.remove-area {
|
||
margin-left: 8rpx;
|
||
font-size: 20rpx;
|
||
color: #ff4757;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.add-area {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #f0f0f0;
|
||
padding: 8rpx 16rpx;
|
||
border-radius: 20rpx;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.add-icon {
|
||
margin-right: 5rpx;
|
||
font-size: 20rpx;
|
||
}
|
||
|
||
/* 弹窗样式 */
|
||
.modal-overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 1000;
|
||
}
|
||
|
||
.modal-content {
|
||
background-color: #fff;
|
||
width: 80%;
|
||
max-width: 600rpx;
|
||
border-radius: 16rpx;
|
||
padding: 30rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.modal-title {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.modal-input {
|
||
width: 100%;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
padding: 10rpx 20rpx;
|
||
border: 1rpx solid #ddd;
|
||
border-radius: 8rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.modal-actions {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
width: 100%;
|
||
}
|
||
|
||
.modal-btn {
|
||
flex: 1;
|
||
height: 80rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 28rpx;
|
||
font-weight: bold;
|
||
margin: 0 10rpx;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.cancel {
|
||
background-color: #f0f0f0;
|
||
color: #333;
|
||
}
|
||
|
||
.confirm {
|
||
background-color: #4CAF50;
|
||
color: #fff;
|
||
}
|
||
</style> |