Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -135,7 +135,8 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
|
|||||||
BeanUtils.copyProperties(orgLocQueryDto, orgLoc);
|
BeanUtils.copyProperties(orgLocQueryDto, orgLoc);
|
||||||
|
|
||||||
Long activityDefinitionId = orgLoc.getActivityDefinitionId();
|
Long activityDefinitionId = orgLoc.getActivityDefinitionId();
|
||||||
String activityName = activityDefinitionId != null ? activityDefinitionMapper.selectById(activityDefinitionId).getName() : "";
|
String activityName = activityDefinitionId != null
|
||||||
|
? activityDefinitionMapper.selectById(activityDefinitionId).getName() : "";
|
||||||
|
|
||||||
List<OrganizationLocation> organizationLocationList =
|
List<OrganizationLocation> organizationLocationList =
|
||||||
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
||||||
@@ -147,8 +148,8 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
|
|||||||
for (OrganizationLocation organizationLocation : organizationLocationList)
|
for (OrganizationLocation organizationLocation : organizationLocationList)
|
||||||
if (DateTimeUtils.isOverlap(organizationLocation.getStartTime(), organizationLocation.getEndTime(),
|
if (DateTimeUtils.isOverlap(organizationLocation.getStartTime(), organizationLocation.getEndTime(),
|
||||||
orgLoc.getStartTime(), orgLoc.getEndTime())) {
|
orgLoc.getStartTime(), orgLoc.getEndTime())) {
|
||||||
String organizationName =
|
Organization org = organizationService.getById(organizationLocation.getOrganizationId());
|
||||||
organizationService.getById(organizationLocation.getOrganizationId()).getName();
|
String organizationName = org != null ? org.getName() : "未知科室";
|
||||||
return R.fail("当前诊疗:" + activityName + CommonConstants.Common.DASH + orgLoc.getStartTime()
|
return R.fail("当前诊疗:" + activityName + CommonConstants.Common.DASH + orgLoc.getStartTime()
|
||||||
+ CommonConstants.Common.DASH + orgLoc.getEndTime() + "与" + organizationName + "时间冲突");
|
+ CommonConstants.Common.DASH + orgLoc.getEndTime() + "与" + organizationName + "时间冲突");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,13 +95,6 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
prescriptionNo = assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_PSYCHOTROPIC_NO.getPrefix(), 8);
|
prescriptionNo = assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_PSYCHOTROPIC_NO.getPrefix(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 诊疗执行科室配置校验(必须在数据库操作之前执行)
|
|
||||||
List<ActivityOrganizationConfigDto> activityOrganizationConfig =
|
|
||||||
requestFormManageAppMapper.getActivityOrganizationConfig(typeCode);
|
|
||||||
if (activityOrganizationConfig.isEmpty()) {
|
|
||||||
throw new ServiceException("请先配置当前时间段的执行科室");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 当前时间
|
// 当前时间
|
||||||
Date curDate = new Date();
|
Date curDate = new Date();
|
||||||
// 请求类型
|
// 请求类型
|
||||||
@@ -146,6 +139,12 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
// 诊疗集合
|
// 诊疗集合
|
||||||
List<ActivitySaveDto> activityList = requestFormSaveDto.getActivityList();
|
List<ActivitySaveDto> activityList = requestFormSaveDto.getActivityList();
|
||||||
log.info("保存申请单,typeCode={}, activityListSize={}, encounterId={}", typeCode, activityList != null ? activityList.size() : 0, encounterId);
|
log.info("保存申请单,typeCode={}, activityListSize={}, encounterId={}", typeCode, activityList != null ? activityList.size() : 0, encounterId);
|
||||||
|
// 诊疗执行科室配置
|
||||||
|
List<ActivityOrganizationConfigDto> activityOrganizationConfig =
|
||||||
|
requestFormManageAppMapper.getActivityOrganizationConfig(typeCode);
|
||||||
|
if (activityOrganizationConfig.isEmpty()) {
|
||||||
|
throw new ServiceException("请先配置当前时间段的执行科室");
|
||||||
|
}
|
||||||
|
|
||||||
for (ActivitySaveDto activitySaveDto : activityList) {
|
for (ActivitySaveDto activitySaveDto : activityList) {
|
||||||
serviceRequest = new ServiceRequest();
|
serviceRequest = new ServiceRequest();
|
||||||
@@ -435,7 +434,7 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
return new java.util.ArrayList<>(); // 返回空列表而不是查询数据库
|
return new java.util.ArrayList<>(); // 返回空列表而不是查询数据库
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RequestFormQueryDto> requestFormList = requestFormManageAppMapper.getRequestForm(encounterId, typeCode, startDate, endDate, status);
|
List<RequestFormQueryDto> requestFormList = requestFormManageAppMapper.getRequestForm(encounterId, typeCode, startDate, endDate, status, null);
|
||||||
for (RequestFormQueryDto requestFormQueryDto : requestFormList) {
|
for (RequestFormQueryDto requestFormQueryDto : requestFormList) {
|
||||||
// 查询处方详情
|
// 查询处方详情
|
||||||
List<RequestFormDetailQueryDto> requestFormDetail =
|
List<RequestFormDetailQueryDto> requestFormDetail =
|
||||||
|
|||||||
@@ -37,13 +37,15 @@ public interface RequestFormManageAppMapper {
|
|||||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param status 单据状态(可选)
|
* @param status 单据状态(可选)
|
||||||
|
* @param keyword 关键字(可选,申请单号/检查项目名称模糊匹配)
|
||||||
* @return 申请单列表
|
* @return 申请单列表
|
||||||
*/
|
*/
|
||||||
List<RequestFormQueryDto> getRequestForm(@Param("encounterId") Long encounterId,
|
List<RequestFormQueryDto> getRequestForm(@Param("encounterId") Long encounterId,
|
||||||
@Param("typeCode") String typeCode,
|
@Param("typeCode") String typeCode,
|
||||||
@Param("startDate") String startDate,
|
@Param("startDate") String startDate,
|
||||||
@Param("endDate") String endDate,
|
@Param("endDate") String endDate,
|
||||||
@Param("status") String status);
|
@Param("status") String status,
|
||||||
|
@Param("keyword") String keyword);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询申请单详情
|
* 查询申请单详情
|
||||||
|
|||||||
@@ -522,6 +522,7 @@ const categoryList = ref([]); // 原始分类+项目数据
|
|||||||
const dictSearchKey = ref('');
|
const dictSearchKey = ref('');
|
||||||
const activeNames = ref(''); // 当前展开的折叠项
|
const activeNames = ref(''); // 当前展开的折叠项
|
||||||
const categoryLoadingSet = ref(new Set()); // Bug #500: 正在加载方法的分类集合
|
const categoryLoadingSet = ref(new Set()); // Bug #500: 正在加载方法的分类集合
|
||||||
|
const isAnimating = ref(false); // Bug #500: 防止快速切换时折叠动画重叠导致抖动
|
||||||
|
|
||||||
const allMethods = ref([]);
|
const allMethods = ref([]);
|
||||||
|
|
||||||
@@ -669,8 +670,13 @@ async function handleCategoryExpand(cat) {
|
|||||||
categoryLoadingSet.value.delete(cat.typeId);
|
categoryLoadingSet.value.delete(cat.typeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Bug #500: 改为非 async 函数,避免 el-collapse 的 @change 等待异步完成导致抖动
|
// Bug #500: 添加防抖逻辑,快速切换时跳过中间状态的动画,避免高度跳变和白屏闪烁
|
||||||
function handleCollapseChange(activeName) {
|
function handleCollapseChange(activeName) {
|
||||||
|
if (isAnimating.value) return; // 动画进行中,忽略后续点击
|
||||||
|
|
||||||
|
isAnimating.value = true;
|
||||||
|
setTimeout(() => { isAnimating.value = false; }, 300); // 与 CSS 过渡时长一致
|
||||||
|
|
||||||
if (activeName) {
|
if (activeName) {
|
||||||
const cat = filteredCategoryList.value.find(c => c.typeId == activeName);
|
const cat = filteredCategoryList.value.find(c => c.typeId == activeName);
|
||||||
if (cat && (!cat.methods || cat.methods.length === 0)) {
|
if (cat && (!cat.methods || cat.methods.length === 0)) {
|
||||||
@@ -1307,6 +1313,7 @@ defineExpose({ getList });
|
|||||||
.collapse-scroll {
|
.collapse-scroll {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden; /* Bug #500: 防止切换时水平方向溢出导致抖动 */
|
||||||
}
|
}
|
||||||
.empty-hint {
|
.empty-hint {
|
||||||
color: #909399;
|
color: #909399;
|
||||||
@@ -1479,10 +1486,10 @@ defineExpose({ getList });
|
|||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
/* Bug #500: 折叠面板展开/收起动画使用 will-change 优化性能 */
|
/* Bug #500: 折叠面板动画容器,添加 overflow:hidden 防止展开时内容溢出导致闪烁 */
|
||||||
:deep(.el-collapse-item__wrap) {
|
:deep(.el-collapse-item__wrap) {
|
||||||
border: none;
|
border: none;
|
||||||
will-change: height;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
:deep(.el-collapse-item) {
|
:deep(.el-collapse-item) {
|
||||||
transition: margin 0.2s ease;
|
transition: margin 0.2s ease;
|
||||||
|
|||||||
@@ -175,10 +175,9 @@ const hasMatchedFields = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 查询科室 */
|
/** 查询科室 */
|
||||||
const getLocationInfo = () => {
|
const getLocationInfo = async () => {
|
||||||
getOrgList().then((res) => {
|
const res = await getOrgList();
|
||||||
orgOptions.value = res.data.records;
|
orgOptions.value = res.data.records;
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const recursionFun = (targetDepartment) => {
|
const recursionFun = (targetDepartment) => {
|
||||||
@@ -199,7 +198,12 @@ const recursionFun = (targetDepartment) => {
|
|||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleViewDetail = (row) => {
|
const handleViewDetail = async (row) => {
|
||||||
|
// 确保科室数据已加载,以便将 ID 解析为名称
|
||||||
|
if (!orgOptions.value || orgOptions.value.length === 0) {
|
||||||
|
await getLocationInfo();
|
||||||
|
}
|
||||||
|
|
||||||
currentDetail.value = row;
|
currentDetail.value = row;
|
||||||
// 解析 descJson
|
// 解析 descJson
|
||||||
if (row.descJson) {
|
if (row.descJson) {
|
||||||
@@ -220,10 +224,9 @@ const handleViewDetail = (row) => {
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => patientInfo.value?.encounterId,
|
() => patientInfo.value?.encounterId,
|
||||||
(val) => {
|
async (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
fetchData();
|
await Promise.all([fetchData(), getLocationInfo()]);
|
||||||
getLocationInfo();
|
|
||||||
} else {
|
} else {
|
||||||
tableData.value = [];
|
tableData.value = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,15 +49,6 @@
|
|||||||
<el-option label="已作废" value="7" />
|
<el-option label="已作废" value="7" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="关键字">
|
|
||||||
<el-input
|
|
||||||
v-model="filterForm.keyword"
|
|
||||||
placeholder="申请单号/检查项目"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
@keyup.enter="handleSearch"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleSearch" :loading="loading">
|
<el-button type="primary" @click="handleSearch" :loading="loading">
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon><Search /></el-icon>
|
||||||
@@ -86,62 +77,18 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||||
<el-table-column label="申请单名称" width="140">
|
<el-table-column prop="name" label="申请单名称" width="140" />
|
||||||
<template #default="scope">
|
|
||||||
<span>{{ getItemName(scope.row) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="createTime" label="创建时间" width="160" />
|
<el-table-column prop="createTime" label="创建时间" width="160" />
|
||||||
<el-table-column prop="prescriptionNo" label="申请单号" width="140" />
|
<el-table-column prop="prescriptionNo" label="处方号" width="140" />
|
||||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||||
<el-table-column label="申请单状态" width="120" align="center">
|
<el-table-column label="申请单状态" width="120" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span>{{ parseStatus(scope.row.status) }}</span>
|
<span>{{ parseStatus(scope.row.status) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" fixed="right" width="240">
|
<el-table-column label="操作" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
<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="handleEdit(scope.row)">修改</el-button>
|
|
||||||
<el-popconfirm
|
|
||||||
title="确认删除该申请单?"
|
|
||||||
@confirm="handleDelete(scope.row)"
|
|
||||||
width="200"
|
|
||||||
>
|
|
||||||
<template #reference>
|
|
||||||
<el-button link type="danger">删除</el-button>
|
|
||||||
</template>
|
|
||||||
</el-popconfirm>
|
|
||||||
</template>
|
|
||||||
<!-- 已签发(护士未校对):撤回 -->
|
|
||||||
<template v-else-if="scope.row.status === '1' || scope.row.status === 1">
|
|
||||||
<el-popconfirm
|
|
||||||
title="确认撤回该申请单?撤回后将回滚至待签发状态"
|
|
||||||
@confirm="handleWithdraw(scope.row)"
|
|
||||||
width="260"
|
|
||||||
>
|
|
||||||
<template #reference>
|
|
||||||
<el-button link type="warning">撤回</el-button>
|
|
||||||
</template>
|
|
||||||
</el-popconfirm>
|
|
||||||
</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="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="handlePrint(scope.row)">打印</el-button>
|
|
||||||
<el-button link type="primary" @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="handlePrint(scope.row)">打印</el-button>
|
|
||||||
<el-button link type="success" @click="handleViewReport(scope.row)">看报告</el-button>
|
|
||||||
</template>
|
|
||||||
<!-- 已作废:仅详情 -->
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -163,7 +110,7 @@
|
|||||||
currentDetail.patientName || '-'
|
currentDetail.patientName || '-'
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请单名称">{{
|
<el-descriptions-item label="申请单名称">{{
|
||||||
getItemName(currentDetail)
|
currentDetail.name || '-'
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请单状态">{{
|
<el-descriptions-item label="申请单状态">{{
|
||||||
parseStatus(currentDetail.status)
|
parseStatus(currentDetail.status)
|
||||||
@@ -171,7 +118,7 @@
|
|||||||
<el-descriptions-item label="创建时间">{{
|
<el-descriptions-item label="创建时间">{{
|
||||||
currentDetail.createTime || '-'
|
currentDetail.createTime || '-'
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请单号">{{
|
<el-descriptions-item label="处方号">{{
|
||||||
currentDetail.prescriptionNo || '-'
|
currentDetail.prescriptionNo || '-'
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请者">{{
|
<el-descriptions-item label="申请者">{{
|
||||||
@@ -213,101 +160,6 @@
|
|||||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 修改申请单弹窗 -->
|
|
||||||
<el-dialog
|
|
||||||
v-model="editDialogVisible"
|
|
||||||
title="修改检查申请"
|
|
||||||
width="800px"
|
|
||||||
destroy-on-close
|
|
||||||
top="5vh"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
>
|
|
||||||
<div v-if="editDetail" class="applicationShow-container">
|
|
||||||
<el-form :model="editForm" label-width="120px">
|
|
||||||
<el-form-item label="申请单名称">
|
|
||||||
<el-input v-model="editForm.name" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="发往科室">
|
|
||||||
<el-tree-select
|
|
||||||
clearable
|
|
||||||
style="width: 100%"
|
|
||||||
v-model="editForm.targetDepartment"
|
|
||||||
filterable
|
|
||||||
:data="orgOptions"
|
|
||||||
:props="{
|
|
||||||
value: 'id',
|
|
||||||
label: 'name',
|
|
||||||
children: 'children',
|
|
||||||
}"
|
|
||||||
value-key="id"
|
|
||||||
check-strictly
|
|
||||||
placeholder="请选择科室"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="紧急程度">
|
|
||||||
<el-select v-model="editForm.urgencyLevel" placeholder="请选择紧急程度" clearable style="width: 100%">
|
|
||||||
<el-option label="普通" value="routine" />
|
|
||||||
<el-option label="急诊" value="emergency" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="过敏史">
|
|
||||||
<el-input v-model="editForm.allergyHistory" type="textarea" :rows="2" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="检查目的">
|
|
||||||
<el-input v-model="editForm.examinationPurpose" type="textarea" :rows="2" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="病史摘要">
|
|
||||||
<el-input v-model="editForm.medicalHistorySummary" type="textarea" :rows="2" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="期望检查时间">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="editForm.expectedExaminationTime"
|
|
||||||
type="datetime"
|
|
||||||
placeholder="请选择期望检查时间"
|
|
||||||
style="width: 100%"
|
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="临床诊断">
|
|
||||||
<el-input v-model="editForm.clinicalDiagnosis" type="textarea" :rows="2" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="注意事项">
|
|
||||||
<el-input v-model="editForm.attention" type="textarea" :rows="2" />
|
|
||||||
</el-form-item>
|
|
||||||
<div v-if="editDetail.requestFormDetailList && editDetail.requestFormDetailList.length">
|
|
||||||
<el-divider>申请项目</el-divider>
|
|
||||||
<el-table :data="editDetail.requestFormDetailList" border size="small">
|
|
||||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
|
||||||
<el-table-column prop="adviceName" label="医嘱名称" />
|
|
||||||
<el-table-column prop="quantity" label="数量" width="80" align="center" />
|
|
||||||
<el-table-column prop="unitCode_dictText" label="单位" width="100" />
|
|
||||||
<el-table-column prop="totalPrice" label="总价" width="100" align="right" />
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="editDialogVisible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="handleSaveEdit" :loading="saveLoading">保存</el-button>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
<!-- 报告查看弹窗 -->
|
|
||||||
<el-dialog
|
|
||||||
v-model="reportDialogVisible"
|
|
||||||
title="检查报告"
|
|
||||||
width="900px"
|
|
||||||
destroy-on-close
|
|
||||||
top="5vh"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
>
|
|
||||||
<div v-if="reportUrl" style="min-height: 500px;">
|
|
||||||
<iframe :src="reportUrl" style="width: 100%; height: 500px; border: none;" />
|
|
||||||
</div>
|
|
||||||
<el-empty v-else description="暂无报告数据" />
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="reportDialogVisible = false">关闭</el-button>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -315,7 +167,7 @@
|
|||||||
import {computed, getCurrentInstance, ref, watch} from 'vue';
|
import {computed, getCurrentInstance, ref, watch} from 'vue';
|
||||||
import {Refresh, Search} from '@element-plus/icons-vue';
|
import {Refresh, Search} from '@element-plus/icons-vue';
|
||||||
import {patientInfo} from '../../store/patient.js';
|
import {patientInfo} from '../../store/patient.js';
|
||||||
import {getCheck, deleteRequestForm, withdrawRequestForm, getTestResult} from './api';
|
import {getCheck} from './api';
|
||||||
import {getOrgList} from '@/views/doctorstation/components/api.js';
|
import {getOrgList} from '@/views/doctorstation/components/api.js';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
@@ -327,33 +179,10 @@ const currentDetail = ref(null);
|
|||||||
const descJsonData = ref(null);
|
const descJsonData = ref(null);
|
||||||
const orgOptions = ref([]);
|
const orgOptions = ref([]);
|
||||||
|
|
||||||
// 修改申请单相关
|
|
||||||
const editDialogVisible = ref(false);
|
|
||||||
const editDetail = ref(null);
|
|
||||||
const editForm = ref({});
|
|
||||||
const saveLoading = ref(false);
|
|
||||||
|
|
||||||
// 报告查看相关
|
|
||||||
const reportDialogVisible = ref(false);
|
|
||||||
const reportUrl = ref('');
|
|
||||||
|
|
||||||
// 筛选表单数据
|
// 筛选表单数据
|
||||||
const getDefaultDateRange = () => {
|
|
||||||
const now = new Date();
|
|
||||||
const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
||||||
const formatDate = (d) => {
|
|
||||||
const year = d.getFullYear();
|
|
||||||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
||||||
const day = String(d.getDate()).padStart(2, '0');
|
|
||||||
return `${year}-${month}-${day}`;
|
|
||||||
};
|
|
||||||
return [formatDate(weekAgo), formatDate(now)];
|
|
||||||
};
|
|
||||||
|
|
||||||
const filterForm = ref({
|
const filterForm = ref({
|
||||||
dateRange: getDefaultDateRange(), // 默认近一周
|
dateRange: [], // [startDate, endDate]
|
||||||
status: '', // 申请单状态
|
status: '', // 申请单状态
|
||||||
keyword: '', // 关键字搜索
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
@@ -378,11 +207,6 @@ const fetchData = async () => {
|
|||||||
params.status = filterForm.value.status;
|
params.status = filterForm.value.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加关键字搜索
|
|
||||||
if (filterForm.value.keyword && filterForm.value.keyword.trim()) {
|
|
||||||
params.keyword = filterForm.value.keyword.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await getCheck(params);
|
const res = await getCheck(params);
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
const raw = res.data?.records || res.data;
|
const raw = res.data?.records || res.data;
|
||||||
@@ -419,9 +243,8 @@ const handleSearch = async () => {
|
|||||||
* 重置按钮处理
|
* 重置按钮处理
|
||||||
*/
|
*/
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
filterForm.value.dateRange = getDefaultDateRange();
|
filterForm.value.dateRange = [];
|
||||||
filterForm.value.status = '';
|
filterForm.value.status = '';
|
||||||
filterForm.value.keyword = '';
|
|
||||||
fetchData();
|
fetchData();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -444,36 +267,9 @@ const parseStatus = (status) => {
|
|||||||
return statusMap[String(status)] || '-';
|
return statusMap[String(status)] || '-';
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取申请单展示名称:优先使用具体医嘱名称列表
|
|
||||||
*/
|
|
||||||
const getItemName = (row) => {
|
|
||||||
const items = row?.requestFormDetailList;
|
|
||||||
if (items && items.length > 0) {
|
|
||||||
return items.map(item => item.adviceName).filter(Boolean).join('、') || row.name || '-';
|
|
||||||
}
|
|
||||||
return row.name || '-';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建打印用项目名称字符串(同步函数,用于模板字符串)
|
|
||||||
*/
|
|
||||||
const buildItemNames = (row) => {
|
|
||||||
const items = row?.requestFormDetailList;
|
|
||||||
if (items && items.length > 0) {
|
|
||||||
return items.map(item => item.adviceName).filter(Boolean).join('、') || row.name || '';
|
|
||||||
}
|
|
||||||
return row.name || '';
|
|
||||||
};
|
|
||||||
|
|
||||||
const labelMap = {
|
const labelMap = {
|
||||||
categoryType: '项目类别',
|
categoryType: '项目类别',
|
||||||
targetDepartment: '发往科室',
|
targetDepartment: '发往科室',
|
||||||
urgencyLevel: '紧急程度',
|
|
||||||
allergyHistory: '过敏史',
|
|
||||||
examinationPurpose: '检查目的',
|
|
||||||
medicalHistorySummary: '病史摘要',
|
|
||||||
expectedExaminationTime: '期望检查时间',
|
|
||||||
symptom: '症状',
|
symptom: '症状',
|
||||||
sign: '体征',
|
sign: '体征',
|
||||||
clinicalDiagnosis: '临床诊断',
|
clinicalDiagnosis: '临床诊断',
|
||||||
@@ -503,26 +299,19 @@ const getLocationInfo = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const recursionFun = (targetDepartment) => {
|
const recursionFun = (targetDepartment) => {
|
||||||
if (!targetDepartment) return '';
|
|
||||||
if (!Array.isArray(orgOptions.value) || orgOptions.value.length === 0) return '';
|
|
||||||
let name = '';
|
let name = '';
|
||||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||||
const obj = orgOptions.value[index];
|
const obj = orgOptions.value[index];
|
||||||
if (obj.id == targetDepartment) {
|
if (obj.id == targetDepartment) {
|
||||||
name = obj.name;
|
name = obj.name;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
const subObjArray = obj['children'];
|
const subObjArray = obj['children'];
|
||||||
if (Array.isArray(subObjArray)) {
|
for (let index = 0; index < subObjArray.length; index++) {
|
||||||
for (let i = 0; i < subObjArray.length; i++) {
|
const item = subObjArray[index];
|
||||||
const item = subObjArray[i];
|
if (item.id == targetDepartment) {
|
||||||
if (item.id == targetDepartment) {
|
name = item.name;
|
||||||
name = item.name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name) break;
|
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
@@ -535,15 +324,7 @@ const handleViewDetail = (row) => {
|
|||||||
if (row.descJson) {
|
if (row.descJson) {
|
||||||
try {
|
try {
|
||||||
const obj = JSON.parse(row.descJson);
|
const obj = JSON.parse(row.descJson);
|
||||||
if (obj.targetDepartment) {
|
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||||
const deptName = recursionFun(obj.targetDepartment);
|
|
||||||
obj.targetDepartment = deptName || obj.targetDepartment;
|
|
||||||
}
|
|
||||||
// 紧急程度转换为显示文本
|
|
||||||
const urgencyMap = { routine: '普通', emergency: '急诊' };
|
|
||||||
if (obj.urgencyLevel) {
|
|
||||||
obj.urgencyLevel = urgencyMap[obj.urgencyLevel] || obj.urgencyLevel;
|
|
||||||
}
|
|
||||||
descJsonData.value = obj;
|
descJsonData.value = obj;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('解析 descJson 失败:', e);
|
console.error('解析 descJson 失败:', e);
|
||||||
@@ -555,229 +336,6 @@ const handleViewDetail = (row) => {
|
|||||||
detailDialogVisible.value = true;
|
detailDialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改申请单
|
|
||||||
*/
|
|
||||||
const handleEdit = (row) => {
|
|
||||||
editDetail.value = row;
|
|
||||||
// 解析 descJson 为表单数据
|
|
||||||
const form = { name: row.name || '' };
|
|
||||||
if (row.descJson) {
|
|
||||||
try {
|
|
||||||
const desc = JSON.parse(row.descJson);
|
|
||||||
form.targetDepartment = desc.targetDepartment || '';
|
|
||||||
form.urgencyLevel = desc.urgencyLevel || '';
|
|
||||||
form.allergyHistory = desc.allergyHistory || '';
|
|
||||||
form.examinationPurpose = desc.examinationPurpose || '';
|
|
||||||
form.medicalHistorySummary = desc.medicalHistorySummary || '';
|
|
||||||
form.expectedExaminationTime = desc.expectedExaminationTime || '';
|
|
||||||
form.clinicalDiagnosis = desc.clinicalDiagnosis || '';
|
|
||||||
form.attention = desc.attention || '';
|
|
||||||
form.symptom = desc.symptom || '';
|
|
||||||
form.sign = desc.sign || '';
|
|
||||||
} catch (e) {
|
|
||||||
console.error('解析 descJson 失败:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
editForm.value = form;
|
|
||||||
editDialogVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存修改
|
|
||||||
*/
|
|
||||||
const handleSaveEdit = async () => {
|
|
||||||
if (!editDetail.value?.requestFormId) {
|
|
||||||
proxy.$modal?.msgWarning?.('申请单ID不存在');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
saveLoading.value = true;
|
|
||||||
try {
|
|
||||||
// 复用 save-check 接口进行更新(传入 requestFormId 即为编辑场景)
|
|
||||||
const res = await proxy.$http?.post?.('/reg-doctorstation/request-form/save-check', {
|
|
||||||
requestFormId: editDetail.value.requestFormId,
|
|
||||||
encounterId: editDetail.value.encounterId,
|
|
||||||
patientId: editDetail.value.patientId,
|
|
||||||
name: editForm.value.name,
|
|
||||||
organizationId: editDetail.value.inHospitalOrgId || patientInfo.value?.inHospitalOrgId,
|
|
||||||
descJson: JSON.stringify({
|
|
||||||
targetDepartment: editForm.value.targetDepartment,
|
|
||||||
urgencyLevel: editForm.value.urgencyLevel,
|
|
||||||
allergyHistory: editForm.value.allergyHistory,
|
|
||||||
examinationPurpose: editForm.value.examinationPurpose,
|
|
||||||
medicalHistorySummary: editForm.value.medicalHistorySummary,
|
|
||||||
expectedExaminationTime: editForm.value.expectedExaminationTime,
|
|
||||||
clinicalDiagnosis: editForm.value.clinicalDiagnosis,
|
|
||||||
attention: editForm.value.attention,
|
|
||||||
symptom: editForm.value.symptom,
|
|
||||||
sign: editForm.value.sign,
|
|
||||||
}),
|
|
||||||
activityList: [], // 修改场景仅更新描述信息,不修改项目
|
|
||||||
});
|
|
||||||
if (res?.code === 200) {
|
|
||||||
proxy.$modal?.msgSuccess?.('修改成功');
|
|
||||||
editDialogVisible.value = false;
|
|
||||||
await fetchData();
|
|
||||||
} else {
|
|
||||||
proxy.$modal?.msgError?.(res?.msg || '修改失败');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('修改申请单失败:', e.message);
|
|
||||||
proxy.$modal?.msgError?.('修改失败: ' + (e.message || '网络异常'));
|
|
||||||
} finally {
|
|
||||||
saveLoading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除申请单(仅待签发状态可删除)
|
|
||||||
*/
|
|
||||||
const handleDelete = async (row) => {
|
|
||||||
if (!row.requestFormId) {
|
|
||||||
proxy.$modal?.msgWarning?.('申请单ID不存在');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const res = await deleteRequestForm({ requestFormId: row.requestFormId });
|
|
||||||
if (res?.code === 200) {
|
|
||||||
proxy.$modal?.msgSuccess?.('删除成功');
|
|
||||||
await fetchData();
|
|
||||||
} else {
|
|
||||||
proxy.$modal?.msgError?.(res?.msg || '删除失败');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('删除申请单失败:', e.message);
|
|
||||||
proxy.$modal?.msgError?.('删除失败: ' + (e.message || '网络异常'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 撤回申请单(已签发状态撤回至待签发)
|
|
||||||
*/
|
|
||||||
const handleWithdraw = async (row) => {
|
|
||||||
if (!row.requestFormId) {
|
|
||||||
proxy.$modal?.msgWarning?.('申请单ID不存在');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const res = await withdrawRequestForm({ requestFormId: row.requestFormId });
|
|
||||||
if (res?.code === 200) {
|
|
||||||
proxy.$modal?.msgSuccess?.('撤回成功');
|
|
||||||
await fetchData();
|
|
||||||
} else {
|
|
||||||
proxy.$modal?.msgError?.(res?.msg || '撤回失败');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('撤回申请单失败:', e.message);
|
|
||||||
proxy.$modal?.msgError?.('撤回失败: ' + (e.message || '网络异常'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打印申请单
|
|
||||||
*/
|
|
||||||
const handlePrint = (row) => {
|
|
||||||
// 打开新窗口进行打印
|
|
||||||
const printWindow = window.open('', '_blank');
|
|
||||||
if (!printWindow) {
|
|
||||||
proxy.$modal?.msgWarning?.('请允许浏览器弹出窗口以进行打印');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const content = buildPrintContent(row);
|
|
||||||
printWindow.document.write(`
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>检查申请单打印</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: "Microsoft YaHei", sans-serif; padding: 20px; font-size: 14px; }
|
|
||||||
h2 { text-align: center; margin-bottom: 20px; }
|
|
||||||
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
|
|
||||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
||||||
th { background: #f5f5f5; }
|
|
||||||
.info-row { margin: 8px 0; }
|
|
||||||
.label { font-weight: bold; display: inline-block; width: 100px; }
|
|
||||||
@media print { .no-print { display: none; } }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${content}
|
|
||||||
<div class="no-print" style="text-align: center; margin-top: 20px;">
|
|
||||||
<button onclick="window.print()">打印</button>
|
|
||||||
<button onclick="window.close()">关闭</button>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`);
|
|
||||||
printWindow.document.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建打印内容
|
|
||||||
*/
|
|
||||||
const buildPrintContent = (row) => {
|
|
||||||
let descHtml = '';
|
|
||||||
if (row.descJson) {
|
|
||||||
try {
|
|
||||||
const desc = JSON.parse(row.descJson);
|
|
||||||
descHtml = Object.entries(labelMap)
|
|
||||||
.filter(([key]) => desc[key])
|
|
||||||
.map(([key, label]) => `<div class="info-row"><span class="label">${label}:</span>${desc[key]}</div>`)
|
|
||||||
.join('');
|
|
||||||
} catch (e) {
|
|
||||||
console.error('解析 descJson 失败:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let itemsHtml = '';
|
|
||||||
if (row.requestFormDetailList && row.requestFormDetailList.length) {
|
|
||||||
itemsHtml = `
|
|
||||||
<h3>申请项目</h3>
|
|
||||||
<table>
|
|
||||||
<tr><th>序号</th><th>医嘱名称</th><th>数量</th><th>单位</th><th>总价</th></tr>
|
|
||||||
${row.requestFormDetailList.map((item, i) => `
|
|
||||||
<tr>
|
|
||||||
<td>${i + 1}</td>
|
|
||||||
<td>${item.adviceName || '-'}</td>
|
|
||||||
<td>${item.quantity || '-'}</td>
|
|
||||||
<td>${item.unitCode_dictText || '-'}</td>
|
|
||||||
<td>${item.totalPrice || '-'}</td>
|
|
||||||
</tr>
|
|
||||||
`).join('')}
|
|
||||||
</table>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
return `
|
|
||||||
<h2>检查申请单</h2>
|
|
||||||
<div class="info-row"><span class="label">患者姓名:</span>${row.patientName || '-'}</div>
|
|
||||||
<div class="info-row"><span class="label">申请单名称:</span>${buildItemNames(row) || '-'}</div>
|
|
||||||
<div class="info-row"><span class="label">创建时间:</span>${row.createTime || '-'}</div>
|
|
||||||
<div class="info-row"><span class="label">申请单号:</span>${row.prescriptionNo || '-'}</div>
|
|
||||||
<div class="info-row"><span class="label">申请者:</span>${row.requesterId_dictText || '-'}</div>
|
|
||||||
<div class="info-row"><span class="label">申请单状态:</span>${parseStatus(row.status)}</div>
|
|
||||||
${descHtml ? `<h3>申请单描述</h3>${descHtml}` : ''}
|
|
||||||
${itemsHtml}
|
|
||||||
`;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查看报告
|
|
||||||
*/
|
|
||||||
const handleViewReport = async (row) => {
|
|
||||||
reportUrl.value = '';
|
|
||||||
reportDialogVisible.value = true;
|
|
||||||
try {
|
|
||||||
const res = await getTestResult({ encounterId: row.encounterId, requestFormId: row.requestFormId });
|
|
||||||
if (res?.code === 200 && res?.data) {
|
|
||||||
reportUrl.value = res.data;
|
|
||||||
} else {
|
|
||||||
console.warn('获取检查报告失败:', res?.msg || '无数据');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('获取检查报告异常:', e.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => patientInfo.value?.encounterId,
|
() => patientInfo.value?.encounterId,
|
||||||
(val) => {
|
(val) => {
|
||||||
@@ -786,9 +344,8 @@ watch(
|
|||||||
getLocationInfo();
|
getLocationInfo();
|
||||||
} else {
|
} else {
|
||||||
tableData.value = [];
|
tableData.value = [];
|
||||||
filterForm.value.dateRange = getDefaultDateRange();
|
filterForm.value.dateRange = [];
|
||||||
filterForm.value.status = '';
|
filterForm.value.status = '';
|
||||||
filterForm.value.keyword = '';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|||||||
@@ -181,10 +181,9 @@ const hasMatchedFields = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 查询科室 */
|
/** 查询科室 */
|
||||||
const getLocationInfo = () => {
|
const getLocationInfo = async () => {
|
||||||
getOrgList().then((res) => {
|
const res = await getOrgList();
|
||||||
orgOptions.value = res.data.records;
|
orgOptions.value = res.data.records;
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const recursionFun = (targetDepartment) => {
|
const recursionFun = (targetDepartment) => {
|
||||||
@@ -205,7 +204,12 @@ const recursionFun = (targetDepartment) => {
|
|||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleViewDetail = (row) => {
|
const handleViewDetail = async (row) => {
|
||||||
|
// 确保科室数据已加载,以便将 ID 解析为名称
|
||||||
|
if (!orgOptions.value || orgOptions.value.length === 0) {
|
||||||
|
await getLocationInfo();
|
||||||
|
}
|
||||||
|
|
||||||
currentDetail.value = row;
|
currentDetail.value = row;
|
||||||
// 解析 descJson
|
// 解析 descJson
|
||||||
if (row.descJson) {
|
if (row.descJson) {
|
||||||
@@ -226,10 +230,9 @@ const handleViewDetail = (row) => {
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => patientInfo.value?.encounterId,
|
() => patientInfo.value?.encounterId,
|
||||||
(val) => {
|
async (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
fetchData();
|
await Promise.all([fetchData(), getLocationInfo()]);
|
||||||
getLocationInfo();
|
|
||||||
} else {
|
} else {
|
||||||
tableData.value = [];
|
tableData.value = [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,15 @@
|
|||||||
<el-option label="已作废" value="5" />
|
<el-option label="已作废" value="5" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="关键字">
|
||||||
|
<el-input
|
||||||
|
v-model="filterForm.keyword"
|
||||||
|
placeholder="申请单号/检验项目"
|
||||||
|
clearable
|
||||||
|
style="width: 200px"
|
||||||
|
@keyup.enter="handleSearch"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleSearch" :loading="loading">
|
<el-button type="primary" @click="handleSearch" :loading="loading">
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon><Search /></el-icon>
|
||||||
@@ -188,6 +197,7 @@ const orgOptions = ref([]);
|
|||||||
const filterForm = ref({
|
const filterForm = ref({
|
||||||
dateRange: [], // [startDate, endDate]
|
dateRange: [], // [startDate, endDate]
|
||||||
status: '', // 单据状态
|
status: '', // 单据状态
|
||||||
|
keyword: '', // 关键字搜索
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
@@ -211,7 +221,12 @@ const fetchData = async () => {
|
|||||||
if (filterForm.value.status !== '' && filterForm.value.status !== undefined) {
|
if (filterForm.value.status !== '' && filterForm.value.status !== undefined) {
|
||||||
params.status = filterForm.value.status;
|
params.status = filterForm.value.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加关键字搜索
|
||||||
|
if (filterForm.value.keyword && filterForm.value.keyword.trim()) {
|
||||||
|
params.keyword = filterForm.value.keyword.trim();
|
||||||
|
}
|
||||||
|
|
||||||
const res = await getInspection(params);
|
const res = await getInspection(params);
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
const raw = res.data?.records || res.data;
|
const raw = res.data?.records || res.data;
|
||||||
@@ -251,6 +266,7 @@ const handleReset = () => {
|
|||||||
// 重置筛选条件为默认值
|
// 重置筛选条件为默认值
|
||||||
filterForm.value.dateRange = [];
|
filterForm.value.dateRange = [];
|
||||||
filterForm.value.status = '';
|
filterForm.value.status = '';
|
||||||
|
filterForm.value.keyword = '';
|
||||||
// 重新加载数据
|
// 重新加载数据
|
||||||
fetchData();
|
fetchData();
|
||||||
};
|
};
|
||||||
@@ -331,10 +347,9 @@ const hasMatchedFields = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 查询科室 */
|
/** 查询科室 */
|
||||||
const getLocationInfo = () => {
|
const getLocationInfo = async () => {
|
||||||
getDepartmentList().then((res) => {
|
const res = await getDepartmentList();
|
||||||
orgOptions.value = res.data || [];
|
orgOptions.value = res.data || [];
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const recursionFun = (targetDepartment) => {
|
const recursionFun = (targetDepartment) => {
|
||||||
@@ -357,7 +372,12 @@ const recursionFun = (targetDepartment) => {
|
|||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleViewDetail = (row) => {
|
const handleViewDetail = async (row) => {
|
||||||
|
// 确保科室数据已加载,以便将 ID 解析为名称
|
||||||
|
if (!orgOptions.value || orgOptions.value.length === 0) {
|
||||||
|
await getLocationInfo();
|
||||||
|
}
|
||||||
|
|
||||||
currentDetail.value = row;
|
currentDetail.value = row;
|
||||||
// 解析 descJson
|
// 解析 descJson
|
||||||
if (row.descJson) {
|
if (row.descJson) {
|
||||||
@@ -378,13 +398,13 @@ const handleViewDetail = (row) => {
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => patientInfo.value?.encounterId,
|
() => patientInfo.value?.encounterId,
|
||||||
(val) => {
|
async (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
// 设置默认日期范围为近7天
|
// 设置默认日期范围为近7天
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const sevenDaysAgo = new Date(today);
|
const sevenDaysAgo = new Date(today);
|
||||||
sevenDaysAgo.setDate(today.getDate() - 6); // 包含今天共7天
|
sevenDaysAgo.setDate(today.getDate() - 6); // 包含今天共7天
|
||||||
|
|
||||||
// 格式化为 YYYY-MM-DD
|
// 格式化为 YYYY-MM-DD
|
||||||
const formatDate = (date) => {
|
const formatDate = (date) => {
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
@@ -392,19 +412,19 @@ watch(
|
|||||||
const day = String(date.getDate()).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
return `${year}-${month}-${day}`;
|
return `${year}-${month}-${day}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
filterForm.value.dateRange = [
|
filterForm.value.dateRange = [
|
||||||
formatDate(sevenDaysAgo),
|
formatDate(sevenDaysAgo),
|
||||||
formatDate(today)
|
formatDate(today)
|
||||||
];
|
];
|
||||||
|
|
||||||
fetchData();
|
await Promise.all([fetchData(), getLocationInfo()]);
|
||||||
getLocationInfo();
|
|
||||||
} else {
|
} else {
|
||||||
tableData.value = [];
|
tableData.value = [];
|
||||||
// 重置筛选条件
|
// 重置筛选条件
|
||||||
filterForm.value.dateRange = [];
|
filterForm.value.dateRange = [];
|
||||||
filterForm.value.status = '';
|
filterForm.value.status = '';
|
||||||
|
filterForm.value.keyword = '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
|
|||||||
@@ -176,6 +176,8 @@ const projectWithDepartment = (selectProjectIds, type) => {
|
|||||||
});
|
});
|
||||||
arr.push(searchData);
|
arr.push(searchData);
|
||||||
});
|
});
|
||||||
|
// 保存用户手动选择的发往科室(提交时需要保留)
|
||||||
|
const manualDept = type === 2 ? form.targetDepartment : '';
|
||||||
// 清空科室
|
// 清空科室
|
||||||
form.targetDepartment = '';
|
form.targetDepartment = '';
|
||||||
if (arr.length > 0) {
|
if (arr.length > 0) {
|
||||||
@@ -194,11 +196,17 @@ const projectWithDepartment = (selectProjectIds, type) => {
|
|||||||
// 选中项目中的执行科室id与全部科室数据做匹配
|
// 选中项目中的执行科室id与全部科室数据做匹配
|
||||||
const findItem = findTreeItem(orgOptions.value, obj.orgId);
|
const findItem = findTreeItem(orgOptions.value, obj.orgId);
|
||||||
if (!findItem) {
|
if (!findItem) {
|
||||||
isRelease = false;
|
// type=2(提交)时,若用户已手动选择发往科室,则允许提交
|
||||||
ElMessage({
|
if (type === 2 && manualDept) {
|
||||||
type: 'error',
|
form.targetDepartment = manualDept;
|
||||||
message: '未找到项目执行的科室',
|
isRelease = true;
|
||||||
});
|
} else {
|
||||||
|
isRelease = false;
|
||||||
|
ElMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: '未找到项目执行的科室',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type == 1) {
|
if (type == 1) {
|
||||||
if (isRelease) {
|
if (isRelease) {
|
||||||
@@ -232,7 +240,7 @@ const submit = () => {
|
|||||||
unitCode: item.priceList[0].unitCode /** 请求单位编码 */,
|
unitCode: item.priceList[0].unitCode /** 请求单位编码 */,
|
||||||
unitPrice: item.priceList[0].price /** 单价 */,
|
unitPrice: item.priceList[0].price /** 单价 */,
|
||||||
totalPrice: item.priceList[0].price /** 总价 */,
|
totalPrice: item.priceList[0].price /** 总价 */,
|
||||||
positionId: item.positionId, //执行科室id
|
positionId: item.positionId || form.targetDepartment, //执行科室id,未配置时使用用户手动选择的科室
|
||||||
ybClassEnum: item.ybClassEnum, //类别医保编码
|
ybClassEnum: item.ybClassEnum, //类别医保编码
|
||||||
conditionId: item.conditionId, //诊断ID
|
conditionId: item.conditionId, //诊断ID
|
||||||
encounterDiagnosisId: item.encounterDiagnosisId, //就诊诊断id
|
encounterDiagnosisId: item.encounterDiagnosisId, //就诊诊断id
|
||||||
|
|||||||
@@ -881,8 +881,9 @@ function handleFocus(row, index) {
|
|||||||
// 用 adviceType + categoryCode 组合查找匹配的选项
|
// 用 adviceType + categoryCode 组合查找匹配的选项
|
||||||
const selectValue = (adviceType == 1 && row.categoryCode) ? '1-' + row.categoryCode : adviceType;
|
const selectValue = (adviceType == 1 && row.categoryCode) ? '1-' + row.categoryCode : adviceType;
|
||||||
const selectedItem = adviceTypeList.value.find(item => item.value === selectValue) || adviceTypeList.value.find(item => item.adviceType === adviceType);
|
const selectedItem = adviceTypeList.value.find(item => item.value === selectValue) || adviceTypeList.value.find(item => item.adviceType === adviceType);
|
||||||
// 修复Bug #486:当行没有显式选择医嘱类型时,不传categoryCode,让搜索在全药库中进行
|
// 修复Bug #486:当行没有显式选择医嘱类型时(row.adviceType为undefined),
|
||||||
const categoryCode = selectedItem ? selectedItem.categoryCode : (row.adviceType !== undefined ? (adviceQueryParams.value.categoryCode || '') : '');
|
// 不传categoryCode,让搜索在全药库中进行;只有行已选择类型时才用对应categoryCode过滤
|
||||||
|
const categoryCode = row.adviceType !== undefined ? (selectedItem ? selectedItem.categoryCode : '') : '';
|
||||||
const searchKey = row.adviceName || '';
|
const searchKey = row.adviceName || '';
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -919,8 +920,9 @@ function handleChange(value) {
|
|||||||
// 用 adviceType + categoryCode 组合查找匹配的选项
|
// 用 adviceType + categoryCode 组合查找匹配的选项
|
||||||
const selectValue = (adviceType == 1 && row?.categoryCode) ? '1-' + row.categoryCode : adviceType;
|
const selectValue = (adviceType == 1 && row?.categoryCode) ? '1-' + row.categoryCode : adviceType;
|
||||||
const selectedItem = adviceTypeList.value.find(item => item.value === selectValue) || adviceTypeList.value.find(item => item.adviceType === adviceType);
|
const selectedItem = adviceTypeList.value.find(item => item.value === selectValue) || adviceTypeList.value.find(item => item.adviceType === adviceType);
|
||||||
// 修复Bug #486:当行没有显式选择医嘱类型时,不传categoryCode,让搜索在全药库中进行
|
// 修复Bug #486:当行没有显式选择医嘱类型时(row?.adviceType为undefined),
|
||||||
const categoryCode = selectedItem ? selectedItem.categoryCode : (row?.adviceType !== undefined ? (adviceQueryParams.value.categoryCode || '') : '');
|
// 不传categoryCode,让搜索在全药库中进行;只有行已选择类型时才用对应categoryCode过滤
|
||||||
|
const categoryCode = row?.adviceType !== undefined ? (selectedItem ? selectedItem.categoryCode : '') : '';
|
||||||
tableRef.refresh(adviceType, categoryCode, value);
|
tableRef.refresh(adviceType, categoryCode, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,13 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- <el-tab-pane label="医技报告" name="fourth">Task</el-tab-pane> -->
|
<!-- <el-tab-pane label="医技报告" name="fourth">Task</el-tab-pane> -->
|
||||||
<el-tab-pane label="检验申请" name="test">
|
<el-tab-pane label="检验申请" name="test">
|
||||||
<TestApplication ref="testApplicationRef" :show-status-column="false" />
|
<TestApplication ref="testApplicationRef" :show-status-column="true" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
```vue
|
||||||
<el-tab-pane label="检查申请" name="examine">
|
<el-tab-pane label="检查申请" name="examine">
|
||||||
<ExamineApplication ref="examineApplicationRef" />
|
<ExamineApplication ref="examineApplicationRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
```
|
||||||
<el-tab-pane label="汇总发药申请" name="summaryDrug">
|
<el-tab-pane label="汇总发药申请" name="summaryDrug">
|
||||||
<SummaryDrugApplication ref="summaryDrugApplicationRef" />
|
<SummaryDrugApplication ref="summaryDrugApplicationRef" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -44,11 +46,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onBeforeMount, onMounted, provide, reactive, ref, watch } from 'vue';
|
import {computed, onBeforeMount, onMounted, provide, reactive, ref, watch,} from 'vue';
|
||||||
|
|
||||||
import Emr from './emr/index.vue';
|
import Emr from './emr/index.vue';
|
||||||
import inPatientBarDoctorFold from '@/components/patientBar/inPatientBarDoctorFold.vue';
|
import inPatientBarDoctorFold from '@/components/patientBar/inPatientBarDoctorFold.vue';
|
||||||
import SummaryDrugApplication from './components/applicationShow/summaryDrugApplication.vue';
|
|
||||||
import PatientList from '@/components/PatientList/patient-list.vue';
|
import PatientList from '@/components/PatientList/patient-list.vue';
|
||||||
import {localPatientInfo, updateLocalPatientInfo} from './store/localPatient';
|
import {localPatientInfo, updateLocalPatientInfo} from './store/localPatient';
|
||||||
import {patientInfo, updatePatientInfo} from './store/patient';
|
import {patientInfo, updatePatientInfo} from './store/patient';
|
||||||
@@ -83,7 +84,6 @@ const currentPatientInfo = ref({});
|
|||||||
const testApplicationRef = ref();
|
const testApplicationRef = ref();
|
||||||
const examineApplicationRef = ref();
|
const examineApplicationRef = ref();
|
||||||
const surgeryApplicationRef = ref();
|
const surgeryApplicationRef = ref();
|
||||||
const summaryDrugApplicationRef = ref();
|
|
||||||
const bloodTtransfusionAapplicationRef = ref();
|
const bloodTtransfusionAapplicationRef = ref();
|
||||||
|
|
||||||
// 患者列表相关逻辑
|
// 患者列表相关逻辑
|
||||||
|
|||||||
@@ -469,11 +469,19 @@ function handleExecute() {
|
|||||||
console.log(list, 'list');
|
console.log(list, 'list');
|
||||||
adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => {
|
adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess(res.msg || '医嘱执行成功');
|
|
||||||
handleGetPrescription();
|
handleGetPrescription();
|
||||||
lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => {
|
// 仅当选中医嘱中包含药品/耗材类医嘱时,才调用耗材批号匹配
|
||||||
console.warn('lotNumberMatch failed after adviceExecute:', error);
|
const hasMedOrDevice = list.some(
|
||||||
});
|
(item) =>
|
||||||
|
item.adviceTable === 'med_medication_request' ||
|
||||||
|
String(item.adviceTable || '').includes('device'),
|
||||||
|
);
|
||||||
|
if (hasMedOrDevice) {
|
||||||
|
lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => {
|
||||||
|
console.warn('lotNumberMatch failed after adviceExecute:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
proxy.$modal.msgSuccess(res.msg || '医嘱执行成功');
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '医嘱执行失败');
|
proxy.$modal.msgError(res.msg || '医嘱执行失败');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user