fix:优化病例为病历,新增发送内容和附件功能

This commit is contained in:
Jafeng 2026-02-04 15:15:45 +08:00
parent b9385ebf02
commit 5d6a5a4a82
5 changed files with 220 additions and 10 deletions

View File

@ -21,7 +21,7 @@
{ {
"path": "pages/home/case-home", "path": "pages/home/case-home",
"style": { "style": {
"navigationBarTitleText": "病" "navigationBarTitleText": "病"
} }
}, },
{ {
@ -311,7 +311,7 @@
"pagePath": "pages/home/case-home", "pagePath": "pages/home/case-home",
"iconPath": "static/tabbar/cart.png", "iconPath": "static/tabbar/cart.png",
"selectedIconPath": "static/tabbar/cart_selected.png", "selectedIconPath": "static/tabbar/cart_selected.png",
"text": "病" "text": "病"
}, },
{ {
"pagePath": "pages/home/work-home", "pagePath": "pages/home/work-home",

View File

@ -46,6 +46,33 @@
<view class="counter">{{ (form.taskContent || '').length }}/200</view> <view class="counter">{{ (form.taskContent || '').length }}/200</view>
</view> </view>
</view> </view>
<view class="block">
<view class="block-title">向患者发送</view>
<view class="textarea-box">
<textarea v-model="form.sendContent" class="textarea" placeholder="请输入要发送给患者的内容" maxlength="200" />
<view class="counter">{{ (form.sendContent || '').length }}/200</view>
</view>
</view>
<view class="row clickable" @click="chooseFile">
<view class="left">
<view class="label">添加附件</view>
</view>
<view class="right">
<uni-icons type="plusempty" size="16" color="#0877F1" />
</view>
</view>
<view v-if="showFileList.length" class="file-list">
<view v-for="(i, index) in showFileList" :key="String(i._k || index)" class="file-item">
<view class="file-main">
<view v-if="i.typeStr" class="file-type">{{ i.typeStr }}</view>
<view class="file-name">{{ i.fileName }}</view>
</view>
<uni-icons type="closeempty" size="18" color="#999" @click="removeFile(index)" />
</view>
</view>
</view> </view>
<view class="footer"> <view class="footer">
@ -106,6 +133,7 @@ import api from '@/utils/api';
import useAccountStore from '@/store/account'; import useAccountStore from '@/store/account';
import { toast } from '@/utils/widget'; import { toast } from '@/utils/widget';
import { getTodoEventTypeLabel, getTodoEventTypeOptions } from '@/utils/todo-const'; import { getTodoEventTypeLabel, getTodoEventTypeOptions } from '@/utils/todo-const';
import { chooseAndUploadImage } from '@/utils/file';
const archiveId = ref(''); const archiveId = ref('');
const archiveName = ref(''); const archiveName = ref('');
@ -127,6 +155,8 @@ const form = reactive({
executorName: '', // anotherName executorName: '', // anotherName
eventType: '', eventType: '',
taskContent: '', taskContent: '',
sendContent: '',
fileList: [],
}); });
const eventTypeLabel = computed(() => getTodoEventTypeLabel(form.eventType)); const eventTypeLabel = computed(() => getTodoEventTypeLabel(form.eventType));
@ -165,6 +195,8 @@ function resetForm(keepCustomer = false) {
form.executorName = ''; form.executorName = '';
form.eventType = ''; form.eventType = '';
form.taskContent = ''; form.taskContent = '';
form.sendContent = '';
form.fileList = [];
if (!keepCustomer) { if (!keepCustomer) {
archiveId.value = ''; archiveId.value = '';
archiveName.value = ''; archiveName.value = '';
@ -174,6 +206,35 @@ function resetForm(keepCustomer = false) {
uni.setStorageSync('select-mamagement-plan', ''); uni.setStorageSync('select-mamagement-plan', '');
} }
const QUESTIONNAIRE_ICON =
'https://796f-youcan-clouddev-1-8ewcqf31dbb2b5-1317294507.tcb.qcloud.la/other/19-%E9%97%AE%E5%8D%B7.png?sign=55a4cd77c418b2c548b65792a2cf6bce&t=1701328694';
const ARTICLE_ICON =
'https://796f-youcan-clouddev-1-8ewcqf31dbb2b5-1317294507.tcb.qcloud.la/other/18-%E5%AE%A3%E6%95%99.png?sign=26f221d14fd57a2ff0a106dfb01a5e7a&t=1701328694';
const showFileList = computed(() =>
(Array.isArray(form.fileList) ? form.fileList : []).map((i, idx) => {
const type = i?.type;
const fileType = i?.file && typeof i.file.type === 'string' ? i.file.type : '';
let typeStr = '';
if (type === 'image' || fileType.includes('image')) typeStr = '【图片】';
else if (type === 'video' || fileType.includes('video')) typeStr = '【视频】';
else if (fileType === 'article') typeStr = '【文章】';
else if (fileType === 'questionnaire') typeStr = '【问卷】';
else if (type === 'link') typeStr = '【链接】';
const fileName =
String(i?.file?.name || i?.file?.title || i?.name || i?.URL || '').trim() ||
`附件${idx + 1}`;
return {
...i,
_k: `${idx}_${String(i?.type || '')}_${String(i?.URL || '')}`,
typeStr,
fileName,
};
})
);
async function ensureDoctor() { async function ensureDoctor() {
if (doctorInfo.value) return; if (doctorInfo.value) return;
if (!account.value?.openid) return; if (!account.value?.openid) return;
@ -272,6 +333,9 @@ async function save() {
const customerName = String(customer.name || archiveName.value || ''); const customerName = String(customer.name || archiveName.value || '');
const customerUserId = String(customer.externalUserId || customer.customerUserId || '') || ''; const customerUserId = String(customer.externalUserId || customer.customerUserId || '') || '';
const enableSend = !!(String(form.sendContent || '').trim() || (Array.isArray(form.fileList) && form.fileList.length));
const fileList = Array.isArray(form.fileList) ? form.fileList : [];
const params = { const params = {
corpId, corpId,
customerId, customerId,
@ -283,15 +347,15 @@ async function save() {
userId: form.executorUserId || userId, userId: form.executorUserId || userId,
taskList: [ taskList: [
{ {
enableSend: false, enableSend,
eventType: form.eventType, eventType: form.eventType,
executeMethod: 'todo', executeMethod: 'todo',
executorUserId: form.executorUserId || userId, executorUserId: form.executorUserId || userId,
planExecutionTime: form.planExecutionTime, planExecutionTime: form.planExecutionTime,
sendContent: '', sendContent: String(form.sendContent || ''),
taskContent: form.taskContent, taskContent: form.taskContent,
taskId: `${Date.now()}_${Math.random().toString(16).slice(2)}`, taskId: `${Date.now()}_${Math.random().toString(16).slice(2)}`,
fileList: [], fileList,
}, },
], ],
}; };
@ -324,6 +388,81 @@ function pickExecutor(m) {
function closeExecutorPicker() { function closeExecutorPicker() {
executorPopup.value?.close?.(); executorPopup.value?.close?.();
} }
function removeFile(index) {
if (!Array.isArray(form.fileList)) form.fileList = [];
form.fileList.splice(index, 1);
}
function chooseFile() {
uni.showActionSheet({
itemList: ['图片', '文章', '问卷'],
success: ({ tapIndex }) => {
if (tapIndex === 0) chooseImage();
else if (tapIndex === 1) chooseArticle();
else if (tapIndex === 2) chooseQuestionnaire();
},
});
}
async function chooseImage() {
const url = await chooseAndUploadImage({ count: 1 });
if (!url) return;
form.fileList.push({
type: 'image',
URL: url,
file: {
type: 'image',
name: `图片_${dayjs().format('MMDD_HHmmss')}.jpg`,
},
});
}
function chooseArticle() {
const eventName = `on-select-article_${Date.now()}`;
uni.navigateTo({
url: `/pages/message/article-list?select=1&eventName=${eventName}`,
});
uni.$once(eventName, (data) => {
const corpId = getCorpId();
const articleId = String(data?._id || data?.id || '');
if (!articleId) return;
const url = `${__VITE_ENV__?.MP_PATIENT_PAGE_BASE_URL || ''}pages/article/index?id=${articleId}&corpId=${corpId}`;
form.fileList.push({
type: 'link',
URL: String(data?.cover || data?.imgUrl || '') || ARTICLE_ICON,
file: {
type: 'article',
name: String(data?.title || '宣教文章'),
subtitle: String(data?.summary || data?.desc || ''),
url,
},
});
});
}
function chooseQuestionnaire() {
const eventName = `on-select-survey_${Date.now()}`;
uni.navigateTo({
url: `/pages/message/survey-list?select=1&eventName=${eventName}&patientId=${archiveId.value}&customerName=${archiveName.value || ''}`,
});
uni.$once(eventName, (data) => {
const corpId = getCorpId();
const surveryId = String(data?._id || data?.surveryId || '');
if (!surveryId) return;
const url = `${__VITE_ENV__?.MP_PATIENT_PAGE_BASE_URL || ''}pages/survery/fill?corpId=${corpId}&surveryId=${surveryId}`;
form.fileList.push({
type: 'link',
URL: QUESTIONNAIRE_ICON,
file: {
type: 'questionnaire',
name: String(data?.name || '问卷'),
surveryId,
url,
},
});
});
}
</script> </script>
<style scoped> <style scoped>
@ -440,6 +579,39 @@ function closeExecutorPicker() {
font-size: 12px; font-size: 12px;
color: #999; color: #999;
} }
.file-list {
padding: 0 14px 14px;
}
.file-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin-top: 10px;
padding: 12px 12px;
background: #f5f6f8;
border-radius: 8px;
}
.file-main {
display: flex;
align-items: center;
min-width: 0;
gap: 8px;
}
.file-type {
flex-shrink: 0;
font-size: 12px;
color: #666;
}
.file-name {
font-size: 14px;
color: #333;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 240px;
}
.toggle-row { .toggle-row {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -60,9 +60,9 @@
class="send-btn" class="send-btn"
size="mini" size="mini"
type="primary" type="primary"
@click.stop="sendArticle(article)" @click.stop="handlePrimaryAction(article)"
> >
发送 {{ isSelectMode ? '选择' : '发送' }}
</button> </button>
</view> </view>
</view> </view>
@ -124,6 +124,9 @@ const pageParams = ref({
corpId: "", corpId: "",
}); });
const isSelectMode = ref(false);
const selectEventName = ref("");
// //
const searchTitle = ref(""); const searchTitle = ref("");
let searchTimer = null; let searchTimer = null;
@ -311,6 +314,20 @@ const closePreview = () => {
previewPopup.value?.close(); previewPopup.value?.close();
}; };
const selectArticle = (article) => {
if (!selectEventName.value) {
uni.showToast({ title: "缺少 eventName", icon: "none" });
return;
}
uni.$emit(selectEventName.value, article);
uni.navigateBack();
};
const handlePrimaryAction = (article) => {
if (isSelectMode.value) return selectArticle(article);
return sendArticle(article);
};
// //
const sendArticle = async (article) => { const sendArticle = async (article) => {
try { try {
@ -398,6 +415,8 @@ const goBack = () => {
// //
onLoad((options) => { onLoad((options) => {
isSelectMode.value = String(options?.select || '') === '1';
selectEventName.value = String(options?.eventName || '');
if (options.groupId) { if (options.groupId) {
pageParams.value.groupId = options.groupId; pageParams.value.groupId = options.groupId;
} }

View File

@ -63,9 +63,9 @@
class="send-btn" class="send-btn"
size="mini" size="mini"
type="primary" type="primary"
@click="sendSurvey(survey)" @click="handlePrimaryAction(survey)"
> >
发送 {{ isSelectMode ? '选择' : '发送' }}
</button> </button>
</view> </view>
</view> </view>
@ -118,14 +118,33 @@ const pageSize = 30;
const total = ref(0); const total = ref(0);
const emptyText = ref(""); const emptyText = ref("");
const isSelectMode = ref(false);
const selectEventName = ref("");
// //
onLoad((options) => { onLoad((options) => {
isSelectMode.value = String(options?.select || '') === '1';
selectEventName.value = String(options?.eventName || '');
customerId.value = options?.patientId || ""; customerId.value = options?.patientId || "";
customerName.value = options?.customerName || ""; customerName.value = options?.customerName || "";
getCategoryList(); getCategoryList();
loadSurveyList(); loadSurveyList();
}); });
const selectSurvey = (survey) => {
if (!selectEventName.value) {
uni.showToast({ title: "缺少 eventName", icon: "none" });
return;
}
uni.$emit(selectEventName.value, survey);
uni.navigateBack();
};
const handlePrimaryAction = (survey) => {
if (isSelectMode.value) return selectSurvey(survey);
return sendSurvey(survey);
};
// //
const getCategoryList = async () => { const getCategoryList = async () => {
try { try {

View File

@ -47,7 +47,7 @@ export default [
}, },
{ {
path: 'pages/home/case-home', path: 'pages/home/case-home',
meta: { title: '病', login: false }, meta: { title: '病', login: false },
}, },
{ {
path: 'pages/case/search', path: 'pages/case/search',