ykt-wxapp/pages/message/components/description-popup.vue

417 lines
8.6 KiB
Vue
Raw Normal View History

2026-01-20 13:21:50 +08:00
<template>
<uni-popup ref="symptomPopup" type="bottom" :mask-click="false">
<view class="symptom-popup">
<view class="popup-header">
<text class="popup-title">请描述您的病情</text>
</view>
<view class="popup-content">
<textarea class="symptom-textarea" v-model="symptomDescription" placeholder="请描述您的病情..." :maxlength="200"
show-confirm-bar="false"></textarea>
<view class="section">
<view class="checkbox-row">
<text class="section-title">是否到线下医院就诊过</text>
<uni-data-checkbox class="checkbox-group" mode="tag" v-model="hasVisitedHospital" :localdata="yesNoOptions"
:multiple="false"></uni-data-checkbox>
</view>
</view>
<!-- 诊断选择 - 只有选择"是"才显示 -->
<view class="section" v-if="hasVisitedHospital === 'yes'">
<text class="section-title">诊断*</text>
<view class="diagnosis-container">
<!-- 已选择的疾病标签 -->
<view class="selected-diseases" v-if="selectedDiseases.length > 0">
<view v-for="(disease, index) in selectedDiseases" :key="`${index}-common`" class="tag-item tag-item-active"
@click="removeDiseaseTag(index)">
{{ disease }}
</view>
<!-- <uni-tag v-for="(disease, index) in selectedDiseases" :key="index" :text="disease" type="primary"
size="small" :circle="true" @click="removeDiseaseTag(index)"></uni-tag> -->
</view>
<!-- 添加疾病按钮 -->
<view class="add-disease-btn" @click="goToSelectDisease">
<view class="tag-item">+ 添加</view>
</view>
</view>
</view>
<view class="section">
<view class="upload-header">
<text class="section-title">上传资料</text>
<text class="upload-subtitle">病历处方检查检验报告等图片</text>
</view>
<view class="upload-actions">
<view class="upload-btn" @click="add()">
<uni-icons type="camera" size="24" color="#666"></uni-icons>
<text class="upload-text">添加照片</text>
</view>
</view>
<!-- 已选择的图片预览 -->
<view class="image-preview" v-if="images.length > 0">
<view v-for="(image, index) in images" :key="image" class="preview-item">
<image :src="image" class="preview-image" mode="aspectFill"></image>
<view class="remove-btn" @click="remove(index)">
<uni-icons type="close" size="16" color="white"></uni-icons>
</view>
</view>
</view>
</view>
</view>
<view class="popup-footer">
<button class="popup-btn cancel-btn" @click="closeSymptomPopup">取消</button>
<button class="popup-btn submit-btn" @click="submitSymptomDescription">提交</button>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref, watch } from 'vue'
import { submitOrderDescription } from '@/api/consult-order';
import { registerOnceEvent } from '@/hooks/useOnceEvent'
import useImageUpload from '@/hooks/useImageUpload'
import { set } from '@/utils/cache'
import { toast } from '@/utils/widget'
const emits = defineEmits(['close', 'submit'])
// 定义组件的props
const props = defineProps({
visible: {
type: Boolean,
default: false
},
orderId: {
type: String,
default: ''
},
accountId: {
type: String,
default: ''
},
isIMMode: {
type: Boolean,
default: false
}
})
// 定义组件的emit事件
// 响应式数据
const symptomPopup = ref(null)
const symptomDescription = ref('')
const loading = ref(false)
const { images, add, remove, uploadImages } = useImageUpload('order')
// 是否到线下医院就诊过
const hasVisitedHospital = ref('')
const yesNoOptions = ref([
{ value: 'yes', text: '是' },
{ value: 'no', text: '否' }
])
// 诊断选择
const selectedDiseases = ref([])
// 关闭病情描述弹窗
const closeSymptomPopup = () => {
emits('close')
}
// 跳转到疾病选择页面
const goToSelectDisease = () => {
const eventName = registerOnceEvent(changeDisease)
set('diseaseSelected', selectedDiseases.value)
// 将当前已选择的疾病数据传递到选择页面
uni.navigateTo({
url: `/pages-home/consultation/disease?eventName=${eventName}`
})
}
// 删除疾病标签
const removeDiseaseTag = (index) => {
selectedDiseases.value.splice(index, 1)
}
// 提交病情描述
const submitSymptomDescription = async () => {
if (loading.value) return;
loading.value = true;
if (!symptomDescription.value.trim() && images.value.length === 0) {
toast('请输入病情描述或上传图片')
loading.value = false;
return
}
if (images.value.length) {
const res = await uploadImages()
if (!res) {
loading.value = false;
return;
}
}
// 构造要提交的数据
const descriptionData = {
description: symptomDescription.value.trim(),
hasVisitedHospital: hasVisitedHospital.value === 'yes',
diseases: selectedDiseases.value,
images: images.value
}
const res = await submitOrderDescription({
accountId: props.accountId,
orderId: props.orderId,
...descriptionData
})
if (res && res.success) {
toast(res.message);
closeSymptomPopup()
emits('submit', res.data)
}
loading.value = false
}
function changeDisease(diseases) {
selectedDiseases.value = diseases
}
watch(() => props.visible, (n) => {
if (n) {
symptomPopup.value && symptomPopup.value.open()
} else {
symptomPopup.value && symptomPopup.value.close()
}
})
</script>
<style scoped lang="scss">
/* 病情描述弹窗样式 */
.symptom-popup {
background-color: white;
border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx;
max-height: 75vh;
display: flex;
flex-direction: column;
z-index: 999; // 确保弹窗在最上层,避免被 ConsultationBar 遮挡
}
.popup-header {
padding: 20rpx 20rpx 0;
}
.popup-title {
font-size: $font-size-text;
font-weight: 600;
color: #333;
}
.popup-content {
flex: 1;
padding: 10rpx 20rpx 20rpx 20rpx;
overflow-y: auto;
}
.symptom-textarea {
width: 100%;
min-height: 120rpx;
background-color: #f8f9fa;
border: 1rpx solid #e9ecef;
border-radius: 16rpx;
padding: 12rpx;
font-size: 28rpx;
line-height: 1.5;
box-sizing: border-box;
resize: none;
}
.section {
margin-top: 20rpx;
}
.section-title {
font-size: $font-size-text;
font-weight: 600;
color: #333;
margin-bottom: 0;
flex: 1;
}
.upload-subtitle {
font-size: $font-size-tip;
color: #666;
display: block;
margin-bottom: 16rpx;
}
.upload-header {
display: flex;
align-items: center;
margin-bottom: 16rpx;
gap: 12rpx;
}
.upload-header .section-title {
margin-bottom: 0;
flex: none;
}
.upload-header .upload-subtitle {
margin-bottom: 0;
flex: 1;
text-align: left;
}
.upload-actions {
display: flex;
gap: 20rpx;
}
.upload-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 120rpx;
height: 120rpx;
background-color: #f8f9fa;
border: 1rpx solid #e9ecef;
border-radius: 16rpx;
gap: 8rpx;
transition: all 0.3s;
}
.upload-btn:active {
background-color: #e9ecef;
transform: scale(0.95);
}
.upload-text {
font-size: $font-size-tip;
color: #666;
}
.image-preview {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
margin-top: 16rpx;
}
.preview-item {
position: relative;
width: 80rpx;
height: 80rpx;
}
.preview-image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.remove-btn {
position: absolute;
top: -8rpx;
right: -8rpx;
width: 24rpx;
height: 24rpx;
background-color: #ff4757;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.popup-footer {
display: flex;
padding: 20rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
border-top: 1rpx solid #f0f0f0;
gap: 16rpx;
}
.popup-btn {
flex: 1;
height: 88rpx;
border-radius: 12rpx;
font-size: $font-size-text;
font-weight: 500;
border: none;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
}
.cancel-btn {
background-color: #f8f9fa;
color: #666;
}
.cancel-btn:active {
background-color: #e9ecef;
}
.submit-btn {
background-color: $primary-color;
color: white;
}
.popup-btn::after {
border: none;
}
.checkbox-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12rpx;
}
.checkbox-row .uni-data-checklist {
flex: none;
}
.checkbox-group {
flex-shrink: 0;
}
/* 诊断容器样式 */
.diagnosis-container {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8rpx;
}
.selected-diseases {
display: flex;
flex-wrap: wrap;
gap: 8rpx;
}
.add-disease-btn {
cursor: pointer;
}
.tag-item {
border: 1px solid #eee;
padding: 8rpx 30rpx;
border-radius: 40rpx;
font-size: 28rpx;
color: #666;
margin-bottom: 12rpx;
}
.tag-item-active {
background-color: #0074ff;
border-color: #0074ff;
color: #fff;
}
</style>