Files
medical-mall/pages/mall/delivery/profile-edit.uvue
not-like-juvenile b1c845d571 添加新页面
2026-01-23 17:13:39 +08:00

439 lines
9.3 KiB
Plaintext
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="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>