ykt-wxapp/pages/work/profile.vue

291 lines
9.3 KiB
Vue
Raw Normal View History

2026-01-20 16:30:03 +08:00
<template>
2026-01-23 14:36:28 +08:00
<full-page>
<view class="p-15">
<view class="bg-white px-10 mb-10 rounded">
2026-02-04 18:30:18 +08:00
<form-input :form="formData" :required="rule.anotherName.required" wordLimit="10" title="anotherName"
:name="rule.anotherName.name" @change="onChange($event)" />
2026-01-23 14:36:28 +08:00
<common-cell title="avatar" name="头像">
2026-02-04 18:30:18 +08:00
<view class="flex-grow flex items-center justify-end" @click="chooseAvatar()">
<image v-if="formData.avatar" class="avatar mr-5 rounded-full" :src="formData.avatar" />
<image v-else class="avatar mr-5 rounded-full" src="/static/home/avatar.svg" />
2026-01-23 14:36:28 +08:00
<uni-icons color="#999" type="right" size="16" />
2026-01-20 16:30:03 +08:00
</view>
2026-01-23 14:36:28 +08:00
</common-cell>
2026-02-04 18:30:18 +08:00
<form-select :form="formData" name="性别" title="gender" :range="genderOptions" @change="onChange($event)" />
2026-02-10 13:52:54 +08:00
<form-input v-if="account && account.mobile" :form="formData" disableChange wordLimit="11" title="mobile"
name="手机号 (不可修改)" />
<form-input v-else :form="formData" disableChange wordLimit="11" title="mobile" name="手机号 (不可修改)"
placeholder=" " />
2026-01-23 14:36:28 +08:00
</view>
<view class="bg-white px-10 mb-10 rounded">
2026-01-23 18:08:14 +08:00
<!-- 填写认证资料的时候岗位必填 -->
2026-02-04 18:30:18 +08:00
<common-cell :required="type === 'cert'" title="job" :name="rule.job.name">
2026-02-06 17:10:48 +08:00
<picker mode="selector" :disabled="rule.job.disabled" :range="jobOptions" range-key="name"
2026-02-04 18:30:18 +08:00
@change="changeJob($event)">
<view class="flex-grow flex items-center justify-end">
<view v-if="jobStr" class="text-base text-base">{{ jobStr }}</view>
<uni-icons color="#999" type="right" size="16" />
</view>
</picker>
2026-01-23 14:36:28 +08:00
</common-cell>
2026-02-04 18:33:01 +08:00
<common-cell title="title" :name="rule.title.name">
2026-02-06 17:10:48 +08:00
<picker mode="selector" :disabled="rule.title.disabled" :range="titleOptions" @change="changeTitle($event)">
2026-02-04 18:30:18 +08:00
<view class="flex-grow flex items-center justify-end">
2026-02-04 18:33:01 +08:00
<view class="text-base text-base">{{ formData.title }}</view>
2026-02-04 18:30:18 +08:00
<uni-icons color="#999" type="right" size="16" />
</view>
</picker>
2026-01-23 14:36:28 +08:00
</common-cell>
2026-01-26 14:52:33 +08:00
<common-cell title="dept" :name="rule.dept.name">
2026-02-05 17:12:52 +08:00
<view class="flex-grow flex items-center justify-end" @click="selectDept()">
<view class="text-base text-base">{{ deptNames }}</view>
2026-01-23 14:36:28 +08:00
<uni-icons color="#999" type="right" size="16" />
</view>
</common-cell>
</view>
2026-01-20 16:30:03 +08:00
2026-01-23 14:36:28 +08:00
<view class="bg-white rounded">
2026-02-04 18:30:18 +08:00
<form-textarea autoHeight :border="false" :form="formData" title="memberTroduce" name="个人介绍" :wordLimit="300"
@change="onChange($event)" />
2026-01-23 14:36:28 +08:00
</view>
2026-01-20 16:30:03 +08:00
</view>
2026-01-23 14:36:28 +08:00
<template #footer>
2026-02-10 13:52:54 +08:00
<button-footer v-if="account && account.mobile" :cancelText="cancelText" :confirmText="confirmText"
@confirm="save()" @cancel="back()" />
<button-footer v-else :cancelText="cancelText" :confirmText="confirmText" @confirm="save()" @cancel="back()">
<template #confirm>
<view class="relative py-10 text-base border-primary bg-primary text-white rounded">
{{ confirmText }}
<button class="phone-btn absolute w-full h-full" open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"></button>
</view>
</template>
</button-footer>
2026-01-23 14:36:28 +08:00
</template>
</full-page>
2026-01-20 16:30:03 +08:00
</template>
<script setup>
2026-01-23 14:36:28 +08:00
import { computed, ref } from "vue";
import { storeToRefs } from "pinia";
2026-02-04 18:30:18 +08:00
import { titleList } from "@/baseData";
2026-01-20 16:30:03 +08:00
import useGuard from "@/hooks/useGuard.js";
import useAccountStore from "@/store/account.js";
2026-01-23 14:36:28 +08:00
import api from "@/utils/api.js";
import { upload } from "@/utils/http.js";
import { toast } from "@/utils/widget";
2026-02-02 14:12:46 +08:00
import buttonFooter from "@/components/button-footer.vue";
2026-01-23 14:36:28 +08:00
import commonCell from "@/components/form-template/common-cell.vue";
2026-01-21 13:37:54 +08:00
import FormInput from "@/components/form-template/form-cell/form-input.vue";
2026-01-20 16:30:03 +08:00
import FormSelect from "@/components/form-template/form-cell/form-select.vue";
import FormTextarea from "@/components/form-template/form-cell/form-textarea.vue";
2026-02-02 14:12:46 +08:00
import fullPage from "@/components/full-page.vue";
2026-01-23 14:36:28 +08:00
2026-01-21 13:37:54 +08:00
const { account, doctorInfo } = storeToRefs(useAccountStore());
2026-01-23 14:36:28 +08:00
const { useLoad, useShow } = useGuard();
2026-02-10 13:52:54 +08:00
const { getDoctorInfo, login } = useAccountStore();
2026-01-23 14:36:28 +08:00
2026-02-02 14:12:46 +08:00
const job = { assistant: "医生助理", doctor: "医生" };
2026-02-04 18:30:18 +08:00
const jobOptions = [{ name: '医生', value: 'doctor' }, { name: '医生助理', value: 'assistant' }, { name: '无', value: '' }];
2026-02-04 18:33:01 +08:00
const titleOptions = [...titleList, '无'];
2026-01-23 18:08:14 +08:00
2026-01-23 14:36:28 +08:00
const form = ref({});
2026-02-02 14:12:46 +08:00
const inviteTeamId = ref("");
const type = ref("");
2026-01-29 15:35:57 +08:00
2026-02-02 14:12:46 +08:00
const formData = computed(() => ({
...(doctorInfo.value || {}),
...form.value,
mobile: account.value?.mobile,
}));
const cancelText = computed(() => (doctorInfo.value ? "取消" : "暂不填写"));
const confirmText = computed(() => (type.value === "cert" ? "下一步" : "保存"));
2026-01-23 18:08:14 +08:00
const jobStr = computed(() => {
2026-02-02 14:12:46 +08:00
const jobs =
formData.value && Array.isArray(formData.value.job)
? formData.value.job.filter((i) => i === "assistant" || i === "doctor")
: [];
return jobs[0] && job[jobs[0]] ? job[jobs[0]] : "";
});
2026-01-26 14:52:33 +08:00
const rule = computed(() => {
2026-02-06 17:10:48 +08:00
const data = {
2026-02-02 14:12:46 +08:00
anotherName: { name: "姓名", required: true, disabled: false },
job: { name: "岗位", disabled: false },
2026-02-04 18:33:01 +08:00
title: { name: "职称", disabled: false },
2026-02-02 14:12:46 +08:00
dept: { name: "科室", disabled: false },
2026-02-06 17:10:48 +08:00
}
if (doctorInfo.value && ["verified", "verifying"].includes(doctorInfo.value.verifyStatus)) {
data.anotherName.name = "姓名 (不可修改)";
data.anotherName.required = false;
data.anotherName.disabled = true;
data.job.name = "岗位 (不可修改)";
data.job.disabled = true;
2026-02-09 16:16:06 +08:00
// data.title.name = doctorInfo.value.verifyStatus === 'verified' ? "职称 (不可修改)" : "职称";
// data.title.disabled = doctorInfo.value.verifyStatus === 'verified';
2026-02-06 17:10:48 +08:00
2026-02-09 16:16:06 +08:00
// data.dept.name = doctorInfo.value.verifyStatus === 'verified' ? "科室 (不可修改)" : "科室";
// data.dept.disabled = doctorInfo.value.verifyStatus === 'verified';
2026-02-06 17:10:48 +08:00
}
return data
2026-02-02 14:12:46 +08:00
});
2026-02-05 17:12:52 +08:00
const deptNames = computed(() => {
const hlwDepts = formData.value.hlwDepts || [];
return hlwDepts.map(i => i && i.deptName ? i.deptName : '').filter(Boolean).join(',')
})
2026-01-20 16:30:03 +08:00
// 选项数据
2026-01-21 15:27:18 +08:00
const genderOptions = [
{ label: "男", value: "0" },
{ label: "女", value: "1" },
];
2026-01-23 14:36:28 +08:00
function back() {
const pages = getCurrentPages();
if (pages.length > 1) {
uni.navigateBack();
} else {
uni.switchTab({
2026-02-04 18:30:18 +08:00
url: "/pages/home/work-home",
2026-01-23 14:36:28 +08:00
});
2026-01-20 16:30:03 +08:00
}
}
2026-01-23 14:36:28 +08:00
function chooseAvatar() {
uni.chooseImage({
count: 1,
success: async (res) => {
const [path] = res.tempFilePaths;
const url = await upload(path);
if (url) {
form.value.avatar = url;
} else {
2026-02-02 14:12:46 +08:00
toast("上传失败");
2026-01-23 14:36:28 +08:00
}
2026-02-02 14:12:46 +08:00
},
});
2026-01-20 16:30:03 +08:00
}
2026-01-23 14:36:28 +08:00
function onChange({ title, value }) {
2026-02-02 14:12:46 +08:00
form.value[title] = value;
2026-01-20 16:30:03 +08:00
}
2026-02-04 18:30:18 +08:00
function changeJob(e) {
const data = jobOptions[e.detail.value];
2026-02-06 17:10:48 +08:00
form.value.job = [data.value];
2026-02-04 18:30:18 +08:00
}
2026-02-04 18:33:01 +08:00
function changeTitle(e) {
2026-02-04 18:30:18 +08:00
const data = titleList[e.detail.value];
2026-02-04 18:33:01 +08:00
form.value.title = data || '';
2026-01-23 18:08:14 +08:00
}
function toCert() {
2026-02-02 14:12:46 +08:00
if (jobStr.value === "医生") {
2026-01-23 18:08:14 +08:00
uni.navigateTo({
2026-02-02 14:12:46 +08:00
url: "/pages/work/verify/doctor",
});
} else if (jobStr.value === "医生助理") {
2026-01-23 18:08:14 +08:00
uni.navigateTo({
2026-02-02 14:12:46 +08:00
url: "/pages/work/verify/assistant",
});
2026-01-23 18:08:14 +08:00
} else {
2026-02-02 14:12:46 +08:00
toast("请选择岗位信息");
2026-01-23 18:08:14 +08:00
}
}
2026-02-05 17:12:52 +08:00
function selectDept() {
2026-02-10 13:52:54 +08:00
if (rule.value.dept.disabled) return;
2026-02-05 17:12:52 +08:00
const eventName = `selectDept_${Date.now()}`
const deptIds = (formData.value.hlwDepts || []).map(i => i.deptId).filter(Boolean).join(',')
uni.navigateTo({
url: `/pages/work/department-select?eventName=${eventName}&deptIds=${deptIds}`
})
uni.$once(eventName, data => {
form.value.hlwDepts = data
})
}
2026-02-10 13:52:54 +08:00
async function getPhoneNumber(e) {
const phoneCode = e && e.detail && e.detail.code;
if (e && !phoneCode) return;
try {
const res = await login(phoneCode);
if (!res || !res.mobile) {
return toast('绑定手机号失败')
}
save()
} catch (e) {
toast('绑定手机号失败')
}
}
2026-01-23 14:36:28 +08:00
async function save() {
2026-02-02 14:12:46 +08:00
if (
typeof formData.value.anotherName !== "string" ||
!formData.value.anotherName.trim()
) {
return toast("请输入姓名");
2026-01-23 14:36:28 +08:00
}
2026-02-02 14:12:46 +08:00
if (type.value === "cert" && !jobStr.value) {
return toast("请选择岗位信息");
2026-01-23 14:36:28 +08:00
}
2026-02-02 14:12:46 +08:00
const apiName = doctorInfo.value
? "updateCorpMemberFromWxapp"
: "addCorpMemberFromWxapp";
2026-01-23 14:36:28 +08:00
const data = {
...form.value,
weChatOpenId: account.value.openid,
mobile: account.value.mobile,
corpId: account.value.corpId,
2026-02-02 14:12:46 +08:00
};
2026-01-23 18:08:14 +08:00
if (doctorInfo.value) {
data.id = doctorInfo.value._id;
}
2026-01-29 15:35:57 +08:00
if (inviteTeamId.value) {
data.inviteTeamId = inviteTeamId.value;
}
2026-01-23 14:36:28 +08:00
const res = await api(apiName, data);
if (res && res.success) {
2026-02-05 17:12:52 +08:00
await getDoctorInfo({ withHlwDeptInfo: true });
2026-01-23 18:08:14 +08:00
form.value = {};
2026-02-02 14:12:46 +08:00
if (type.value === "cert") {
toCert();
2026-01-23 18:08:14 +08:00
} else {
2026-02-02 14:12:46 +08:00
await toast("保存成功");
back();
2026-01-23 18:08:14 +08:00
}
2026-01-23 14:36:28 +08:00
} else {
2026-02-02 14:12:46 +08:00
await toast(res?.message || "保存失败");
2026-01-20 16:30:03 +08:00
}
}
2026-02-02 14:12:46 +08:00
useLoad((opts) => {
2026-01-23 14:36:28 +08:00
type.value = opts?.type;
2026-02-02 14:12:46 +08:00
if (type.value === "joinTeam" && opts.teamId) {
inviteTeamId.value = opts.teamId;
2026-01-29 15:35:57 +08:00
}
2026-02-02 14:12:46 +08:00
});
2026-01-20 16:30:03 +08:00
2026-01-23 14:36:28 +08:00
useShow(() => {
2026-02-05 17:12:52 +08:00
getDoctorInfo({ withHlwDeptInfo: true });
2026-01-23 14:36:28 +08:00
});
</script>
2026-01-20 16:30:03 +08:00
2026-01-23 14:36:28 +08:00
<style lang="scss" scoped>
.avatar {
width: 64rpx;
height: 64rpx;
2026-01-20 16:30:03 +08:00
}
2026-02-10 13:52:54 +08:00
.phone-btn {
left: 0;
top: 0;
opacity: 0;
}
2026-01-20 16:30:03 +08:00
</style>