380 lines
8.8 KiB
Vue
380 lines
8.8 KiB
Vue
<template>
|
|
<view class="profile-page">
|
|
<!-- 表单区域 -->
|
|
<view class="form-section bg-white">
|
|
<!-- 姓名 -->
|
|
<common-cell name="姓名" :required="true">
|
|
<view class="form-content__wrapper">
|
|
<input
|
|
class="flex-main-content text-right"
|
|
v-model="formData.name"
|
|
placeholder="请输入"
|
|
placeholder-style="color: #999"
|
|
/>
|
|
<uni-icons class="form-arrow" type="arrowright"></uni-icons>
|
|
</view>
|
|
</common-cell>
|
|
<!-- 头像 -->
|
|
<common-cell name="头像">
|
|
<view class="form-content__wrapper" @click="chooseAvatar">
|
|
<view class="flex-main-content flex items-center">
|
|
<image
|
|
v-if="formData.avatar"
|
|
class="avatar-preview"
|
|
:src="formData.avatar"
|
|
mode="aspectFill"
|
|
/>
|
|
<view v-else class="avatar-placeholder">
|
|
<text class="avatar-icon">👤</text>
|
|
</view>
|
|
</view>
|
|
<uni-icons class="form-arrow" type="arrowright"></uni-icons>
|
|
</view>
|
|
</common-cell>
|
|
<!-- 性别 -->
|
|
<form-select
|
|
name="性别"
|
|
:form="formData"
|
|
title="gender"
|
|
:range="genderOptions"
|
|
@change="handleFieldChange"
|
|
/>
|
|
|
|
<!-- 手机号(不可修改) -->
|
|
<common-cell name="手机号 (不可修改)">
|
|
<view class="form-content__wrapper">
|
|
<view class="flex-main-content text-dark">{{ formData.phone }}</view>
|
|
</view>
|
|
</common-cell>
|
|
|
|
<!-- 岗位 -->
|
|
<form-select
|
|
name="岗位"
|
|
:form="formData"
|
|
title="position"
|
|
:range="positionOptions"
|
|
@change="handleFieldChange"
|
|
/>
|
|
|
|
<!-- 职称 -->
|
|
<form-select
|
|
name="职称"
|
|
:form="formData"
|
|
title="title"
|
|
:range="titleOptions"
|
|
@change="handleFieldChange"
|
|
/>
|
|
|
|
<!-- 科室 -->
|
|
<common-cell name="科室" :required="true">
|
|
<view class="form-content__wrapper" @click="openDepartmentSelect">
|
|
<view
|
|
class="flex-main-content text-right"
|
|
:class="{ 'text-placeholder': !formData.departmentName }"
|
|
>
|
|
{{ formData.departmentName || "请选择" }}
|
|
</view>
|
|
<uni-icons class="form-arrow" type="arrowright"></uni-icons>
|
|
</view>
|
|
</common-cell>
|
|
|
|
<!-- 个人介绍 -->
|
|
<form-textarea
|
|
name="个人介绍"
|
|
:form="formData"
|
|
title="intro"
|
|
:word-limit="500"
|
|
@change="handleFieldChange"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 底部按钮 -->
|
|
<view class="button-footer">
|
|
<view class="btn btn-cancel" @click="handleCancel">取消</view>
|
|
<view class="btn btn-save" @click="handleSave">保存</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from "vue";
|
|
import useGuard from "@/hooks/useGuard.js";
|
|
import {
|
|
getDoctorInfoByAccountId,
|
|
updateDoctorInfo,
|
|
} from "@/api/doctor/doctor.js";
|
|
import { uploadFile } from "@/api/file.js";
|
|
import useAccountStore from "@/store/account.js";
|
|
import { storeToRefs } from "pinia";
|
|
import CommonCell from "@/components/form-template/common-cell.vue";
|
|
import FormSelect from "@/components/form-template/form-cell/form-select.vue";
|
|
import FormTextarea from "@/components/form-template/form-cell/form-textarea.vue";
|
|
|
|
const { account, mobile } = storeToRefs(useAccountStore());
|
|
const { useLoad } = useGuard();
|
|
|
|
// 表单数据
|
|
const formData = ref({
|
|
name: "",
|
|
avatar: "",
|
|
gender: "",
|
|
phone: "",
|
|
position: "",
|
|
title: "",
|
|
department: "",
|
|
departmentName: "",
|
|
departmentId: "",
|
|
intro: "",
|
|
});
|
|
|
|
// 选项数据
|
|
const genderOptions = ["男", "女"];
|
|
const positionOptions = ["医生", "护士", "药师", "技师", "其他"];
|
|
const titleOptions = ["主任医师", "副主任医师", "主治医师", "住院医师", "其他"];
|
|
|
|
// 字段变更处理
|
|
const handleFieldChange = (e) => {
|
|
formData.value[e.title] = e.value;
|
|
};
|
|
|
|
// 选择头像
|
|
const chooseAvatar = () => {
|
|
uni.chooseImage({
|
|
count: 1,
|
|
sizeType: ["compressed"],
|
|
sourceType: ["album", "camera"],
|
|
success: async (res) => {
|
|
const tempFilePath = res.tempFilePaths[0];
|
|
uni.showLoading({
|
|
title: "上传中...",
|
|
});
|
|
try {
|
|
const uploadRes = await uploadFile(tempFilePath, "other", "public");
|
|
if (uploadRes && uploadRes.previewUrl) {
|
|
formData.value.avatar = uploadRes.previewUrl;
|
|
uni.hideLoading();
|
|
uni.showToast({
|
|
title: "上传成功",
|
|
icon: "success",
|
|
});
|
|
} else {
|
|
throw new Error("上传失败");
|
|
}
|
|
} catch (error) {
|
|
uni.hideLoading();
|
|
uni.showToast({
|
|
title: "上传失败",
|
|
icon: "none",
|
|
});
|
|
}
|
|
},
|
|
});
|
|
};
|
|
|
|
// 取消
|
|
const handleCancel = () => {
|
|
uni.navigateBack();
|
|
};
|
|
|
|
// 保存
|
|
const handleSave = async () => {
|
|
// 验证必填字段
|
|
if (!formData.value.name) {
|
|
uni.showToast({
|
|
title: "请输入姓名",
|
|
icon: "none",
|
|
});
|
|
return;
|
|
}
|
|
|
|
uni.showLoading({
|
|
title: "保存中...",
|
|
});
|
|
|
|
try {
|
|
// 调用更新接口
|
|
const result = await updateDoctorInfo({
|
|
name: formData.value.name,
|
|
avatar: formData.value.avatar,
|
|
gender: formData.value.gender,
|
|
position: formData.value.position,
|
|
title: formData.value.title,
|
|
departmentId: formData.value.departmentId,
|
|
department: formData.value.departmentName || formData.value.department,
|
|
intro: formData.value.intro,
|
|
});
|
|
|
|
uni.hideLoading();
|
|
|
|
if (result && result.success) {
|
|
uni.showToast({
|
|
title: "保存成功",
|
|
icon: "success",
|
|
});
|
|
setTimeout(() => {
|
|
uni.navigateBack();
|
|
}, 1500);
|
|
} else {
|
|
uni.showToast({
|
|
title: result?.message || "保存失败",
|
|
icon: "none",
|
|
});
|
|
}
|
|
} catch (error) {
|
|
uni.hideLoading();
|
|
uni.showToast({
|
|
title: "保存失败",
|
|
icon: "none",
|
|
});
|
|
console.error("保存失败:", error);
|
|
}
|
|
};
|
|
|
|
// 加载医生信息
|
|
const loadDoctorInfo = async () => {
|
|
if (!account.value?.id) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
uni.showLoading({
|
|
title: "加载中...",
|
|
});
|
|
|
|
const result = await getDoctorInfoByAccountId(account.value.id);
|
|
uni.hideLoading();
|
|
|
|
if (result && result.success && result.data) {
|
|
const doctorInfo = result.data;
|
|
formData.value = {
|
|
name: doctorInfo.name || "",
|
|
avatar: doctorInfo.avatar || "",
|
|
gender: doctorInfo.gender || "",
|
|
phone: doctorInfo.phone || mobile.value || "",
|
|
position: doctorInfo.position || "",
|
|
title: doctorInfo.title || "",
|
|
department: doctorInfo.department || "",
|
|
departmentName: doctorInfo.department || "",
|
|
departmentId: doctorInfo.departmentId || "",
|
|
intro: doctorInfo.intro || "",
|
|
};
|
|
} else {
|
|
// 如果没有医生信息,设置手机号为授权登录的手机号
|
|
if (mobile.value) {
|
|
formData.value.phone = mobile.value;
|
|
}
|
|
}
|
|
} catch (error) {
|
|
uni.hideLoading();
|
|
console.error("加载医生信息失败:", error);
|
|
}
|
|
};
|
|
|
|
useLoad(() => {
|
|
// 初始化时设置手机号为授权登录的手机号
|
|
if (mobile.value && !formData.value.phone) {
|
|
formData.value.phone = mobile.value;
|
|
}
|
|
loadDoctorInfo();
|
|
});
|
|
|
|
// 打开科室选择
|
|
const openDepartmentSelect = () => {
|
|
uni.navigateTo({
|
|
url: "/pages/work/department-select",
|
|
events: {
|
|
deptSelected: ({ name, deptId }) => {
|
|
formData.value.department = name || "";
|
|
formData.value.departmentName = name || "";
|
|
formData.value.departmentId = deptId || "";
|
|
},
|
|
},
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.profile-page {
|
|
min-height: 100vh;
|
|
background: #f5f5f5;
|
|
padding-bottom: 120rpx;
|
|
}
|
|
|
|
.form-section {
|
|
margin-top: 20rpx;
|
|
}
|
|
|
|
.form-content__wrapper {
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
text-align: right;
|
|
font-size: 28rpx;
|
|
|
|
input {
|
|
text-align: right;
|
|
}
|
|
}
|
|
|
|
.text-placeholder {
|
|
color: #999;
|
|
}
|
|
|
|
.avatar-preview {
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
border-radius: 50%;
|
|
background: #e5e5e5;
|
|
}
|
|
|
|
.avatar-placeholder {
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
border-radius: 50%;
|
|
background: #e5e5e5;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.avatar-icon {
|
|
font-size: 48rpx;
|
|
color: #999;
|
|
}
|
|
}
|
|
|
|
.button-footer {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
display: flex;
|
|
padding: 20rpx 30rpx;
|
|
background: #fff;
|
|
border-top: 1px solid #eee;
|
|
gap: 20rpx;
|
|
z-index: 100;
|
|
|
|
.btn {
|
|
flex: 1;
|
|
height: 88rpx;
|
|
line-height: 88rpx;
|
|
text-align: center;
|
|
border-radius: 8rpx;
|
|
font-size: 32rpx;
|
|
}
|
|
|
|
.btn-cancel {
|
|
background: #fff;
|
|
border: 1px solid #007aff;
|
|
color: #007aff;
|
|
}
|
|
|
|
.btn-save {
|
|
background: #007aff;
|
|
color: #fff;
|
|
}
|
|
}
|
|
</style>
|
|
|