医疗预约系统中的录音与图片上传功能实现:Vue3+Uniapp 实战
在移动医疗应用开发中,实现便捷的多媒体交互功能对于提升用户体验至关重要。本文将详细介绍如何在医疗预约系统中集成录音和图片上传功能,结合 Vue3 和 Uniapp 框架,打造流畅的患者就诊记录交互体验。
功能概述
我们实现的医疗记录页面包含以下核心功能:
- 就诊人信息管理与切换
- 就诊详情展示
- 图片上传功能
- 录音录制与上传功能
- 预约确认流程
下面我们将重点解析图片上传和录音功能的实现细节,这两个功能是提升医疗记录丰富性的关键。
界面设计与布局
首先来看整体界面结构,我们采用了分区设计,将不同功能模块清晰分离:
<template><div class="medical-record-container"><!-- 就诊人信息区域 --><div class="patient-info"><!-- 就诊人信息内容 --></div><!-- 就诊详情区域 --><div class="visit-details"><!-- 就诊详情内容 --><!-- 录音播放区域 --><div class="detail-item"><span class="label">录音</span><span class="value" style="display: flex;align-items: center;gap: 10px;" @click="playAudio"><uv-icon size="28" color="rgb(42,130,228)" name="play-circle-fill"></uv-icon> {{ audioDuration || '00:00' }}</span></div><!-- 添加图片、录音按钮区域 --><div class="action-btns"><div class="action-btn" @click="openPopups" style="border-right: 1px solid #ddd;">添加图片</div><div class="action-btn" @click="openPopupes">添加录音</div></div></div><!-- 文字描述输入区域 --><div class="desc-section"><!-- 文字描述内容 --></div><!-- 费用及确认区域 --><div class="footer"><!-- 费用及确认按钮 --></div><!-- 图片上传弹窗 --><uv-popup ref="popups" mode="bottom"><!-- 图片上传组件 --></uv-popup><!-- 录音弹窗 --><uv-popup ref="popupes" mode="bottom"><!-- 录音组件 --></uv-popup></div>
</template>
界面设计遵循了医疗应用的专业性与易用性原则,采用清晰的视觉层级和直观的交互方式,让用户能够轻松完成图片和录音的添加操作。
图片上传功能实现
图片上传功能允许用户添加医疗相关的图片资料,如检查报告、处方等,实现代码如下:
// 图片上传相关状态
const fileList1 = ref([]);
const imgurl = ref('');// 打开图片上传弹窗
const openPopups = () => {popups.value?.open();
};// 删除图片
const deletePic = (event) => {fileList1.value.splice(event.index, 1);
};// 选择图片后处理
const afterRead = async (event) => {// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式let lists = [].concat(event.file);let fileListLen = fileList1.value.length;lists.map((item) => {fileList1.value.push({...item,status: 'uploading',message: '上传中'});});for (let i = 0; i < lists.length; i++) {const result = await uploadFilePromise(lists[i].url);let item = fileList1.value[fileListLen];fileList1.value.splice(fileListLen, 1, Object.assign(item, {status: 'success',message: '',url: result}));fileListLen++;}
};// 上传文件Promise封装
const uploadFilePromise = (urls) => {return new Promise((resolve, reject) => {uni.uploadFile({url: 'https://yiliao.kuxia.top/pc/Fileimg/file',filePath: urls,name: 'file',formData: {user: 'test'},success: (res) => {setTimeout(() => {const response = JSON.parse(res.data);resolve(response.data.url);imgurl.value = response.data.url;}, 1000);},fail: (err) => {reject(err);}});});
};
图片上传流程设计考虑了以下几点:
- 使用弹窗形式展示上传界面,不占用主界面空间
- 实现了上传进度显示,提升用户体验
- 支持图片删除操作,方便用户纠错
- 通过 Promise 封装上传过程,便于异步流程控制
录音功能实现
录音功能是医疗记录中的重要补充,能够记录医生的口头医嘱或患者的症状描述,实现代码如下:
// 录音相关状态和变量
const audioDuration = ref('00:00');
const isRecording = ref(false);
const recorderManager = ref(null);
const audioPath = ref('');
const recordTime = ref(0);
const recordTimer = ref(null);
const audioUploaded = ref(false);
const audioUrl = ref('');// 初始化录音管理器
const initRecorder = () => {recorderManager.value = uni.getRecorderManager();recorderManager.value.onStart(() => {console.log('录音开始');isRecording.value = true;startRecordTimer();});recorderManager.value.onStop((res) => {console.log('录音结束', res);isRecording.value = false;stopRecordTimer();audioPath.value = res.tempFilePath;// 更新显示的录音时长updateAudioDuration(res.duration);});recorderManager.value.onError((err) => {console.error('录音失败:', err);isRecording.value = false;stopRecordTimer();uni.showToast({title: '录音失败',icon: 'none'});});
};// 开始录音计时器
const startRecordTimer = () => {recordTime.value = 0;recordTimer.value = setInterval(() => {recordTime.value++;updateAudioDuration(recordTime.value * 1000);}, 1000);
};// 停止录音计时器
const stopRecordTimer = () => {if (recordTimer.value) {clearInterval(recordTimer.value);recordTimer.value = null;}
};// 更新录音时长显示
const updateAudioDuration = (durationMs) => {const durationSec = Math.floor(durationMs / 1000);const minutes = Math.floor(durationSec / 60).toString().padStart(2, '0');const seconds = (durationSec % 60).toString().padStart(2, '0');audioDuration.value = `${minutes}:${seconds}`;
};// 点击录音按钮事件
const toggleRecord = () => {if (isRecording.value) {// 停止录音recorderManager.value.stop();} else {// 开始录音recorderManager.value.start({format: 'mp3',duration: 600000, // 最长10分钟sampleRate: 44100,numberOfChannels: 1,encodeBitRate: 192000});audioUploaded.value = false;}
};// 确认上传录音
const confirmUpload = async () => {if (!audioPath.value) {uni.showToast({title: '请先录制音频',icon: 'none'});return;}try {uni.showLoading({title: '上传中...'});// 上传录音文件const uploadedUrl = await uploadAudioFile(audioPath.value);uni.showToast({title: '上传成功',icon: 'success'});audioUploaded.value = true;audioUrl.value = uploadedUrl;popupes.value?.close();} catch (error) {console.error('上传失败:', error);uni.showToast({title: '上传失败',icon: 'none'});} finally {uni.hideLoading();}
};// 播放录音
const playAudio = () => {if (!audioPath.value) {uni.showToast({title: '暂无录音',icon: 'none'});return;}const innerAudioContext = uni.createInnerAudioContext();innerAudioContext.src = audioPath.value;innerAudioContext.play();innerAudioContext.onError((res) => {console.error('播放失败:', res);uni.showToast({title: '播放失败',icon: 'none'});});
};
录音功能的设计亮点:
- 直观的录音时长显示,采用分:秒格式
- 录音状态清晰可见,通过颜色变化提示用户
- 完整的错误处理机制,确保录音过程稳定
- 支持录音播放功能,方便用户确认录音内容
数据提交与预约确认
最后,我们需要将所有信息(包括文字描述、图片和录音)提交到服务器,完成预约流程:
const confirm = async () => {if (!visitdata.value?.card) {uni.showToast({title: '请选择就诊人',icon: 'none'});return;}try {console.log({user_id: uni.getStorageSync('userInfo').id,card: visitdata.value.card,depart_id: department.value?.id,doctor_id: doctor_id,price: doctor.value?.doctorInfo?.money,trends: desc.value,img: imgurl.value,audio: audioUrl.value,status: 1,create_time: time_date,time: time_value,});const res = await addRegister({// 提交的数据包括图片和录音的URLuser_id: uni.getStorageSync('userInfo').id,card: visitdata.value.card,depart_id: department.value?.id,doctor_id: doctor_id,price: doctor.value?.doctorInfo?.money,trends: desc.value,img: imgurl.value,audio: audioUrl.value,status: 1,create_time: time_date,time: time_value,});console.log(res);if (res.code == 1) {// 显示成功提示弹窗successModal.value.open();} else {uni.showToast({title: res.msg,icon: 'none'});}} catch (err) {console.log(err);uni.showToast({title: '预约失败',icon: 'none'});}
};
总结与优化建议
本文实现的图片和录音上传功能,为医疗预约系统增添了丰富的多媒体交互能力。在实际应用中,还可以考虑以下优化方向:
- 实现图片压缩功能,减少上传流量和时间
- 增加录音转文字功能,提高记录的可搜索性
- 支持多图上传和多段录音,满足复杂医疗场景需求
- 实现上传中断后的断点续传功能
通过这些功能的实现,医疗应用能够更好地服务于医患双方,提高医疗记录的完整性和准确性,为远程医疗和复诊提供更全面的参考资料。