ykt-wxapp/pages/message/components/medical-case-progress.vue
2026-01-29 18:03:40 +08:00

198 lines
4.3 KiB
Vue
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>
<uni-popup ref="popup" type="center" :mask-click="false">
<view class="progress-modal">
<view class="close-btn" @click="close">
<text class="close-icon"></text>
</view>
<view class="progress-content">
<view class="progress-title">{{ progressTitle }}</view>
<view class="progress-bar-wrapper">
<view class="progress-bar">
<view class="progress-fill" :style="{ width: progress + '%' }"></view>
</view>
<text class="progress-text">{{ progress }}%</text>
</view>
<view v-if="detectedInfo.length > 0" class="detected-info">
<text class="detected-title">检测到以下{{ caseTypeName }}信息</text>
<view class="info-list">
<view v-for="(item, index) in detectedInfo" :key="index" class="info-item">
<text class="check-icon"></text>
<text class="info-text">{{ item }}</text>
</view>
</view>
</view>
<view v-if="isGenerating" class="generating-text">
正在生成结构化{{ caseTypeName }}...
</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref, computed } from 'vue';
const popup = ref(null);
const progress = ref(0);
const detectedInfo = ref([]);
const isGenerating = ref(false);
const caseType = ref('');
const CASE_TYPE_NAMES = {
outpatient: '门诊病历',
inpatient: '住院病历',
physicalExam: '体检记录',
preConsultation: '预问诊记录'
};
const caseTypeName = computed(() => CASE_TYPE_NAMES[caseType.value] || '病历');
const progressTitle = computed(() => {
if (progress.value < 100) {
return `正在智能整理${caseTypeName.value}...`;
}
return `${caseTypeName.value}生成完成`;
});
const open = (type) => {
caseType.value = type;
progress.value = 0;
detectedInfo.value = [];
isGenerating.value = false;
popup.value?.open();
};
const close = () => {
popup.value?.close();
};
const updateProgress = (value) => {
progress.value = value;
};
const addDetectedInfo = (info) => {
detectedInfo.value.push(info);
};
const setGenerating = (value) => {
isGenerating.value = value;
};
defineExpose({
open,
close,
updateProgress,
addDetectedInfo,
setGenerating
});
</script>
<style scoped lang="scss">
.progress-modal {
width: 600rpx;
background-color: #ffffff;
border-radius: 24rpx;
padding: 48rpx 40rpx;
position: relative;
.close-btn {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
.close-icon {
font-size: 40rpx;
color: #999999;
}
}
.progress-content {
.progress-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
margin-bottom: 32rpx;
text-align: center;
}
.progress-bar-wrapper {
display: flex;
align-items: center;
gap: 16rpx;
margin-bottom: 32rpx;
.progress-bar {
flex: 1;
height: 16rpx;
background-color: #e5e5e5;
border-radius: 8rpx;
overflow: hidden;
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #1890ff 0%, #40a9ff 100%);
transition: width 0.3s ease;
}
}
.progress-text {
font-size: 28rpx;
color: #1890ff;
font-weight: 600;
min-width: 80rpx;
text-align: right;
}
}
.detected-info {
margin-bottom: 24rpx;
.detected-title {
font-size: 28rpx;
color: #666666;
display: block;
margin-bottom: 16rpx;
}
.info-list {
.info-item {
display: flex;
align-items: flex-start;
gap: 12rpx;
margin-bottom: 12rpx;
.check-icon {
font-size: 28rpx;
color: #52c41a;
font-weight: bold;
}
.info-text {
flex: 1;
font-size: 26rpx;
color: #333333;
line-height: 1.5;
}
}
}
}
.generating-text {
font-size: 28rpx;
color: #1890ff;
text-align: center;
padding: 16rpx 0;
}
}
}
</style>