9.8 17:44

This commit is contained in:
zoujiandong
2025-09-08 17:44:31 +08:00
parent 1556ea2ec7
commit d827caed33
11 changed files with 2779 additions and 195 deletions
+194 -41
View File
@@ -26,9 +26,12 @@
</view>
<!-- 姓名 -->
<view class="row">
<view class="row" @click="onEdit('name',form.realName)">
<view class="label"><text>姓名</text><text class="req">*</text></view>
<view class="value">{{ form.realName }}</view>
<view class="value with-arrow">
<text>{{ form.realName }}</text>
<uni-icons type="right" size="18" color="#bbb" />
</view>
</view>
<!-- 性别 -->
@@ -59,7 +62,7 @@
</view>
<!-- 邮箱 -->
<view class="row" @click="onEditEmail">
<view class="row" @click="onEdit('email',form.email)">
<view class="label"><text>邮箱</text></view>
<view class="value with-arrow">
<text>{{ form.email || '' }}</text>
@@ -90,7 +93,7 @@
</view>
<!-- 科室电话 -->
<view class="row" @click="onEditDeptPhone">
<view class="row" @click="onEdit('officePhone',form.officePhone)">
<view class="label"><text>科室电话</text><text class="req">*</text></view>
<view class="value with-arrow">
<text>{{ form.officePhone }}</text>
@@ -108,7 +111,7 @@
</view>
<!-- 执业医师证编号 -->
<view class="row" @click="onEditLicenseNo">
<view class="row" @click="onEdit('certificate',form.certificate)">
<view class="label"><text>执业医师证编号</text><text class="req">*</text></view>
<view class="value with-arrow">
<text>{{ form.certificate }}</text>
@@ -135,7 +138,7 @@
</view>
<!-- 个人简介 -->
<view class="row" @click="onEditIntro">
<view class="row" @click="onEdit('intro',form.intro)">
<view class="label"><text>个人简介</text></view>
<view class="value with-arrow">
<text>{{ form.intro || '暂无简介' }}</text>
@@ -197,7 +200,7 @@
</view>
<picker-view class="picker-view" :indicator-style="indicatorStyle" :value="deptPickerIndex" @change="onDeptChange">
<picker-view-column>
<view v-for="(dept, index) in deptList" :key="index" class="picker-item">{{ dept }}</view>
<view v-for="(office, index) in officeList" :key="index" class="picker-item">{{ office.name }}</view>
</picker-view-column>
</picker-view>
</view>
@@ -212,19 +215,57 @@
</view>
<picker-view class="picker-view" :indicator-style="indicatorStyle" :value="titlePickerIndex" @change="onTitleChange">
<picker-view-column>
<view v-for="(title, index) in titleList" :key="index" class="picker-item">{{ title }}</view>
<view v-for="(title, index) in titleList" :key="index" class="picker-item">{{ title.name }}</view>
</picker-view-column>
</picker-view>
</view>
</view>
<!-- 专长多选弹窗 -->
<view v-if="showSpecialtyPicker" class="picker-mask" @click="closeSpecialtyPicker"></view>
<view v-if="showSpecialtyPicker" class="picker-panel specialties" @click.stop>
<view class="picker-header">
<text class="picker-btn" @click="closeSpecialtyPicker">取消</text>
<text class="picker-title">请选择专长</text>
<text class="picker-btn ok" @click="confirmSpecialties">确定</text>
</view>
<view class="specialty-grid">
<view
v-for="(item,idx) in specialtyOptions"
:key="idx"
class="specialty-item"
:class="{ selected: isSpecialtySelected(item), disabled: isMaxSelected && !isSpecialtySelected(item) }"
@click.stop="toggleSpecialty(item)"
>
<text>{{ item }}</text>
</view>
</view>
<view class="tips">最多可选择10项({{ selectedSpecialties.length }}/10)</view>
</view>
<qf-image-cropper v-if="showCropper" :src="cropperSrc" :width="400" :height="400" :radius="30" @crop="handleCrop"></qf-image-cropper>
<!-- 性别选择器 -->
<view v-if="showGenderPicker" class="picker-mask" @click="closeGenderPicker"></view>
<view v-if="showGenderPicker" class="picker-panel" @click.stop>
<view class="picker-header">
<text class="picker-btn" @click="closeGenderPicker">取消</text>
<text class="picker-title">选择性别</text>
<text class="picker-btn ok" @click="confirmGender">确定</text>
</view>
<picker-view class="picker-view" :indicator-style="indicatorStyle" :value="genderPickerIndex" @change="onGenderChange">
<picker-view-column>
<view v-for="(g, gi) in genderList" :key="gi" class="picker-item">{{ g }}</view>
</picker-view-column>
</picker-view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import { ref,computed } from 'vue';
import { onShow,onLoad,onUnload} from "@dcloudio/uni-app";
import api from '@/api/api';
import areaList from '@/utils/areaList.js';
import docUrl from '@/utils/docUrl';
import navTo from '@/utils/navTo';
import QfImageCropper from '@/components/qf-image-cropper/qf-image-cropper.vue';
const form = ref({
// 基本资料字段
photo: '',
@@ -264,9 +305,31 @@
const months = ref([]);
const days = ref([]);
const datePickerIndex = ref([0, 0, 0]);
const cropperSrc = ref('');
const showCropper = ref(false);
// 科室选择相关变量
const showDeptPicker = ref(false);
// 性别选择
const showGenderPicker = ref(false)
const genderList = ref(['男', '女'])
const genderPickerIndex = ref([0])
const onPickGender = () => {
// 打开时根据当前值预选
const idx = genderList.value.findIndex(g => g === getGenderText(form.value.sex))
genderPickerIndex.value = [idx >= 0 ? idx : 0]
showGenderPicker.value = true
}
const closeGenderPicker = () => { showGenderPicker.value = false }
const onGenderChange = (e) => { genderPickerIndex.value = e.detail.value }
const confirmGender = () => {
const idx = genderPickerIndex.value[0] || 0
const g = genderList.value[idx]
// 写回 form.sex(0男/1女 或根据你项目定义)
form.value.sex = g === '男' ? 0 : 1
showGenderPicker.value = false
}
const deptList = ref([
'内科', '外科', '妇产科', '儿科', '眼科', '耳鼻喉科', '口腔科', '皮肤科',
'神经科', '精神科', '肿瘤科', '康复科', '急诊科', '麻醉科', '病理科',
@@ -275,49 +338,67 @@
'手术室', '门诊部', '住院部', '体检中心', '其他'
]);
const deptPickerIndex = ref([0]);
const onEdit = (name,value) => {
navTo({
url: `/pages_app/writeInfo/writeInfo?editType=${name}&value=${value}`
});
};
// 职称选择相关变量
const showTitlePicker = ref(false);
const titleList = ref([
'住院医师', '主治医师', '副主任医师', '主任医师',
'住院中医师', '主治中医师', '副主任中医师', '主任中医师',
'住院药师', '主管药师', '副主任药师', '主任药师',
'住院护师', '主管护师', '副主任护师', '主任护师',
'住院技师', '主管技师', '副主任技师', '主任技师',
'助理医师', '执业医师', '执业助理医师',
'医士', '医师', '主管医师', '副主任医师', '主任医师',
'护士', '护师', '主管护师', '副主任护师', '主任护师',
'技师', '主管技师', '副主任技师', '主任技师',
'其他'
]);
const titleList = ref([]);
const diseaseList = ref([]);
const officeList = ref([]);
const titlePickerIndex = ref([0]);
// 专长多选
const showSpecialtyPicker = ref(false)
const specialtyOptions = ref([
'肝炎','药物肝病','中西医结合','肝硬化','肝衰竭','乙型肝炎','肝癌介入','寄生虫病',
'产科肝病','胆结石','小儿肝病','肝癌外科','胆囊炎','免疫肝病','脂肪肝病','胆囊息肉',
'酒精肝病','肝癌内科','先天肝病','中医肝胆','肝移植','其他'
])
const selectedSpecialties = ref([])
const isMaxSelected = computed(() => selectedSpecialties.value.length >= 10)
const onEditSpecialty = () => {
selectedSpecialties.value = (form.value.specialityList || []).map(i => i.diseaseName || i)
showSpecialtyPicker.value = true
}
const goBack = () => uni.navigateBack();
const closeSpecialtyPicker = () => { showSpecialtyPicker.value = false }
const isSpecialtySelected = (name) => selectedSpecialties.value.includes(name)
const toggleSpecialty = (name) => {
const i = selectedSpecialties.value.indexOf(name)
if (i > -1) { selectedSpecialties.value.splice(i,1); return }
if (isMaxSelected.value) return
selectedSpecialties.value.push(name)
}
const confirmSpecialties = () => {
form.value.specialityList = selectedSpecialties.value.map(n => ({ diseaseName: n }))
showSpecialtyPicker.value = false
}
// 获取性别文本
const getGenderText = (sex) => {
const genderMap = { 0: '女', 1: '男' };
const genderMap = { 0: '男', 1: '女' };
return genderMap[sex] || '';
};
const getDiseaseList = async () => {
const res = await api.getDiseaseList({});
console.log('疾病列表API响应:', res);
if (res.code === 200) {
deptList.value = res.data.diseaseList.map(item => item.diseaseName);
diseaseList.value = res.data;
}
};
const getPositionList = async () => {
const res = await api.getPositionList({});
console.log('职称列表API响应:', res);
if (res.code === 200 ) {
titleList.value = res.data.positionList.map(item => item.positionName);
titleList.value = res.data
}
};
const getOfficeList = async () => {
const res = await api.getOfficeList({});
console.log('科室列表API响应:', res);
if (res.code === 200 ) {
deptList.value = res.data.officeList.map(item => item.officeName);
officeList.value = res.data
}
};
@@ -395,17 +476,40 @@
}
});
};
const cropType = ref('avatar');
const onChooseAvatar = () => {
openCropper((path) => {
form.value.avatar = path;
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album'],
success: (res) => {
cropperSrc.value = res.tempFilePaths[0];
showCropper.value = true;
}
});
};
const handleCrop = (e) => {
console.log(e);
if(cropType.value === 'avatar'){
form.value.photo = e.tempFilePath;
}else{
form.value.certificateImg = e.tempFilePath;
}
showCropper.value = false;
};
const onChooseLicenseImg = () => {
openCropper((path) => {
form.value.licenseImg = path;
}, { destWidth: 1000, rectWidth: 500 });
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album'],
success: (res) => {
cropperSrc.value = res.tempFilePaths[0];
cropType.value = 'license';
showCropper.value = true;
}
});
};
// 地址选择相关函数
@@ -615,7 +719,8 @@
const confirmTitle = () => {
const selectedIndex = titlePickerIndex.value[0];
const selectedTitle = titleList.value[selectedIndex];
console.log(titleList.value[selectedIndex]);
const selectedTitle = titleList.value[selectedIndex].name;
// 更新表单数据
form.value.positionName = selectedTitle;
@@ -623,7 +728,6 @@
closeTitlePicker();
};
const onPickGender = () => {};
const onPickBirthday = () => {
openDatePicker();
};
@@ -637,14 +741,31 @@
openTitlePicker();
};
const onEditLicenseNo = () => {};
const onEditSpecialty = () => {};
const onEditIntro = () => {};
onLoad(() => {
getExpertByUuid();
});
onShow(() => {
// 可在此处拉取并回填个人资料
getExpertByUuid();
uni.$off('writeInfoSaved')
uni.$on('writeInfoSaved', ({ editType, content }) => {
switch (editType) {
case 'email': form.value.email = content; break
case 'name': form.value.realName = content; break
case 'officePhone': form.value.officePhone = content; break
case 'certificate': form.value.certificate = content; break
case 'intro': form.value.intro = content; break
default: break
}
})
getPositionList();
getOfficeList();
//getDiseaseList();
});
onUnload(() => {
uni.$off('writeInfoSaved')
})
</script>
<style lang="scss" scoped>
@@ -778,4 +899,36 @@
text-align: center;
color: #999;
}
/* 专长弹窗 */
.picker-panel.specialties { max-height: 70vh; }
.specialty-grid {
padding: 24rpx;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20rpx;
max-height: calc(70vh - 160rpx);
overflow-y: auto;
}
.specialty-item {
border: 2rpx solid #e0e0e0;
border-radius: 12rpx;
padding: 24rpx 10rpx;
text-align: center;
font-size: 26rpx;
color: #333;
background: #fff;
}
.specialty-item.selected {
border-color: #8B2316;
color: #8B2316;
background: #fff7f5;
}
.specialty-item.disabled {
opacity: .5;
}
.tips {
padding: 16rpx 24rpx;
font-size: 24rpx;
color: #999;
}
</style>