bug362 413 498 504 507
This commit is contained in:
@@ -49,6 +49,40 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 性别、出生日期、或实足年龄 -->
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="7" class="form-item">
|
||||
<span class="form-label required">性别</span>
|
||||
<el-radio-group v-model="form.sex" class="gender-radio-group">
|
||||
<el-radio value="男">男</el-radio>
|
||||
<el-radio value="女">女</el-radio>
|
||||
<el-radio value="未知">未知</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
<el-col :span="10" class="form-item">
|
||||
<span class="form-label required">出生日期</span>
|
||||
<div class="birth-input-group">
|
||||
<el-input v-model="form.birthYear" class="birth-input year" placeholder="年" maxlength="4" />
|
||||
<span class="birth-separator">年</span>
|
||||
<el-input v-model="form.birthMonth" class="birth-input month" placeholder="月" maxlength="2" />
|
||||
<span class="birth-separator">月</span>
|
||||
<el-input v-model="form.birthDay" class="birth-input day" placeholder="日" maxlength="2" />
|
||||
<span class="birth-separator">日</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="7" class="form-item">
|
||||
<span class="form-label">或 实足年龄</span>
|
||||
<div class="age-input-group">
|
||||
<el-input v-model="form.age" class="age-input" placeholder="年龄" />
|
||||
<el-select v-model="form.ageUnit" class="age-unit-select">
|
||||
<el-option label="岁" value="岁" />
|
||||
<el-option label="月" value="月" />
|
||||
<el-option label="天" value="天" />
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 联系电话、紧急联系人电话 -->
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="12" class="form-item">
|
||||
@@ -1992,4 +2026,53 @@ defineExpose({ show, showReport, close: handleClose });
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
}
|
||||
|
||||
/* 性别单选按钮组 */
|
||||
.gender-radio-group {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
/* 出生日期输入组 */
|
||||
.birth-input-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.birth-input {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.birth-input.year {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.birth-input.month,
|
||||
.birth-input.day {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.birth-separator {
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
/* 年龄输入组 */
|
||||
.age-input-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.age-input {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.age-unit-select {
|
||||
width: 65px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -92,45 +92,42 @@
|
||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||
<el-table-column label="申请单状态" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ parseStatus(scope.row.status) }}</span>
|
||||
<el-tag :type="getStatusTagType(scope.row.status)" effect="plain" round>
|
||||
{{ parseStatus(scope.row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right">
|
||||
<template #default="scope">
|
||||
<!-- 待签发:详情、修改、删除 -->
|
||||
<!-- 详情 - 所有状态都显示 -->
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
<!-- 待签发:修改、删除 -->
|
||||
<template v-if="scope.row.status === '0' || scope.row.status === 0">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
<el-button link type="primary" @click="handleModify(scope.row)">修改</el-button>
|
||||
<el-button link type="primary" @click="handleEdit(scope.row)">修改</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
<!-- 已签发:详情、撤回 -->
|
||||
<!-- 已签发:撤回 -->
|
||||
<template v-else-if="scope.row.status === '1' || scope.row.status === 1">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
<el-button link type="warning" @click="handleWithdraw(scope.row)">撤回</el-button>
|
||||
<el-button link type="warning" @click="handleRecall(scope.row)">撤回</el-button>
|
||||
</template>
|
||||
<!-- 已校对/待接收:详情、打印 -->
|
||||
<!-- 已校对/待接收:打印 -->
|
||||
<template v-else-if="scope.row.status === '2' || scope.row.status === 2 || scope.row.status === '3' || scope.row.status === 3">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
<el-button link type="primary" @click="handlePrint(scope.row)">打印</el-button>
|
||||
</template>
|
||||
<!-- 已接收/已检查:详情、看报告 -->
|
||||
<!-- 已接收/已检查:看报告 -->
|
||||
<template v-else-if="scope.row.status === '4' || scope.row.status === 4 || scope.row.status === '5' || scope.row.status === 5">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
<el-button link type="success" @click="handleViewReport(scope.row)">看报告</el-button>
|
||||
</template>
|
||||
<!-- 已出报告:详情、打印、看报告 -->
|
||||
<!-- 已出报告:打印、看报告 -->
|
||||
<template v-else-if="scope.row.status === '6' || scope.row.status === 6">
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
<el-button link type="primary" @click="handlePrint(scope.row)">打印</el-button>
|
||||
<el-button link type="success" @click="handleViewReport(scope.row)">看报告</el-button>
|
||||
</template>
|
||||
<!-- 已作废:详情 -->
|
||||
<!-- 已作废:无额外按钮 -->
|
||||
<template v-else-if="scope.row.status === '7' || scope.row.status === 7">
|
||||
<el-button link type="info" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
<!-- 其他/未知状态:仅详情 -->
|
||||
<template v-else>
|
||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -203,15 +200,102 @@
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 修改申请单弹窗 - 复用检查申请单组件 -->
|
||||
<el-dialog
|
||||
v-model="editDialogVisible"
|
||||
title="修改检查申请"
|
||||
width="1200px"
|
||||
destroy-on-close
|
||||
top="5vh"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<MedicalExaminations
|
||||
v-if="editDialogVisible"
|
||||
ref="editFormRef"
|
||||
:is-edit-mode="true"
|
||||
:edit-data="editingRow"
|
||||
:external-patient-info="patientInfo"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="editDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleEditSubmit">确认</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 查看报告弹窗 -->
|
||||
<el-dialog
|
||||
v-model="reportDialogVisible"
|
||||
:title="'检查报告 - ' + (reportData?.prescriptionNo || '')"
|
||||
width="900px"
|
||||
destroy-on-close
|
||||
top="5vh"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div v-loading="reportLoading" class="report-viewer">
|
||||
<!-- 报告基本信息 -->
|
||||
<div v-if="reportData" class="report-viewer-container">
|
||||
<el-descriptions title="报告信息" :column="2" border size="small">
|
||||
<el-descriptions-item label="患者姓名">{{ reportData.patientName || reportRow?.patientName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单号">{{ reportData.prescriptionNo || reportRow?.prescriptionNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请单名称">{{ reportData.name || reportRow?.name || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="报告时间">{{ reportData.reportTime || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="诊断意见" :span="2">{{ reportData.diagnosis || reportData.conclusion || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<!-- 报告详细内容 -->
|
||||
<div v-if="reportData.content" class="report-content-section">
|
||||
<div class="section-title">报告内容</div>
|
||||
<div class="report-content-text">{{ reportData.content }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 影像预览 - PACS链接 -->
|
||||
<div v-if="reportData.imageUrl || reportData.pacsUrl" class="report-image-section">
|
||||
<div class="section-title">
|
||||
影像预览
|
||||
<el-button
|
||||
v-if="reportData.imageUrl || reportData.pacsUrl"
|
||||
type="primary"
|
||||
size="small"
|
||||
plain
|
||||
style="margin-left: 12px;"
|
||||
@click="openPacsLink"
|
||||
>
|
||||
<el-icon><Link /></el-icon>
|
||||
打开PACS影像
|
||||
</el-button>
|
||||
</div>
|
||||
<iframe
|
||||
v-if="reportData.imageUrl"
|
||||
:src="reportData.imageUrl"
|
||||
class="report-iframe"
|
||||
frameborder="0"
|
||||
/>
|
||||
<el-empty v-else-if="!reportData.imageUrl && reportData.pacsUrl" description="点击上方按钮打开PACS影像" :image-size="60" />
|
||||
</div>
|
||||
|
||||
<!-- 完全无数据时的提示 -->
|
||||
<el-empty v-if="!reportData.content && !reportData.imageUrl && !reportData.pacsUrl" description="暂无详细报告数据" :image-size="60" />
|
||||
</div>
|
||||
|
||||
<!-- 未获取到报告 -->
|
||||
<el-empty v-else description="暂未生成报告" :image-size="80" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="reportDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {computed, getCurrentInstance, ref, watch} from 'vue';
|
||||
import {Refresh, Search} from '@element-plus/icons-vue';
|
||||
import {computed, getCurrentInstance, ref, watch, nextTick} from 'vue';
|
||||
import {Refresh, Search, Link} from '@element-plus/icons-vue';
|
||||
import {patientInfo} from '../../store/patient.js';
|
||||
import {getCheck, deleteRequestForm, withdrawRequestForm, getTestResult} from './api';
|
||||
import {getDepartmentList} from '@/api/public.js';
|
||||
import {getApplicationList, saveCheckd} from '../order/applicationForm/api';
|
||||
import MedicalExaminations from '../order/applicationForm/medicalExaminations.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -221,6 +305,24 @@ const detailDialogVisible = ref(false);
|
||||
const currentDetail = ref(null);
|
||||
const descJsonData = ref(null);
|
||||
const orgOptions = ref([]);
|
||||
const editForm = ref({
|
||||
name: '',
|
||||
targetDepartment: '',
|
||||
symptom: '',
|
||||
sign: '',
|
||||
clinicalDiagnosis: '',
|
||||
otherDiagnosis: '',
|
||||
relatedResult: '',
|
||||
attention: '',
|
||||
examinationPurpose: '',
|
||||
medicalHistorySummary: '',
|
||||
});
|
||||
|
||||
// 报告弹窗相关
|
||||
const reportDialogVisible = ref(false);
|
||||
const reportLoading = ref(false);
|
||||
const reportData = ref(null);
|
||||
const reportRow = ref(null);
|
||||
|
||||
// 获取近7天的日期范围作为默认值
|
||||
const getDefaultDateRange = () => {
|
||||
@@ -268,7 +370,9 @@ const fetchData = async () => {
|
||||
if (res.code === 200 && res.data) {
|
||||
const raw = res.data?.records || res.data;
|
||||
const list = Array.isArray(raw) ? raw : [raw];
|
||||
console.log('API返回的原始数据:', JSON.stringify(list, null, 2));
|
||||
tableData.value = list.filter(Boolean);
|
||||
console.log('tableData设置后的第一条:', tableData.value[0]);
|
||||
} else {
|
||||
tableData.value = [];
|
||||
}
|
||||
@@ -325,6 +429,25 @@ const parseStatus = (status) => {
|
||||
return statusMap[String(status)] || '-';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取状态标签类型 - 参考临床医嘱样式
|
||||
* @param {string|number} status - 状态码
|
||||
* @returns {string} el-tag type
|
||||
*/
|
||||
const getStatusTagType = (status) => {
|
||||
const typeMap = {
|
||||
'0': 'primary', // 待签发 - 蓝色
|
||||
'1': 'success', // 已签发 - 绿色
|
||||
'2': 'success', // 已校对 - 绿色
|
||||
'3': 'primary', // 待接收 - 蓝色
|
||||
'4': 'primary', // 已接收 - 蓝色
|
||||
'5': 'success', // 已检查 - 绿色
|
||||
'6': 'success', // 已出报告 - 绿色
|
||||
'7': 'danger', // 已作废 - 红色
|
||||
};
|
||||
return typeMap[String(status)] || 'info';
|
||||
};
|
||||
|
||||
const labelMap = {
|
||||
categoryType: '项目类别',
|
||||
targetDepartment: '发往科室',
|
||||
@@ -418,87 +541,391 @@ const handleViewDetail = async (row) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改申请单(仅待签发状态)
|
||||
* 删除申请单 - 仅待签发状态可用
|
||||
*/
|
||||
const handleModify = (row) => {
|
||||
proxy.$modal?.msgWarning?.('修改功能需后端支持,请联系管理员');
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除申请单(仅待签发状态)
|
||||
*/
|
||||
const handleDelete = (row) => {
|
||||
proxy.$confirm?.('确认删除该检查申请单吗?删除后不可恢复。', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
try {
|
||||
const res = await deleteRequestForm({ requestFormId: row.requestFormId || row.id });
|
||||
if (res?.code === 200) {
|
||||
proxy.$modal?.msgSuccess?.('删除成功');
|
||||
await fetchData();
|
||||
} else {
|
||||
proxy.$modal?.msgError?.(res?.msg || '删除失败');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('删除申请单失败(可能后端未实现):', e.message);
|
||||
proxy.$modal?.msgError?.('删除失败,后端服务可能未支持此功能');
|
||||
}
|
||||
}).catch(() => {});
|
||||
};
|
||||
|
||||
/**
|
||||
* 撤回申请单(已签发状态撤回至待签发)
|
||||
*/
|
||||
const handleWithdraw = (row) => {
|
||||
proxy.$confirm?.('确认撤回该检查申请单吗?撤回后状态将变为待签发。', '撤回确认', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(async () => {
|
||||
try {
|
||||
const res = await withdrawRequestForm({ requestFormId: row.requestFormId || row.id });
|
||||
if (res?.code === 200) {
|
||||
proxy.$modal?.msgSuccess?.('撤回成功');
|
||||
await fetchData();
|
||||
} else {
|
||||
proxy.$modal?.msgError?.(res?.msg || '撤回失败');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('撤回申请单失败(可能后端未实现):', e.message);
|
||||
proxy.$modal?.msgError?.('撤回失败,后端服务可能未支持此功能');
|
||||
}
|
||||
}).catch(() => {});
|
||||
};
|
||||
|
||||
/**
|
||||
* 打印申请单
|
||||
*/
|
||||
const handlePrint = (row) => {
|
||||
// 使用浏览器原生打印功能
|
||||
window.print();
|
||||
};
|
||||
|
||||
/**
|
||||
* 查看检查报告
|
||||
*/
|
||||
const handleViewReport = async (row) => {
|
||||
const handleDelete = async (row) => {
|
||||
try {
|
||||
const res = await getTestResult({ encounterId: row.encounterId || patientInfo.value?.encounterId });
|
||||
if (res?.code === 200 && res.data) {
|
||||
const reportUrl = Array.isArray(res.data) ? res.data[0]?.reportUrl : res.data?.reportUrl;
|
||||
if (reportUrl) {
|
||||
window.open(reportUrl, '_blank');
|
||||
} else {
|
||||
proxy.$modal?.msgWarning?.('暂无检查报告');
|
||||
}
|
||||
await proxy.$modal?.confirm?.('确认删除该检查申请单?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
const res = await deleteRequestForm({ requestFormId: row.requestFormId });
|
||||
if (res.code === 200) {
|
||||
proxy.$modal?.msgSuccess?.('删除成功');
|
||||
fetchData();
|
||||
} else {
|
||||
proxy.$modal?.msgWarning?.('暂无检查报告');
|
||||
proxy.$modal?.msgError?.(res.msg || '删除失败');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('查看检查报告失败:', e.message);
|
||||
proxy.$modal?.msgError?.('获取检查报告失败');
|
||||
// 用户取消操作,不做处理
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 撤回申请单 - 仅已签发状态可用
|
||||
*/
|
||||
const handleRecall = async (row) => {
|
||||
try {
|
||||
await proxy.$modal?.confirm?.('确认撤回该申请单?撤回后状态将变更为"待签发"。', '提示', {
|
||||
confirmButtonText: '确定撤回',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
const res = await withdrawRequestForm({ requestFormId: row.requestFormId });
|
||||
if (res.code === 200) {
|
||||
proxy.$modal?.msgSuccess?.('撤回成功');
|
||||
fetchData();
|
||||
} else {
|
||||
proxy.$modal?.msgError?.(res.msg || '撤回失败');
|
||||
}
|
||||
} catch (e) {
|
||||
// 用户取消操作,不做处理
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 打印申请单 - 已校对/待接收/已接收/已检查状态可用
|
||||
* 打印内容与详情展示一致,并包含申请单条码
|
||||
*/
|
||||
const handlePrint = async (row) => {
|
||||
try {
|
||||
proxy.$modal?.msgInfo?.('正在生成打印预览...');
|
||||
|
||||
// 确保科室数据已加载,用于解析发往科室名称
|
||||
if (!orgOptions.value || orgOptions.value.length === 0) {
|
||||
await new Promise((resolve) => {
|
||||
getDepartmentList().then((res) => {
|
||||
orgOptions.value = res.data || [];
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 解析 descJson
|
||||
let descData = {};
|
||||
if (row.descJson) {
|
||||
try {
|
||||
const obj = JSON.parse(row.descJson);
|
||||
// 将发往科室ID转换为名称
|
||||
if (obj.targetDepartment) {
|
||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||
}
|
||||
descData = obj;
|
||||
} catch (e) {
|
||||
console.error('解析 descJson 失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建诊疗项目表格行
|
||||
let detailRowsHtml = '';
|
||||
const detailList = row.requestFormDetailList || [];
|
||||
if (detailList.length > 0) {
|
||||
detailList.forEach((item, index) => {
|
||||
detailRowsHtml += `
|
||||
<tr>
|
||||
<td style="text-align:center;padding:6px 8px;border:1px solid #ddd;">${index + 1}</td>
|
||||
<td style="padding:6px 8px;border:1px solid #ddd;">${item.adviceName || '-'}</td>
|
||||
<td style="text-align:center;padding:6px 8px;border:1px solid #ddd;">${item.quantity || '-'}</td>
|
||||
<td style="padding:6px 8px;border:1px solid #ddd;">${item.unitCode_dictText || '-'}</td>
|
||||
<td style="text-align:right;padding:6px 8px;border:1px solid #ddd;">${item.totalPrice != null ? '¥' + Number(item.totalPrice).toFixed(2) : '-'}</td>
|
||||
</tr>`;
|
||||
});
|
||||
}
|
||||
|
||||
// 构建 descJson 字段行(与详情弹窗展示的字段一致)
|
||||
const fieldKeys = ['targetDepartment', 'symptom', 'sign', 'clinicalDiagnosis', 'otherDiagnosis', 'relatedResult', 'attention'];
|
||||
let descFieldsHtml = '';
|
||||
fieldKeys.forEach((key) => {
|
||||
const label = labelMap[key] || key;
|
||||
if (descData[key] != null && descData[key] !== '') {
|
||||
descFieldsHtml += `
|
||||
<div class="info-row">
|
||||
<span class="label">${label}:</span>
|
||||
<span class="value">${descData[key]}</span>
|
||||
</div>`;
|
||||
}
|
||||
});
|
||||
|
||||
// 构建完整打印HTML
|
||||
const printContent = `
|
||||
<div class="print-wrapper">
|
||||
<!-- 标题 -->
|
||||
<div class="print-header">
|
||||
<div class="print-title">检查申请单</div>
|
||||
<div class="print-meta">打印时间:${new Date().toLocaleString()}</div>
|
||||
</div>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<div class="print-section">
|
||||
<div class="section-title">基本信息</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-row"><span class="label">患者姓名:</span><span class="value">${row.patientName || '-'}</span></div>
|
||||
<div class="info-row"><span class="label">申请单名称:</span><span class="value">${row.name || '-'}</span></div>
|
||||
<div class="info-row"><span class="label">申请单状态:</span><span class="value">${parseStatus(row.status)}</span></div>
|
||||
<div class="info-row"><span class="label">创建时间:</span><span class="value">${row.createTime || '-'}</span></div>
|
||||
<div class="info-row"><span class="label">申请单号:</span><span class="value">${row.prescriptionNo || '-'}</span></div>
|
||||
<div class="info-row"><span class="label">申请者:</span><span class="value">${row.requesterId_dictText || '-'}</span></div>
|
||||
<div class="info-row"><span class="label">就诊ID:</span><span class="value">${row.encounterId || '-'}</span></div>
|
||||
<div class="info-row"><span class="label">申请单ID:</span><span class="value">${row.requestFormId || '-'}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${descFieldsHtml ? `
|
||||
<!-- 申请单描述 -->
|
||||
<div class="print-section">
|
||||
<div class="section-title">申请单描述</div>
|
||||
${descFieldsHtml}
|
||||
</div>` : ''}
|
||||
|
||||
${detailRowsHtml ? `
|
||||
<!-- 诊疗项目 -->
|
||||
<div class="print-section">
|
||||
<div class="section-title">诊疗项目</div>
|
||||
<table class="detail-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:50px;padding:8px;border:1px solid #ddd;background:#f5f7fa;text-align:center;">序号</th>
|
||||
<th style="padding:8px;border:1px solid #ddd;background:#f5f7fa;text-align:left;">医嘱名称</th>
|
||||
<th style="width:60px;padding:8px;border:1px solid #ddd;background:#f5f7fa;text-align:center;">数量</th>
|
||||
<th style="width:60px;padding:8px;border:1px solid #ddd;background:#f5f7fa;text-align:center;">单位</th>
|
||||
<th style="width:80px;padding:8px;border:1px solid #ddd;background:#f5f7fa;text-align:right;">总价</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>${detailRowsHtml}</tbody>
|
||||
</table>
|
||||
</div>` : ''}
|
||||
|
||||
<!-- 条码区 -->
|
||||
<div class="barcode-section">
|
||||
<div class="barcode-container">
|
||||
<div class="barcode-number">${row.prescriptionNo || ''}</div>
|
||||
<div class="barcode-label">申请单号 / 扫码核验</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="print-footer">
|
||||
<div class="footer-line">本申请单仅供院内使用,请勿外传</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// 打开新窗口打印
|
||||
const printWindow = window.open('', '_blank');
|
||||
if (!printWindow) {
|
||||
proxy.$modal?.msgError?.('无法打开打印窗口,请检查浏览器弹窗设置');
|
||||
return;
|
||||
}
|
||||
|
||||
printWindow.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>检查申请单 - 打印</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
padding: 20px;
|
||||
}
|
||||
.print-wrapper {
|
||||
max-width: 210mm;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.print-header {
|
||||
text-align: center;
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 2px solid #333;
|
||||
}
|
||||
.print-title {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.print-meta {
|
||||
font-size: 11px;
|
||||
color: #666;
|
||||
}
|
||||
.print-section {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 6px 16px;
|
||||
}
|
||||
.info-row {
|
||||
font-size: 12px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
.info-row .label {
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
}
|
||||
.info-row .value {
|
||||
color: #333;
|
||||
}
|
||||
.detail-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.detail-table th {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
}
|
||||
.detail-table td {
|
||||
font-size: 12px;
|
||||
}
|
||||
.barcode-section {
|
||||
margin-top: 24px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px dashed #ccc;
|
||||
text-align: center;
|
||||
}
|
||||
.barcode-container {
|
||||
display: inline-block;
|
||||
padding: 12px 24px;
|
||||
border: 2px solid #333;
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
}
|
||||
.barcode-number {
|
||||
font-family: 'Libre Barcode 128', 'Libre Barcode 39', 'Code128', 'C', monospace;
|
||||
font-size: 42px;
|
||||
letter-spacing: 4px;
|
||||
color: #000;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.barcode-label {
|
||||
font-size: 10px;
|
||||
color: #888;
|
||||
margin-top: 4px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.print-footer {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-line {
|
||||
font-size: 10px;
|
||||
color: #aaa;
|
||||
}
|
||||
@media print {
|
||||
body { padding: 0; }
|
||||
.print-wrapper { max-width: none; }
|
||||
.barcode-section { page-break-inside: avoid; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${printContent}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
|
||||
printWindow.document.close();
|
||||
// 等待内容渲染后打印
|
||||
printWindow.onload = function() {
|
||||
setTimeout(() => {
|
||||
printWindow.print();
|
||||
proxy.$modal?.closeAll?.();
|
||||
}, 300);
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('打印失败:', error);
|
||||
proxy.$modal?.msgError?.('打印失败: ' + (error.message || '未知错误'));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 查看报告 - 仅已出报告状态可用
|
||||
* 调用报告查询接口,弹窗展示结构化报告或影像预览(PACS链接)
|
||||
*/
|
||||
const handleViewReport = async (row) => {
|
||||
reportRow.value = row;
|
||||
reportDialogVisible.value = true;
|
||||
reportLoading.value = true;
|
||||
reportData.value = null;
|
||||
try {
|
||||
const res = await getTestResult({ prescriptionNo: row.prescriptionNo });
|
||||
if (res.code === 200) {
|
||||
if (res.data) {
|
||||
// 支持两种返回格式:
|
||||
// 1. res.data 为对象(结构化报告):含 patientName, prescriptionNo, reportTime, diagnosis/content, imageUrl/pacsUrl
|
||||
// 2. res.data 为字符串(报告URL):映射到 imageUrl 以支持iframe预览
|
||||
if (typeof res.data === 'string') {
|
||||
reportData.value = {
|
||||
prescriptionNo: row.prescriptionNo,
|
||||
imageUrl: res.data,
|
||||
};
|
||||
} else if (typeof res.data === 'object') {
|
||||
reportData.value = {
|
||||
...res.data,
|
||||
prescriptionNo: res.data.prescriptionNo || row.prescriptionNo,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
reportData.value = null;
|
||||
}
|
||||
} else {
|
||||
reportData.value = null;
|
||||
proxy.$modal?.msgWarning?.(res.msg || '暂未生成报告');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取报告失败:', e);
|
||||
reportData.value = null;
|
||||
proxy.$modal?.msgError?.('获取报告失败');
|
||||
} finally {
|
||||
reportLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 打开PACS影像链接
|
||||
*/
|
||||
const openPacsLink = () => {
|
||||
const url = reportData.value?.pacsUrl || reportData.value?.imageUrl;
|
||||
if (url) {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
};
|
||||
|
||||
// ========== 修改申请单相关 ==========
|
||||
const editDialogVisible = ref(false);
|
||||
const editFormRef = ref(null);
|
||||
const editingRow = ref(null);
|
||||
|
||||
// 修改申请单 - 复用检查申请单弹窗
|
||||
const handleEdit = (row) => {
|
||||
editingRow.value = { ...row };
|
||||
editDialogVisible.value = true;
|
||||
// 弹窗打开后,手动调用getList确保数据加载
|
||||
nextTick(() => {
|
||||
editFormRef.value?.getList?.();
|
||||
editFormRef.value?.getLocationInfo?.();
|
||||
editFormRef.value?.getDiagnosisList?.();
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑弹窗确认提交
|
||||
const handleEditSubmit = () => {
|
||||
// 调用MedicalExaminations组件的submit方法
|
||||
if (editFormRef.value?.submit) {
|
||||
editFormRef.value.submit();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -626,4 +1053,96 @@ defineExpose({
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// 报告弹窗样式
|
||||
.report-viewer {
|
||||
min-height: 200px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.report-viewer-container {
|
||||
.report-content-section {
|
||||
margin-top: 16px;
|
||||
padding: 12px;
|
||||
background: #fafafa;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #eee;
|
||||
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.report-content-text {
|
||||
font-size: 13px;
|
||||
line-height: 1.8;
|
||||
color: #606266;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.report-image-section {
|
||||
margin-top: 16px;
|
||||
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.report-iframe {
|
||||
width: 100%;
|
||||
height: 480px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 状态标签样式 - 参考临床医嘱
|
||||
:deep(.el-tag) {
|
||||
border-radius: 2px;
|
||||
padding: 0 8px;
|
||||
height: 24px;
|
||||
line-height: 22px;
|
||||
font-size: 12px;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
:deep(.el-tag--info.is-plain) {
|
||||
background: #f4f4f5;
|
||||
border-color: #e9e9eb;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
:deep(.el-tag--primary.is-plain) {
|
||||
background: #ecf5ff;
|
||||
border-color: #d9ecff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-tag--success.is-plain) {
|
||||
background: #f0f9eb;
|
||||
border-color: #e1f3d8;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
:deep(.el-tag--warning.is-plain) {
|
||||
background: #fdf6ec;
|
||||
border-color: #faecd8;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
:deep(.el-tag--danger.is-plain) {
|
||||
background: #fef0f0;
|
||||
border-color: #fde2e2;
|
||||
color: #f56c6c;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -249,7 +249,7 @@ const submit = () => {
|
||||
requestFormId: '', // 申请单ID
|
||||
name: '输血申请单',
|
||||
descJson: JSON.stringify(form),
|
||||
categoryEnum: '3', // 1 检验 2 检查 3 输血 4 手术
|
||||
categoryEnum: '23', // 21 检验 22 检查 23 输血 24 手术(避开 adviceType 1-6 碰撞)
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy.$message.success(res.msg);
|
||||
|
||||
@@ -316,7 +316,7 @@ const submit = () => {
|
||||
requestFormId: '', // 申请单ID
|
||||
name: '检验申请单',
|
||||
descJson: JSON.stringify(form),
|
||||
categoryEnum: '1', // 1 检验 2 检查 3 输血 4 手术
|
||||
categoryEnum: '21', // 21 检验 22 检查 23 输血 24 手术(避开 adviceType 1-6 碰撞)
|
||||
};
|
||||
saveInspection(params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
|
||||
@@ -227,7 +227,7 @@
|
||||
</template>
|
||||
|
||||
<script setup name="MedicalExaminations">
|
||||
import {getCurrentInstance, onMounted, reactive, ref, watch, computed} from 'vue';
|
||||
import {getCurrentInstance, onMounted, reactive, ref, watch, computed, nextTick} from 'vue';
|
||||
import {patientInfo} from '../../../store/patient.js';
|
||||
import {getDepartmentList} from '@/api/public.js';
|
||||
import {getEncounterDiagnosis} from '../../api.js';
|
||||
@@ -251,7 +251,26 @@ const findTreeItem = (list, id) => {
|
||||
};
|
||||
|
||||
const emits = defineEmits(['submitOk']);
|
||||
const props = defineProps({});
|
||||
const props = defineProps({
|
||||
isEditMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
editData: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
// 支持通过props传入patientInfo
|
||||
externalPatientInfo: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
// 优先使用外部传入的patientInfo,否则使用store中的
|
||||
const effectivePatientInfo = computed(() => {
|
||||
return props.externalPatientInfo || patientInfo.value;
|
||||
});
|
||||
const orgOptions = ref([]);
|
||||
const state = reactive({});
|
||||
const applicationListAll = ref();
|
||||
@@ -272,7 +291,9 @@ const isSevereAllergy = computed(() => {
|
||||
});
|
||||
|
||||
const getList = () => {
|
||||
if (!patientInfo.value?.inHospitalOrgId) {
|
||||
console.log('getList called, effectivePatientInfo:', effectivePatientInfo.value);
|
||||
if (!effectivePatientInfo.value?.inHospitalOrgId) {
|
||||
console.log('inHospitalOrgId is missing, setting empty list');
|
||||
applicationList.value = [];
|
||||
return;
|
||||
}
|
||||
@@ -281,7 +302,7 @@ const getList = () => {
|
||||
pageSize: 500,
|
||||
pageNum: 1,
|
||||
categoryCode: '23',
|
||||
organizationId: patientInfo.value.inHospitalOrgId,
|
||||
organizationId: effectivePatientInfo.value.inHospitalOrgId,
|
||||
adviceTypes: [3],
|
||||
})
|
||||
.then((res) => {
|
||||
@@ -298,6 +319,24 @@ const getList = () => {
|
||||
key: item.adviceDefinitionId,
|
||||
};
|
||||
});
|
||||
// 编辑模式下,加载完数据后设置已选项目
|
||||
if (props.isEditMode && props.editData?.requestFormDetailList?.length) {
|
||||
nextTick(() => {
|
||||
// 使用 adviceName 匹配
|
||||
const selectedNames = props.editData.requestFormDetailList.map(item => item.adviceName);
|
||||
console.log('getList completed, selectedNames:', selectedNames);
|
||||
const selectedIds = [];
|
||||
applicationList.value?.forEach(app => {
|
||||
// 匹配时去掉价格部分,只比较名称
|
||||
const appName = app.label?.split(' (')[0];
|
||||
if (selectedNames.includes(appName)) {
|
||||
selectedIds.push(app.key);
|
||||
}
|
||||
});
|
||||
console.log('getList completed, matched selectedIds:', selectedIds);
|
||||
transferValue.value = selectedIds;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
proxy.$message.error(res.message);
|
||||
applicationList.value = [];
|
||||
@@ -387,12 +426,65 @@ const handleSyncHistory = async () => {
|
||||
|
||||
// 自动带入患者过敏史
|
||||
const loadPatientAllergyHistory = () => {
|
||||
if (!patientInfo.value?.patientId) return;
|
||||
if (!effectivePatientInfo.value?.patientId) return;
|
||||
};
|
||||
|
||||
// 加载编辑数据
|
||||
const loadEditData = () => {
|
||||
if (!props.isEditMode || !props.editData?.requestFormId) return;
|
||||
|
||||
console.log('loadEditData called, editData:', props.editData);
|
||||
|
||||
// 解析已有的descJson填充表单
|
||||
if (props.editData.descJson) {
|
||||
try {
|
||||
const obj = JSON.parse(props.editData.descJson);
|
||||
form.targetDepartment = obj.targetDepartment || '';
|
||||
form.urgencyLevel = obj.urgencyLevel || 'routine';
|
||||
form.allergyHistory = obj.allergyHistory || '';
|
||||
form.examinationPurpose = obj.examinationPurpose || '';
|
||||
form.medicalHistorySummary = obj.medicalHistorySummary || '';
|
||||
form.expectedExaminationTime = obj.expectedExaminationTime || '';
|
||||
form.symptom = obj.symptom || '';
|
||||
form.sign = obj.sign || '';
|
||||
form.clinicalDiagnosis = obj.clinicalDiagnosis || '';
|
||||
form.otherDiagnosis = obj.otherDiagnosis || '';
|
||||
form.relatedResult = obj.relatedResult || '';
|
||||
form.attention = obj.attention || '';
|
||||
form.allergyConfirmed = obj.allergyConfirmed || false;
|
||||
} catch (e) {
|
||||
console.error('解析descJson失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置已选项目(从requestFormDetailList获取)
|
||||
// 注意:后端返回的字段是 adviceName,不是 adviceDefinitionId
|
||||
console.log('requestFormDetailList:', props.editData.requestFormDetailList);
|
||||
if (props.editData.requestFormDetailList && props.editData.requestFormDetailList.length) {
|
||||
// 使用 adviceName 匹配
|
||||
const selectedNames = props.editData.requestFormDetailList.map(item => item.adviceName);
|
||||
console.log('setting transferValue by adviceName to:', selectedNames);
|
||||
// 通过名称匹配找到对应的 key
|
||||
const selectedIds = [];
|
||||
applicationList.value?.forEach(app => {
|
||||
if (selectedNames.includes(app.label?.split(' (')[0])) {
|
||||
selectedIds.push(app.key);
|
||||
}
|
||||
});
|
||||
console.log('matched selectedIds:', selectedIds);
|
||||
transferValue.value = selectedIds;
|
||||
} else {
|
||||
console.log('requestFormDetailList is empty or undefined');
|
||||
}
|
||||
};
|
||||
|
||||
const projectWithDepartment = (selectProjectIds, type) => {
|
||||
let isRelease = true;
|
||||
const arr = [];
|
||||
// 确保 applicationList 存在
|
||||
if (!applicationList.value || !Array.isArray(applicationList.value)) {
|
||||
return true;
|
||||
}
|
||||
selectProjectIds.forEach((element) => {
|
||||
const searchData = applicationList.value.find((item) => {
|
||||
return element == item.adviceDefinitionId;
|
||||
@@ -429,9 +521,28 @@ const projectWithDepartment = (selectProjectIds, type) => {
|
||||
};
|
||||
|
||||
watch(() => transferValue.value, (newValue) => {
|
||||
console.log('transferValue changed:', newValue);
|
||||
console.log('applicationList length:', applicationList.value?.length);
|
||||
projectWithDepartment(newValue, 1);
|
||||
});
|
||||
|
||||
// 监听 applicationList 加载完成,重新设置已选项目
|
||||
watch(() => applicationList.value, (newList) => {
|
||||
if (newList && newList.length > 0 && props.isEditMode && props.editData?.requestFormDetailList?.length) {
|
||||
console.log('applicationList loaded, re-setting transferValue');
|
||||
// 使用 adviceName 匹配
|
||||
const selectedNames = props.editData.requestFormDetailList.map(item => item.adviceName);
|
||||
const selectedIds = [];
|
||||
newList.forEach(app => {
|
||||
const appName = app.label?.split(' (')[0];
|
||||
if (selectedNames.includes(appName)) {
|
||||
selectedIds.push(app.key);
|
||||
}
|
||||
});
|
||||
transferValue.value = selectedIds;
|
||||
}
|
||||
});
|
||||
|
||||
const getPriorityCode = () => {
|
||||
return form.urgencyLevel === 'emergency' ? 1 : 0;
|
||||
};
|
||||
@@ -470,28 +581,32 @@ const submit = () => {
|
||||
adviceType: item.adviceType,
|
||||
definitionId: item.priceList[0].definitionId,
|
||||
definitionDetailId: item.priceList[0].definitionDetailId,
|
||||
accountId: patientInfo.value.accountId,
|
||||
accountId: effectivePatientInfo.value.accountId,
|
||||
};
|
||||
});
|
||||
|
||||
const submitForm = { ...form, priorityCode: getPriorityCode() };
|
||||
console.log('提交 descJson:', JSON.stringify(submitForm));
|
||||
|
||||
// 如果是编辑模式,带上requestFormId
|
||||
const requestFormId = props.isEditMode ? props.editData?.requestFormId : '';
|
||||
|
||||
saveCheckd({
|
||||
activityList: applicationListAllFilter,
|
||||
patientId: patientInfo.value.patientId,
|
||||
encounterId: patientInfo.value.encounterId,
|
||||
organizationId: patientInfo.value.inHospitalOrgId,
|
||||
requestFormId: '',
|
||||
name: transferValue.value.map(id => {
|
||||
const item = applicationListAll.value?.find(i => i.adviceDefinitionId === id);
|
||||
return item?.adviceName || '';
|
||||
}).filter(Boolean).join('、'),
|
||||
patientId: effectivePatientInfo.value.patientId,
|
||||
encounterId: effectivePatientInfo.value.encounterId,
|
||||
organizationId: effectivePatientInfo.value.inHospitalOrgId,
|
||||
requestFormId: requestFormId,
|
||||
name: applicationListAllFilter.map(item => item.adviceName).join('、'),
|
||||
descJson: JSON.stringify(submitForm),
|
||||
categoryEnum: '2',
|
||||
categoryEnum: '22',
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy.$message.success(res.msg);
|
||||
if (props.isEditMode) {
|
||||
proxy.$message.success(res.msg || '修改成功');
|
||||
} else {
|
||||
proxy.$message.success(res.msg);
|
||||
}
|
||||
applicationList.value = [];
|
||||
resetForm();
|
||||
emits('submitOk');
|
||||
@@ -527,7 +642,7 @@ const getLocationInfo = () => {
|
||||
};
|
||||
|
||||
function getDiagnosisList() {
|
||||
getEncounterDiagnosis(patientInfo.value.encounterId).then((res) => {
|
||||
getEncounterDiagnosis(effectivePatientInfo.value.encounterId).then((res) => {
|
||||
if (res.code == 200) {
|
||||
const datas = (res.data || []).map((item) => {
|
||||
let obj = { ...item };
|
||||
@@ -548,9 +663,24 @@ onMounted(() => {
|
||||
getList();
|
||||
getLocationInfo();
|
||||
loadPatientAllergyHistory();
|
||||
loadEditData();
|
||||
});
|
||||
|
||||
defineExpose({ state, submit, getLocationInfo, getDiagnosisList, resetForm });
|
||||
// 监听编辑模式变化,重新加载数据
|
||||
watch(
|
||||
() => props.isEditMode,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
nextTick(() => {
|
||||
getList();
|
||||
getLocationInfo();
|
||||
loadEditData();
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
defineExpose({ state, submit, getLocationInfo, getDiagnosisList, resetForm, getList });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -267,7 +267,7 @@ const submit = () => {
|
||||
requestFormId: '', // 申请单ID
|
||||
name: '手术申请单',
|
||||
descJson: JSON.stringify(form),
|
||||
categoryEnum: '4', // 1 检验 2 检查 3 输血 4 手术
|
||||
categoryEnum: '24', // 21 检验 22 检查 23 输血 24 手术(避开 adviceType 1-6 碰撞)
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy.$message.success(res.msg);
|
||||
|
||||
@@ -1225,7 +1225,7 @@ function handleSave() {
|
||||
groupId: item.groupId,
|
||||
uniqueKey: undefined,
|
||||
// 确保 therapyEnum 被正确传递
|
||||
therapyEnum: parsedContent.therapyEnum || item.therapyEnum || '1',
|
||||
therapyEnum: parsedContent?.therapyEnum || item.therapyEnum || '1',
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -519,17 +519,31 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
// 加载科室选项
|
||||
// 加载科室选项(支持树形/扁平两种数据结构)
|
||||
function loadDepartmentOptions() {
|
||||
getOrgList()
|
||||
.then((res) => {
|
||||
if (res.data && res.data.records && res.data.records.length > 0) {
|
||||
const firstRecord = res.data.records[0];
|
||||
// 优先使用 children(树形结构),回退到 records 本身(扁平结构)
|
||||
departmentOptions.value = (firstRecord.children && firstRecord.children.length > 0)
|
||||
? firstRecord.children
|
||||
: res.data.records;
|
||||
if (res.data) {
|
||||
// 尝试从树形结构中取:records[0].children
|
||||
if (res.data.records && res.data.records.length > 0) {
|
||||
if (res.data.records[0].children && res.data.records[0].children.length > 0) {
|
||||
departmentOptions.value = res.data.records[0].children;
|
||||
return;
|
||||
}
|
||||
// 如果 records[0] 有 id 和 name(非树根节点),直接用所有 records
|
||||
if (res.data.records[0].id) {
|
||||
departmentOptions.value = res.data.records;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 兜底:如果 records 不存在或为空,尝试直接使用 data 本身
|
||||
if (Array.isArray(res.data)) {
|
||||
departmentOptions.value = res.data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 所有方式都失败,置空
|
||||
departmentOptions.value = [];
|
||||
})
|
||||
.catch(() => {
|
||||
console.warn('科室列表加载失败(可能无权限)');
|
||||
@@ -593,12 +607,14 @@ function getItemType_Text(type) {
|
||||
}
|
||||
function getUnitCodeOptions(row) {
|
||||
const unitCodes = [
|
||||
{ code: String(row.unitCode), codeText: row.unitCode_dictText },
|
||||
{ code: String(row.minUnitCode), codeText: row.minUnitCode_dictText },
|
||||
].filter(item => item.code);
|
||||
{ code: row.unitCode != null ? String(row.unitCode) : null, codeText: row.unitCode_dictText },
|
||||
{ code: row.minUnitCode != null ? String(row.minUnitCode) : null, codeText: row.minUnitCode_dictText },
|
||||
];
|
||||
// 过滤掉 code 为空的单位选项
|
||||
const validUnitCodes = unitCodes.filter(item => item.code != null && item.code !== '');
|
||||
// 使用 Set 来跟踪已经存在的 code
|
||||
const seenCodes = new Set();
|
||||
const uniqueUnitCodes = unitCodes.filter((item) => {
|
||||
const uniqueUnitCodes = validUnitCodes.filter((item) => {
|
||||
// 如果 Set 中没有这个 code,就保留它,并把它加入 Set
|
||||
if (!seenCodes.has(item.code)) {
|
||||
seenCodes.add(item.code);
|
||||
@@ -667,14 +683,36 @@ function selectChange(row) {
|
||||
defaultUnitCode = String(row.minUnitCode);
|
||||
} else if (row.unitCode) {
|
||||
defaultUnitCode = String(row.unitCode);
|
||||
} else if (row.minUnitCode_dictText) {
|
||||
// 兜底:如果 minUnitCode 为空但字典文本存在,使用文本作为选项值
|
||||
defaultUnitCode = row.minUnitCode_dictText;
|
||||
} else if (row.unitCode_dictText) {
|
||||
defaultUnitCode = row.unitCode_dictText;
|
||||
}
|
||||
// 如果默认单位不在 uniqueUnitCodes 中,添加兜底选项
|
||||
if (defaultUnitCode && !uniqueUnitCodes.some(u => u.code === defaultUnitCode)) {
|
||||
uniqueUnitCodes.push({ code: defaultUnitCode, codeText: defaultUnitCode });
|
||||
}
|
||||
// 设置默认执行科室/位置(统一转为字符串,避免 el-select 类型不匹配)
|
||||
let defaultPositionId = undefined;
|
||||
if (row.adviceType === 3 && departmentOptions.value.length > 0) {
|
||||
// 诊疗:优先使用患者所在科室,否则取第一个科室
|
||||
const patientOrgId = props.patientInfo.organizationId;
|
||||
const matched = departmentOptions.value.find(d => String(d.id) === String(patientOrgId));
|
||||
defaultPositionId = matched ? String(matched.id) : String(departmentOptions.value[0].id);
|
||||
// 诊疗:
|
||||
// 1. 优先使用诊疗目录项目的"所属科室"(row.orgId)
|
||||
// 2. 其次使用患者当前病房科室(patientInfo.organizationId)
|
||||
// 3. 最后取第一个科室
|
||||
const orgIdPriority = [row.orgId, props.patientInfo.organizationId];
|
||||
for (const id of orgIdPriority) {
|
||||
if (id) {
|
||||
const matched = departmentOptions.value.find(d => String(d.id) === String(id));
|
||||
if (matched) {
|
||||
defaultPositionId = String(matched.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!defaultPositionId) {
|
||||
defaultPositionId = String(departmentOptions.value[0].id);
|
||||
}
|
||||
} else if (row.adviceType === 2 && locationOptions.value.length > 0) {
|
||||
// 耗材:默认取第一个药房/耗材房
|
||||
defaultPositionId = String(locationOptions.value[0].value);
|
||||
|
||||
@@ -458,7 +458,9 @@ const loadPatientInfo = () => {
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
);
|
||||
} else {
|
||||
interventionForm.value.startTime = dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss');
|
||||
// 已有患者(entranceType == 1)不自动填充当前时间,避免覆盖历史数据
|
||||
// 新入科患者由后端默认返回当前时间,或由用户手动选择
|
||||
interventionForm.value.startTime = '';
|
||||
}
|
||||
interventionForm.value.height = res.data.height;
|
||||
interventionForm.value.weight = res.data.weight;
|
||||
|
||||
Reference in New Issue
Block a user