Merge remote-tracking branch 'origin/dev-hjf' into dev-wdb
This commit is contained in:
commit
01f91d83d8
@ -376,11 +376,20 @@ function eventTypeLabel(eventType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolveUserName(userId) {
|
function resolveUserName(userId) {
|
||||||
|
const id = String(userId || "");
|
||||||
if (!id) return "";
|
if (!id) return "";
|
||||||
const map = userNameMap.value || {};
|
const map = userNameMap.value || {};
|
||||||
return String(map[id] || "") || id;
|
return String(map[id] || "") || id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshChatRoom() {
|
||||||
|
if (!props.fromChat) return;
|
||||||
|
const pending = uni.getStorageSync(PENDING_FOLLOWUP_SEND_STORAGE_KEY);
|
||||||
|
if (pending && typeof pending === "object") {
|
||||||
|
chatGroupId.value = String(pending.chatGroupId || pending.groupId || "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function formatTodo(todo) {
|
function formatTodo(todo) {
|
||||||
const status = getStatus(todo);
|
const status = getStatus(todo);
|
||||||
const plannedExecutionTime = todo?.plannedExecutionTime;
|
const plannedExecutionTime = todo?.plannedExecutionTime;
|
||||||
@ -446,13 +455,23 @@ async function getMore() {
|
|||||||
toast(res?.message || "获取回访任务失败");
|
toast(res?.message || "获取回访任务失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const arr = Array.isArray(res.data) ? res.data : [];
|
|
||||||
|
// 对齐管理端同接口返回结构:{ success, data: { data: [], total } }
|
||||||
|
const payload = res?.data;
|
||||||
|
const arr = payload && Array.isArray(payload.data)
|
||||||
|
? payload.data
|
||||||
|
: Array.isArray(payload)
|
||||||
|
? payload
|
||||||
|
: [];
|
||||||
const next = arr.map(formatTodo);
|
const next = arr.map(formatTodo);
|
||||||
|
|
||||||
total.value = typeof res.total === "number" ? res.total : 0;
|
total.value = payload && typeof payload.total === "number" ? payload.total : 0;
|
||||||
pages.value = Math.ceil(total.value / pageSize) || 0;
|
pages.value = Math.ceil(total.value / pageSize) || 0;
|
||||||
list.value = page.value === 1 ? next : [...list.value, ...next];
|
list.value = page.value === 1 ? next : [...list.value, ...next];
|
||||||
page.value += 1;
|
page.value += 1;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("getCustomerTodos failed:", e);
|
||||||
|
toast("获取回访任务失败");
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,11 +9,16 @@
|
|||||||
</view>
|
</view>
|
||||||
</picker>
|
</picker>
|
||||||
|
|
||||||
<uni-datetime-picker type="daterange" :value="dateRange" @change="pickTimeRange">
|
<uni-datetime-picker type="daterange" v-model="dateRange" @change="pickTimeRange">
|
||||||
<view class="filter-pill">
|
<view class="filter-pill">
|
||||||
<view class="pill-text">{{ dateRangeLabel }}</view>
|
<view class="pill-text">{{ dateRangeLabel }}</view>
|
||||||
|
<view class="pill-icons">
|
||||||
|
<view v-if="isDateRangeActive" class="pill-clear" @tap.stop="clearTimeRange" @click.stop="clearTimeRange">
|
||||||
|
<uni-icons type="closeempty" size="16" color="#666" />
|
||||||
|
</view>
|
||||||
<uni-icons type="arrowdown" size="12" color="#666" />
|
<uni-icons type="arrowdown" size="12" color="#666" />
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
</uni-datetime-picker>
|
</uni-datetime-picker>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -80,7 +85,7 @@ const props = defineProps({
|
|||||||
floatingBottom: { type: Number, default: 16 },
|
floatingBottom: { type: Number, default: 16 },
|
||||||
});
|
});
|
||||||
|
|
||||||
const FALLBACK_TEMPLATE_TYPES = ['outpatient', 'inhospital', 'preConsultation', 'physicalExaminationTemplate'];
|
const FALLBACK_TEMPLATE_TYPES = ['outpatient', 'inhospital', 'preConsultationRecord', 'physicalExaminationTemplate'];
|
||||||
const templates = ref([]);
|
const templates = ref([]);
|
||||||
const selectableTemplates = computed(() => templates.value.filter((i) => i && i.templateType && typeof i.name === 'string' && i.name.trim()));
|
const selectableTemplates = computed(() => templates.value.filter((i) => i && i.templateType && typeof i.name === 'string' && i.name.trim()));
|
||||||
const useActionSheet = computed(() => selectableTemplates.value.length > 0 && selectableTemplates.value.length <= 6);
|
const useActionSheet = computed(() => selectableTemplates.value.length > 0 && selectableTemplates.value.length <= 6);
|
||||||
@ -97,6 +102,9 @@ const currentType = ref({ name: '全部', value: 'ALL' });
|
|||||||
const records = ref([]);
|
const records = ref([]);
|
||||||
|
|
||||||
const dateRange = ref([]);
|
const dateRange = ref([]);
|
||||||
|
const isDateRangeActive = computed(
|
||||||
|
() => Array.isArray(dateRange.value) && dateRange.value.length === 2 && dateRange.value[0] && dateRange.value[1]
|
||||||
|
);
|
||||||
const dateRangeLabel = computed(() => {
|
const dateRangeLabel = computed(() => {
|
||||||
if (Array.isArray(dateRange.value) && dateRange.value.length === 2 && dateRange.value[0] && dateRange.value[1]) {
|
if (Array.isArray(dateRange.value) && dateRange.value.length === 2 && dateRange.value[0] && dateRange.value[1]) {
|
||||||
return `${dateRange.value[0]} 至 ${dateRange.value[1]}`;
|
return `${dateRange.value[0]} 至 ${dateRange.value[1]}`;
|
||||||
@ -226,12 +234,13 @@ async function loadTeamMembers() {
|
|||||||
|
|
||||||
function getSortTimeTitle(templateType) {
|
function getSortTimeTitle(templateType) {
|
||||||
const rawType = String(templateType || '');
|
const rawType = String(templateType || '');
|
||||||
|
const ui = normalizeMedicalType(rawType);
|
||||||
|
// 预问诊记录:列表时间固定使用就诊日期字段,避免被模板配置的 timeTitle 覆盖
|
||||||
|
if (ui === 'preConsultationRecord') return 'consultationDate';
|
||||||
const t = templateMap.value[rawType] || {};
|
const t = templateMap.value[rawType] || {};
|
||||||
if (t?.service?.timeTitle) return String(t.service.timeTitle);
|
if (t?.service?.timeTitle) return String(t.service.timeTitle);
|
||||||
const ui = normalizeMedicalType(rawType);
|
|
||||||
if (ui === 'outpatient') return 'visitTime';
|
if (ui === 'outpatient') return 'visitTime';
|
||||||
if (ui === 'inhospital') return 'inhosDate';
|
if (ui === 'inhospital') return 'inhosDate';
|
||||||
if (ui === 'preConsultation') return 'consultDate';
|
|
||||||
if (ui === 'physicalExaminationTemplate') return 'inspectDate';
|
if (ui === 'physicalExaminationTemplate') return 'inspectDate';
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -275,14 +284,15 @@ function normalizeMedicalType(raw) {
|
|||||||
const s = String(raw || '').trim();
|
const s = String(raw || '').trim();
|
||||||
if (!s) return '';
|
if (!s) return '';
|
||||||
const lower = s.toLowerCase();
|
const lower = s.toLowerCase();
|
||||||
if (lower.includes('preconsult') || (lower.includes('pre') && lower.includes('consult'))) return 'preConsultation';
|
if (lower.includes('preconsult') || (lower.includes('pre') && lower.includes('consult'))) return 'preConsultationRecord';
|
||||||
if (lower === 'outpatient' || lower === 'out_patient' || lower === 'out-patient') return 'outpatient';
|
if (lower === 'outpatient' || lower === 'out_patient' || lower === 'out-patient') return 'outpatient';
|
||||||
if (lower === 'inhospital' || lower === 'in_hospital' || lower === 'in-hospital' || lower === 'inpatient') return 'inhospital';
|
if (lower === 'inhospital' || lower === 'in_hospital' || lower === 'in-hospital' || lower === 'inpatient') return 'inhospital';
|
||||||
if (lower === 'preconsultation' || lower === 'pre_consultation' || lower === 'pre-consultation') return 'preConsultation';
|
if (lower === 'preconsultation' || lower === 'pre_consultation' || lower === 'pre-consultation') return 'preConsultationRecord';
|
||||||
if (lower === 'physicalexaminationtemplate' || lower === 'physicalexamination' || lower === 'physical_examination') return 'physicalExaminationTemplate';
|
if (lower === 'physicalexaminationtemplate' || lower === 'physicalexamination' || lower === 'physical_examination') return 'physicalExaminationTemplate';
|
||||||
if (s === 'outPatient') return 'outpatient';
|
if (s === 'outPatient') return 'outpatient';
|
||||||
if (s === 'inHospital') return 'inhospital';
|
if (s === 'inHospital') return 'inhospital';
|
||||||
if (s === 'preConsultation') return 'preConsultation';
|
if (s === 'preConsultation') return 'preConsultationRecord';
|
||||||
|
if (s === 'preConsultationRecord') return 'preConsultationRecord';
|
||||||
if (s === 'physicalExaminationTemplate') return 'physicalExaminationTemplate';
|
if (s === 'physicalExaminationTemplate') return 'physicalExaminationTemplate';
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -389,7 +399,7 @@ async function refreshList() {
|
|||||||
const tagClass = {
|
const tagClass = {
|
||||||
outpatient: 'bg-amber',
|
outpatient: 'bg-amber',
|
||||||
inhospital: 'bg-teal',
|
inhospital: 'bg-teal',
|
||||||
preConsultation: 'bg-indigo',
|
preConsultationRecord: 'bg-indigo',
|
||||||
physicalExaminationTemplate: 'bg-green',
|
physicalExaminationTemplate: 'bg-green',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -401,14 +411,14 @@ function resolveRecordType(r) {
|
|||||||
if (r.inspectDate || r.positiveFind || r.inspectSummary) return 'physicalExaminationTemplate';
|
if (r.inspectDate || r.positiveFind || r.inspectSummary) return 'physicalExaminationTemplate';
|
||||||
if (r.inhosDate || r.surgeryName || r.surgeryDate || r.operationDate) return 'inhospital';
|
if (r.inhosDate || r.surgeryName || r.surgeryDate || r.operationDate) return 'inhospital';
|
||||||
if (r.visitTime || r.disposePlan || r.treatmentPlan) return 'outpatient';
|
if (r.visitTime || r.disposePlan || r.treatmentPlan) return 'outpatient';
|
||||||
if (r.consultDate || r.presentIllness || r.presentIllnessHistory || r.pastHistory) return 'preConsultation';
|
if (r.consultationDate || r.consultDate || r.presentIllness || r.presentIllnessHistory || r.pastHistory) return 'preConsultationRecord';
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDiagnosis(r) {
|
function getDiagnosis(r) {
|
||||||
if (!r) return '--';
|
if (!r) return '--';
|
||||||
const t = resolveRecordType(r);
|
const t = resolveRecordType(r);
|
||||||
if (t === 'preConsultation') return normalizeText(r.chiefComplaint) || normalizeText(r.summary) || '--';
|
if (t === 'preConsultationRecord') return normalizeText(r.chiefComplaint) || normalizeText(r.summary) || '--';
|
||||||
if (t === 'physicalExaminationTemplate') return formatPositiveFind(r.positiveFind) || normalizeText(r.summary) || '--';
|
if (t === 'physicalExaminationTemplate') return formatPositiveFind(r.positiveFind) || normalizeText(r.summary) || '--';
|
||||||
if (t === 'outpatient' || t === 'inhospital') return normalizeText(r.diagnosisName || r.diagnosis) || normalizeText(r.summary) || '--';
|
if (t === 'outpatient' || t === 'inhospital') return normalizeText(r.diagnosisName || r.diagnosis) || normalizeText(r.summary) || '--';
|
||||||
return normalizeText(r.diagnosisName || r.diagnosis || r.summary) || '--';
|
return normalizeText(r.diagnosisName || r.diagnosis || r.summary) || '--';
|
||||||
@ -433,7 +443,7 @@ function getDisplayLines(r) {
|
|||||||
if (t === 'physicalExaminationTemplate') {
|
if (t === 'physicalExaminationTemplate') {
|
||||||
return [{ label: '体检小结:', value: firstLine(r.summary || r.inspectSummary) }];
|
return [{ label: '体检小结:', value: firstLine(r.summary || r.inspectSummary) }];
|
||||||
}
|
}
|
||||||
if (t === 'preConsultation') {
|
if (t === 'preConsultationRecord') {
|
||||||
const lines = [
|
const lines = [
|
||||||
{ label: '主诉:', value: firstLine(r.chiefComplaint) },
|
{ label: '主诉:', value: firstLine(r.chiefComplaint) },
|
||||||
{ label: '现病史:', value: firstLine(r.presentIllness || r.presentIllnessHistory) },
|
{ label: '现病史:', value: firstLine(r.presentIllness || r.presentIllnessHistory) },
|
||||||
@ -461,7 +471,19 @@ function pickType(e) {
|
|||||||
refreshList();
|
refreshList();
|
||||||
}
|
}
|
||||||
function pickTimeRange(val) {
|
function pickTimeRange(val) {
|
||||||
|
if (Array.isArray(val)) {
|
||||||
dateRange.value = val;
|
dateRange.value = val;
|
||||||
|
} else if (val && typeof val === 'object' && Array.isArray(val.value)) {
|
||||||
|
dateRange.value = val.value;
|
||||||
|
} else if (val && typeof val === 'object' && val.detail && Array.isArray(val.detail.value)) {
|
||||||
|
dateRange.value = val.detail.value;
|
||||||
|
} else {
|
||||||
|
dateRange.value = [];
|
||||||
|
}
|
||||||
|
refreshList();
|
||||||
|
}
|
||||||
|
function clearTimeRange() {
|
||||||
|
dateRange.value = [];
|
||||||
refreshList();
|
refreshList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +611,17 @@ watch(
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
.pill-icons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.pill-clear {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.share-tip {
|
.share-tip {
|
||||||
padding: 20rpx 28rpx 0;
|
padding: 20rpx 28rpx 0;
|
||||||
|
|||||||
@ -136,7 +136,7 @@ function formatPatient(raw) {
|
|||||||
const lr = raw.latestRecord;
|
const lr = raw.latestRecord;
|
||||||
const type = normalizeRecordTypeLabel(lr.type || lr.medicalTypeName || lr.medicalType || '');
|
const type = normalizeRecordTypeLabel(lr.type || lr.medicalTypeName || lr.medicalType || '');
|
||||||
const date = lr.date || '';
|
const date = lr.date || '';
|
||||||
const diagnosis = lr.diagnosis || '';
|
const diagnosis = normalizeBriefText(lr.diagnosisName || lr.inspectSummary || lr.chiefComplaint || lr.diagnosis || '');
|
||||||
if (type || date || diagnosis) {
|
if (type || date || diagnosis) {
|
||||||
record = {
|
record = {
|
||||||
type: type || '-',
|
type: type || '-',
|
||||||
@ -169,6 +169,34 @@ function normalizeText(value) {
|
|||||||
return String(value || '').trim();
|
return String(value || '').trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeBriefText(value) {
|
||||||
|
if (value === null || value === undefined) return '';
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
const parts = value.map((i) => normalizeBriefText(i)).filter((i) => String(i).trim());
|
||||||
|
return parts.join(',');
|
||||||
|
}
|
||||||
|
let s = String(value || '').trim();
|
||||||
|
if (!s) return '';
|
||||||
|
|
||||||
|
// 常见异常:后端把数组字符串化成 "[]" 或带换行的 JSON 数组
|
||||||
|
if (s === '[]' || s === '[ ]') return '';
|
||||||
|
if (s.startsWith('[') && s.endsWith(']')) {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(s);
|
||||||
|
if (Array.isArray(parsed)) {
|
||||||
|
s = parsed.map((i) => normalizeBriefText(i)).filter((i) => String(i).trim()).join(',');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 非 JSON 数组:去掉最外层括号,避免展示成 “[]”
|
||||||
|
s = s.replace(/^\[\s*/, '').replace(/\s*\]$/, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = String(s || '').replace(/[\r\n]+/g, ' ').replace(/\s+/g, ' ').trim();
|
||||||
|
if (s === '[]' || s === '[ ]') return '';
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeDigits(value) {
|
function normalizeDigits(value) {
|
||||||
const s = normalizeText(value);
|
const s = normalizeText(value);
|
||||||
return s.replace(/\D/g, '');
|
return s.replace(/\D/g, '');
|
||||||
|
|||||||
@ -24,6 +24,10 @@ const ALIAS_MAP = {
|
|||||||
presentIllnessHistory: 'presentIllness',
|
presentIllnessHistory: 'presentIllness',
|
||||||
pastMedicalHistory: 'pastHistory',
|
pastMedicalHistory: 'pastHistory',
|
||||||
},
|
},
|
||||||
|
preConsultationRecord: {
|
||||||
|
presentIllnessHistory: 'presentIllness',
|
||||||
|
pastMedicalHistory: 'pastHistory',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function normalizeVisitRecordFormData(templateType, raw) {
|
export function normalizeVisitRecordFormData(templateType, raw) {
|
||||||
@ -37,4 +41,3 @@ export function normalizeVisitRecordFormData(templateType, raw) {
|
|||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -76,6 +76,7 @@ const forms = computed(() => ({ ...detail.value, ...form }));
|
|||||||
const HIDDEN_FIELD_NAMES = {
|
const HIDDEN_FIELD_NAMES = {
|
||||||
outpatient: ['就诊机构', '就诊科室', '机构名称', '责任医生'],
|
outpatient: ['就诊机构', '就诊科室', '机构名称', '责任医生'],
|
||||||
inhospital: ['就诊机构', '机构名称'],
|
inhospital: ['就诊机构', '机构名称'],
|
||||||
|
physicalExaminationTemplate: ['体检套餐名称'],
|
||||||
};
|
};
|
||||||
const HIDDEN_FIELD_TITLES = {
|
const HIDDEN_FIELD_TITLES = {
|
||||||
// 对应 systemFieldName/title(来自模板):
|
// 对应 systemFieldName/title(来自模板):
|
||||||
@ -87,6 +88,8 @@ const HIDDEN_FIELD_TITLES = {
|
|||||||
// - 就诊机构: corp
|
// - 就诊机构: corp
|
||||||
// - 机构名称: corpName
|
// - 机构名称: corpName
|
||||||
inhospital: ['corp', 'corpName'],
|
inhospital: ['corp', 'corpName'],
|
||||||
|
// - 体检套餐名称: inspectPakageName
|
||||||
|
physicalExaminationTemplate: ['inspectPakageName'],
|
||||||
};
|
};
|
||||||
function shouldHideField(item) {
|
function shouldHideField(item) {
|
||||||
const t = String(templateType.value || '');
|
const t = String(templateType.value || '');
|
||||||
@ -306,10 +309,13 @@ async function remove() {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.scroll {
|
.scroll {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
.scroll-gap {
|
.scroll-gap {
|
||||||
height: calc(240rpx + env(safe-area-inset-bottom));
|
height: calc(240rpx + env(safe-area-inset-bottom));
|
||||||
@ -340,6 +346,7 @@ async function remove() {
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 24rpx;
|
gap: 24rpx;
|
||||||
box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
|
box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
|
||||||
|
z-index: 50;
|
||||||
}
|
}
|
||||||
.btn {
|
.btn {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|||||||
@ -49,8 +49,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue';
|
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||||
import { onLoad } from '@dcloudio/uni-app';
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import { loading, hideLoading, toast } from '@/utils/widget';
|
import { loading, hideLoading, toast } from '@/utils/widget';
|
||||||
@ -65,6 +65,8 @@ const medicalType = ref('');
|
|||||||
const rawType = ref('');
|
const rawType = ref('');
|
||||||
const record = ref({});
|
const record = ref({});
|
||||||
const temp = ref(null);
|
const temp = ref(null);
|
||||||
|
const needReload = ref(false);
|
||||||
|
let recordChangedHandler = null;
|
||||||
|
|
||||||
const files = computed(() => {
|
const files = computed(() => {
|
||||||
const arr = record.value?.files;
|
const arr = record.value?.files;
|
||||||
@ -79,14 +81,16 @@ function normalizeMedicalType(raw) {
|
|||||||
const s = String(raw || '').trim();
|
const s = String(raw || '').trim();
|
||||||
if (!s) return '';
|
if (!s) return '';
|
||||||
const lower = s.toLowerCase();
|
const lower = s.toLowerCase();
|
||||||
if (lower.includes('preconsult') || (lower.includes('pre') && lower.includes('consult'))) return 'preConsultation';
|
if (lower.includes('preconsultationrecord')) return 'preConsultationRecord';
|
||||||
|
if (lower.includes('preconsult') || (lower.includes('pre') && lower.includes('consult'))) return 'preConsultationRecord';
|
||||||
if (lower === 'outpatient' || lower === 'out_patient' || lower === 'out-patient') return 'outpatient';
|
if (lower === 'outpatient' || lower === 'out_patient' || lower === 'out-patient') return 'outpatient';
|
||||||
if (lower === 'inhospital' || lower === 'in_hospital' || lower === 'in-hospital' || lower === 'inpatient') return 'inhospital';
|
if (lower === 'inhospital' || lower === 'in_hospital' || lower === 'in-hospital' || lower === 'inpatient') return 'inhospital';
|
||||||
if (lower === 'preconsultation' || lower === 'pre_consultation' || lower === 'pre-consultation') return 'preConsultation';
|
if (lower === 'preconsultation' || lower === 'pre_consultation' || lower === 'pre-consultation') return 'preConsultationRecord';
|
||||||
if (lower === 'physicalexaminationtemplate' || lower === 'physicalexamination' || lower === 'physical_examination') return 'physicalExaminationTemplate';
|
if (lower === 'physicalexaminationtemplate' || lower === 'physicalexamination' || lower === 'physical_examination') return 'physicalExaminationTemplate';
|
||||||
if (s === 'outPatient') return 'outpatient';
|
if (s === 'outPatient') return 'outpatient';
|
||||||
if (s === 'inHospital') return 'inhospital';
|
if (s === 'inHospital') return 'inhospital';
|
||||||
if (s === 'preConsultation') return 'preConsultation';
|
if (s === 'preConsultation') return 'preConsultationRecord';
|
||||||
|
if (s === 'preConsultationRecord') return 'preConsultationRecord';
|
||||||
if (s === 'physicalExaminationTemplate') return 'physicalExaminationTemplate';
|
if (s === 'physicalExaminationTemplate') return 'physicalExaminationTemplate';
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -98,7 +102,7 @@ const typeLabel = computed(() => record.value?.tempName || temp.value?.name || g
|
|||||||
function getDefaultTimeTitle(t) {
|
function getDefaultTimeTitle(t) {
|
||||||
if (t === 'outpatient') return 'visitTime';
|
if (t === 'outpatient') return 'visitTime';
|
||||||
if (t === 'inhospital') return 'inhosDate';
|
if (t === 'inhospital') return 'inhosDate';
|
||||||
if (t === 'preConsultation') return 'consultDate';
|
if (t === 'preConsultationRecord') return 'consultationDate';
|
||||||
if (t === 'physicalExaminationTemplate') return 'inspectDate';
|
if (t === 'physicalExaminationTemplate') return 'inspectDate';
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -106,7 +110,7 @@ function getDefaultTimeTitle(t) {
|
|||||||
function getDefaultTimeName(t) {
|
function getDefaultTimeName(t) {
|
||||||
if (t === 'outpatient') return '就诊日期';
|
if (t === 'outpatient') return '就诊日期';
|
||||||
if (t === 'inhospital') return '入院日期';
|
if (t === 'inhospital') return '入院日期';
|
||||||
if (t === 'preConsultation') return '问诊日期';
|
if (t === 'preConsultationRecord') return '问诊日期';
|
||||||
if (t === 'physicalExaminationTemplate') return '体检日期';
|
if (t === 'physicalExaminationTemplate') return '体检日期';
|
||||||
return '日期';
|
return '日期';
|
||||||
}
|
}
|
||||||
@ -212,6 +216,8 @@ const sections = computed(() => {
|
|||||||
? ['corp', 'deptName', 'corpName', 'doctor']
|
? ['corp', 'deptName', 'corpName', 'doctor']
|
||||||
: t === 'inhospital'
|
: t === 'inhospital'
|
||||||
? ['corp', 'corpName']
|
? ['corp', 'corpName']
|
||||||
|
: t === 'physicalExaminationTemplate'
|
||||||
|
? ['inspectPakageName']
|
||||||
: []);
|
: []);
|
||||||
|
|
||||||
const list = [];
|
const list = [];
|
||||||
@ -289,6 +295,41 @@ const topText = computed(() => {
|
|||||||
return suffix ? `${time || '--'} ${suffix}` : `${time || '--'}`;
|
return suffix ? `${time || '--'} ${suffix}` : `${time || '--'}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function fetchRecord({ silent = false } = {}) {
|
||||||
|
if (!archiveId.value || !id.value || !medicalType.value) return false;
|
||||||
|
const corpId = getCorpId();
|
||||||
|
if (!corpId) {
|
||||||
|
if (!silent) toast('缺少 corpId');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!silent) loading('加载中...');
|
||||||
|
try {
|
||||||
|
const res = await api('getMedicalRecordById', {
|
||||||
|
_id: id.value,
|
||||||
|
corpId,
|
||||||
|
memberId: archiveId.value,
|
||||||
|
medicalType: medicalType.value,
|
||||||
|
});
|
||||||
|
const r = res?.record || res?.data?.record || null;
|
||||||
|
if (!res?.success || !r) return false;
|
||||||
|
|
||||||
|
const raw = String(r?.templateType || r?.medicalType || medicalType.value || '');
|
||||||
|
rawType.value = raw;
|
||||||
|
const ui = normalizeMedicalType(raw);
|
||||||
|
record.value = normalizeVisitRecordFormData(ui, r);
|
||||||
|
temp.value = await loadTemplate(raw);
|
||||||
|
uni.setNavigationBarTitle({ title: String(typeLabel.value || '病历详情') });
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取病历记录失败:', error);
|
||||||
|
if (!silent) toast('加载失败');
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
if (!silent) hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onLoad(async (opt) => {
|
onLoad(async (opt) => {
|
||||||
archiveId.value = opt?.archiveId ? String(opt.archiveId) : '';
|
archiveId.value = opt?.archiveId ? String(opt.archiveId) : '';
|
||||||
id.value = opt?.id ? String(opt.id) : '';
|
id.value = opt?.id ? String(opt.id) : '';
|
||||||
@ -298,45 +339,32 @@ onLoad(async (opt) => {
|
|||||||
setTimeout(() => uni.navigateBack(), 300);
|
setTimeout(() => uni.navigateBack(), 300);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const ok = await fetchRecord();
|
||||||
// 使用真实 API 获取病历记录
|
if (!ok) {
|
||||||
loading('加载中...');
|
|
||||||
try {
|
|
||||||
const corpId = getCorpId();
|
|
||||||
if (!corpId) {
|
|
||||||
hideLoading();
|
|
||||||
toast('缺少 corpId');
|
|
||||||
setTimeout(() => uni.navigateBack(), 300);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await api('getMedicalRecordById', {
|
|
||||||
_id: id.value,
|
|
||||||
corpId,
|
|
||||||
memberId: archiveId.value,
|
|
||||||
medicalType: medicalType.value,
|
|
||||||
});
|
|
||||||
hideLoading();
|
|
||||||
const r = res?.record || res?.data?.record || null;
|
|
||||||
if (!res?.success || !r) {
|
|
||||||
toast('记录不存在');
|
toast('记录不存在');
|
||||||
setTimeout(() => uni.navigateBack(), 300);
|
setTimeout(() => uni.navigateBack(), 300);
|
||||||
return;
|
|
||||||
}
|
|
||||||
const raw = String(r?.templateType || r?.medicalType || medicalType.value || '');
|
|
||||||
rawType.value = raw;
|
|
||||||
const ui = normalizeMedicalType(raw);
|
|
||||||
record.value = normalizeVisitRecordFormData(ui, r);
|
|
||||||
temp.value = await loadTemplate(raw);
|
|
||||||
uni.setNavigationBarTitle({ title: String(typeLabel.value || '病历详情') });
|
|
||||||
} catch (error) {
|
|
||||||
hideLoading();
|
|
||||||
console.error('获取病历记录失败:', error);
|
|
||||||
toast('加载失败');
|
|
||||||
setTimeout(() => uni.navigateBack(), 300);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
recordChangedHandler = () => {
|
||||||
|
needReload.value = true;
|
||||||
|
};
|
||||||
|
// 页面在编辑页返回前可能收到事件:先标记,回到页面再刷新
|
||||||
|
uni.$on('archive-detail:visit-record-changed', recordChangedHandler);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (recordChangedHandler) uni.$off('archive-detail:visit-record-changed', recordChangedHandler);
|
||||||
|
recordChangedHandler = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(async () => {
|
||||||
|
if (!needReload.value) return;
|
||||||
|
needReload.value = false;
|
||||||
|
await fetchRecord({ silent: true });
|
||||||
|
});
|
||||||
|
|
||||||
function preview(idx) {
|
function preview(idx) {
|
||||||
const urls = files.value.map((i) => i.url);
|
const urls = files.value.map((i) => i.url);
|
||||||
uni.previewImage({ urls, current: urls[idx] });
|
uni.previewImage({ urls, current: urls[idx] });
|
||||||
|
|||||||
@ -212,6 +212,7 @@ const lastPatientsLoadOk = ref(true);
|
|||||||
const loadedGroupsTeamId = ref('');
|
const loadedGroupsTeamId = ref('');
|
||||||
let enterRefreshInflight = null;
|
let enterRefreshInflight = null;
|
||||||
const hasEnteredOnce = ref(false);
|
const hasEnteredOnce = ref(false);
|
||||||
|
let lastReloadStartedAt = 0;
|
||||||
|
|
||||||
const accountStore = useAccountStore();
|
const accountStore = useAccountStore();
|
||||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||||
@ -852,15 +853,16 @@ function normalizeMedicalType(raw) {
|
|||||||
// 中文兜底(部分接口返回展示名)
|
// 中文兜底(部分接口返回展示名)
|
||||||
if (s.includes('门诊')) return 'outpatient';
|
if (s.includes('门诊')) return 'outpatient';
|
||||||
if (s.includes('住院') || s.includes('入院')) return 'inhospital';
|
if (s.includes('住院') || s.includes('入院')) return 'inhospital';
|
||||||
if (s.includes('预问诊') || s.includes('问诊')) return 'preConsultation';
|
if (s.includes('预问诊') || s.includes('问诊')) return 'preConsultationRecord';
|
||||||
if (s.includes('体检')) return 'physicalExaminationTemplate';
|
if (s.includes('体检')) return 'physicalExaminationTemplate';
|
||||||
if (lower.includes('preconsult') || (lower.includes('pre') && lower.includes('consult'))) return 'preConsultation';
|
if (lower.includes('preconsult') || (lower.includes('pre') && lower.includes('consult'))) return 'preConsultationRecord';
|
||||||
if (lower === 'outpatient' || lower === 'out_patient' || lower === 'out-patient') return 'outpatient';
|
if (lower === 'outpatient' || lower === 'out_patient' || lower === 'out-patient') return 'outpatient';
|
||||||
if (lower === 'inhospital' || lower === 'in_hospital' || lower === 'in-hospital' || lower === 'inpatient') return 'inhospital';
|
if (lower === 'inhospital' || lower === 'in_hospital' || lower === 'in-hospital' || lower === 'inpatient') return 'inhospital';
|
||||||
if (lower === 'physicalexaminationtemplate' || lower === 'physicalexamination' || lower === 'physical_examination') return 'physicalExaminationTemplate';
|
if (lower === 'physicalexaminationtemplate' || lower === 'physicalexamination' || lower === 'physical_examination') return 'physicalExaminationTemplate';
|
||||||
if (s === 'outPatient') return 'outpatient';
|
if (s === 'outPatient') return 'outpatient';
|
||||||
if (s === 'inHospital') return 'inhospital';
|
if (s === 'inHospital') return 'inhospital';
|
||||||
if (s === 'preConsultation') return 'preConsultation';
|
if (s === 'preConsultation') return 'preConsultationRecord';
|
||||||
|
if (s === 'preConsultationRecord') return 'preConsultationRecord';
|
||||||
if (s === 'physicalExaminationTemplate') return 'physicalExaminationTemplate';
|
if (s === 'physicalExaminationTemplate') return 'physicalExaminationTemplate';
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -940,6 +942,7 @@ function resolveLatestRecord(lr) {
|
|||||||
'date',
|
'date',
|
||||||
'visitTime',
|
'visitTime',
|
||||||
'inhosDate',
|
'inhosDate',
|
||||||
|
'consultationDate',
|
||||||
'consultDate',
|
'consultDate',
|
||||||
'inspectDate',
|
'inspectDate',
|
||||||
'sortTime',
|
'sortTime',
|
||||||
@ -951,77 +954,22 @@ function resolveLatestRecord(lr) {
|
|||||||
);
|
);
|
||||||
const rawDateStr = String(rawDate ?? '').trim();
|
const rawDateStr = String(rawDate ?? '').trim();
|
||||||
const date = (/^\d{10,13}$/.test(rawDateStr) ? (formatAnyDate(rawDateStr, 'YYYY-MM-DD') || rawDateStr) : rawDateStr)
|
const date = (/^\d{10,13}$/.test(rawDateStr) ? (formatAnyDate(rawDateStr, 'YYYY-MM-DD') || rawDateStr) : rawDateStr)
|
||||||
|| formatAnyDate(pick('visitTime', 'inhosDate', 'consultDate', 'inspectDate', 'sortTime', 'createTime', 'updateTime'), 'YYYY-MM-DD')
|
|| formatAnyDate(pick('visitTime', 'inhosDate', 'consultationDate', 'consultDate', 'inspectDate', 'sortTime', 'createTime', 'updateTime'), 'YYYY-MM-DD')
|
||||||
|| '-';
|
|| '-';
|
||||||
|
|
||||||
let third = '';
|
let third = '';
|
||||||
// 后端若已计算出统一展示字段 diagnosis,则优先使用
|
// searchCorpCustomerForCaseList 接口存在问题,按类型优先展示:
|
||||||
const directDiagnosis = normalizeText(pick('diagnosis', 'diagnosisName'));
|
// - 预问诊:chiefComplaint
|
||||||
if (String(directDiagnosis || '').trim()) {
|
// - 体检:inspectSummary
|
||||||
third = directDiagnosis;
|
// - 门诊/住院:diagnosisName
|
||||||
} else if (uiType === 'outpatient' || uiType === 'inhospital') {
|
if (uiType === 'outpatient' || uiType === 'inhospital') {
|
||||||
third = normalizeText(pick(
|
third = normalizeText(pick('diagnosisName', 'diagnosis'));
|
||||||
'diagnosisName',
|
|
||||||
'diagnosis',
|
|
||||||
'diagnosisList',
|
|
||||||
'diagnosisNames',
|
|
||||||
'mainDiagnosis',
|
|
||||||
'admissionDiagnosis',
|
|
||||||
'inDiagnosis',
|
|
||||||
'outDiagnosis',
|
|
||||||
'outPatientDiagnosis',
|
|
||||||
'inHospitalDiagnosis'
|
|
||||||
));
|
|
||||||
} else if (uiType === 'preConsultation') {
|
|
||||||
third = normalizeText(
|
|
||||||
pick(
|
|
||||||
'diagnosis',
|
|
||||||
'diagnosisName',
|
|
||||||
'chiefComplaint',
|
|
||||||
'chiefComplain',
|
|
||||||
'chiefComplaintText',
|
|
||||||
'chiefComplaintContent',
|
|
||||||
'complaint',
|
|
||||||
'complaintDesc',
|
|
||||||
'complaintText',
|
|
||||||
'mainComplaint',
|
|
||||||
'mainSuit',
|
|
||||||
'mainSuitText',
|
|
||||||
'mainSuitContent',
|
|
||||||
'chief',
|
|
||||||
'zs',
|
|
||||||
'zhuSu',
|
|
||||||
'cc',
|
|
||||||
'presentIllness',
|
|
||||||
'historyOfPresentIllness',
|
|
||||||
'currentIllness'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else if (uiType === 'physicalExaminationTemplate') {
|
} else if (uiType === 'physicalExaminationTemplate') {
|
||||||
third = normalizeText(
|
third = normalizeText(pick('inspectSummary', 'summary', 'summaryText', 'inspectConclusion', 'inspectResult'));
|
||||||
pick(
|
} else if (uiType === 'preConsultationRecord') {
|
||||||
'diagnosis',
|
third = normalizeText(pick('chiefComplaint', 'chiefComplain', 'chiefComplaintText', 'chiefComplaintContent'));
|
||||||
'diagnosisName',
|
|
||||||
'summary',
|
|
||||||
'summaryText',
|
|
||||||
'inspectSummary',
|
|
||||||
'checkSummary',
|
|
||||||
'examSummary',
|
|
||||||
'physicalSummary',
|
|
||||||
'briefSummary',
|
|
||||||
'resultSummary',
|
|
||||||
'conclusion',
|
|
||||||
'conclusionText',
|
|
||||||
'inspectConclusion',
|
|
||||||
'inspectResult',
|
|
||||||
'finalConclusion',
|
|
||||||
'finalSummary',
|
|
||||||
'reportConclusion',
|
|
||||||
'reportSummary'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
third = normalizeText(pick('diagnosis', 'diagnosisName', 'summary', 'chiefComplaint'));
|
third = normalizeText(pick('diagnosisName', 'diagnosis', 'inspectSummary', 'summary', 'chiefComplaint'));
|
||||||
}
|
}
|
||||||
third = String(third || '').replace(/\s+/g, ' ').trim();
|
third = String(third || '').replace(/\s+/g, ' ').trim();
|
||||||
if (!third) {
|
if (!third) {
|
||||||
@ -1033,7 +981,7 @@ function resolveLatestRecord(lr) {
|
|||||||
|
|
||||||
const type = typeLabel || (uiType === 'outpatient' ? '门诊记录'
|
const type = typeLabel || (uiType === 'outpatient' ? '门诊记录'
|
||||||
: uiType === 'inhospital' ? '住院记录'
|
: uiType === 'inhospital' ? '住院记录'
|
||||||
: uiType === 'preConsultation' ? '预问诊记录'
|
: uiType === 'preConsultationRecord' ? '预问诊记录'
|
||||||
: uiType === 'physicalExaminationTemplate' ? '体检档案'
|
: uiType === 'physicalExaminationTemplate' ? '体检档案'
|
||||||
: '-');
|
: '-');
|
||||||
|
|
||||||
@ -1217,6 +1165,7 @@ async function reload(reset = true, opts = {}) {
|
|||||||
query.includeRecentAddTime = true;
|
query.includeRecentAddTime = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastReloadStartedAt = Date.now();
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let res;
|
let res;
|
||||||
try {
|
try {
|
||||||
@ -1769,6 +1718,8 @@ onLoad(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
|
const showAt = Date.now();
|
||||||
|
const wasEnteredOnce = hasEnteredOnce.value;
|
||||||
const need = uni.getStorageSync(NEED_RELOAD_STORAGE_KEY);
|
const need = uni.getStorageSync(NEED_RELOAD_STORAGE_KEY);
|
||||||
if (need) {
|
if (need) {
|
||||||
uni.removeStorageSync(NEED_RELOAD_STORAGE_KEY);
|
uni.removeStorageSync(NEED_RELOAD_STORAGE_KEY);
|
||||||
@ -1781,6 +1732,12 @@ onShow(async () => {
|
|||||||
if (needGroups) uni.removeStorageSync(GROUPS_RELOAD_KEY);
|
if (needGroups) uni.removeStorageSync(GROUPS_RELOAD_KEY);
|
||||||
|
|
||||||
await refreshOnEnter();
|
await refreshOnEnter();
|
||||||
|
|
||||||
|
// 避免“复用旧的 inflight 请求”导致回到本页仍然展示旧数据:
|
||||||
|
// 只有在非首次进入且本次 onShow 没有发起新的 reload 时,才补一次 reload。
|
||||||
|
if (wasEnteredOnce && lastReloadStartedAt && lastReloadStartedAt < showAt) {
|
||||||
|
await reload(true, { silent: true, keepOnFail: true });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user