Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -76,6 +76,26 @@ public class OperatingRoomAppServiceImpl implements IOperatingRoomAppService {
|
|||||||
operatingRoomPage.getRecords().forEach(e -> {
|
operatingRoomPage.getRecords().forEach(e -> {
|
||||||
// 状态
|
// 状态
|
||||||
e.setStatusEnum_dictText(e.getStatusEnum() != null && e.getStatusEnum() == 1 ? "启用" : "停用");
|
e.setStatusEnum_dictText(e.getStatusEnum() != null && e.getStatusEnum() == 1 ? "启用" : "停用");
|
||||||
|
// 类型
|
||||||
|
if (e.getRoomTypeEnum() != null) {
|
||||||
|
switch (e.getRoomTypeEnum()) {
|
||||||
|
case 1:
|
||||||
|
e.setRoomTypeEnum_dictText("急诊手术室");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
e.setRoomTypeEnum_dictText("择期手术室");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
e.setRoomTypeEnum_dictText("日间手术室");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
e.setRoomTypeEnum_dictText("复合手术室");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
e.setRoomTypeEnum_dictText("未知");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// 拼音码
|
// 拼音码
|
||||||
e.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(e.getName()));
|
e.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(e.getName()));
|
||||||
// 五笔码
|
// 五笔码
|
||||||
@@ -105,6 +125,27 @@ public class OperatingRoomAppServiceImpl implements IOperatingRoomAppService {
|
|||||||
operatingRoomDto.setStatusEnum_dictText(
|
operatingRoomDto.setStatusEnum_dictText(
|
||||||
operatingRoom.getStatusEnum() != null && operatingRoom.getStatusEnum() == 1 ? "启用" : "停用");
|
operatingRoom.getStatusEnum() != null && operatingRoom.getStatusEnum() == 1 ? "启用" : "停用");
|
||||||
|
|
||||||
|
// 类型描述
|
||||||
|
if (operatingRoom.getRoomTypeEnum() != null) {
|
||||||
|
switch (operatingRoom.getRoomTypeEnum()) {
|
||||||
|
case 1:
|
||||||
|
operatingRoomDto.setRoomTypeEnum_dictText("急诊手术室");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
operatingRoomDto.setRoomTypeEnum_dictText("择期手术室");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
operatingRoomDto.setRoomTypeEnum_dictText("日间手术室");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
operatingRoomDto.setRoomTypeEnum_dictText("复合手术室");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
operatingRoomDto.setRoomTypeEnum_dictText("未知");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 如果有机构ID,查询机构名称
|
// 如果有机构ID,查询机构名称
|
||||||
if (operatingRoom.getOrganizationId() != null) {
|
if (operatingRoom.getOrganizationId() != null) {
|
||||||
String orgName = commonService.getOrgNameById(operatingRoom.getOrganizationId());
|
String orgName = commonService.getOrgNameById(operatingRoom.getOrganizationId());
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.openhis.web.basedatamanage.dto;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import com.openhis.common.annotation.Dict;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
@@ -35,6 +36,13 @@ public class OperatingRoomDto implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手术室类型
|
||||||
|
*/
|
||||||
|
@Dict(dictCode = "operating_room_type")
|
||||||
|
private Integer roomTypeEnum;
|
||||||
|
private String roomTypeEnum_dictText;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所属机构ID
|
* 所属机构ID
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -167,6 +167,14 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
|||||||
Long encounterId = saveDiagnosisParam.getEncounterId();
|
Long encounterId = saveDiagnosisParam.getEncounterId();
|
||||||
// 诊断定义集合
|
// 诊断定义集合
|
||||||
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
||||||
|
// 如果本次保存中有设置主诊断,则先清空该就诊下所有的主诊断标记,确保唯一性
|
||||||
|
boolean hasMain = diagnosisChildList.stream().anyMatch(d -> Integer.valueOf(1).equals(d.getMaindiseFlag()));
|
||||||
|
if (hasMain) {
|
||||||
|
iEncounterDiagnosisService.update(new LambdaUpdateWrapper<EncounterDiagnosis>()
|
||||||
|
.eq(EncounterDiagnosis::getEncounterId, encounterId)
|
||||||
|
.set(EncounterDiagnosis::getMaindiseFlag, 0));
|
||||||
|
}
|
||||||
|
|
||||||
// 保存诊断管理
|
// 保存诊断管理
|
||||||
Condition condition;
|
Condition condition;
|
||||||
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
||||||
@@ -240,6 +248,14 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
|||||||
Long encounterId = saveDiagnosisParam.getEncounterId();
|
Long encounterId = saveDiagnosisParam.getEncounterId();
|
||||||
// 诊断定义集合
|
// 诊断定义集合
|
||||||
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
||||||
|
// 如果本次保存中有设置主诊断,则先清空该就诊下所有的主诊断标记,确保唯一性
|
||||||
|
boolean hasMain = diagnosisChildList.stream().anyMatch(d -> Integer.valueOf(1).equals(d.getMaindiseFlag()));
|
||||||
|
if (hasMain) {
|
||||||
|
iEncounterDiagnosisService.update(new LambdaUpdateWrapper<EncounterDiagnosis>()
|
||||||
|
.eq(EncounterDiagnosis::getEncounterId, encounterId)
|
||||||
|
.set(EncounterDiagnosis::getMaindiseFlag, 0));
|
||||||
|
}
|
||||||
|
|
||||||
// 保存诊断管理
|
// 保存诊断管理
|
||||||
Condition condition;
|
Condition condition;
|
||||||
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
||||||
@@ -259,21 +275,21 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
|
|||||||
EncounterDiagnosis encounterDiagnosis;
|
EncounterDiagnosis encounterDiagnosis;
|
||||||
|
|
||||||
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
||||||
|
encounterDiagnosis = new EncounterDiagnosis();
|
||||||
if (saveDiagnosisChildParam.getUpdateId() != null) {
|
if (saveDiagnosisChildParam.getUpdateId() != null) {
|
||||||
String updateId = saveDiagnosisChildParam.getUpdateId();
|
String updateId = saveDiagnosisChildParam.getUpdateId();
|
||||||
encounterDiagnosis = new EncounterDiagnosis();
|
|
||||||
encounterDiagnosis.setId(Long.parseLong(updateId));
|
encounterDiagnosis.setId(Long.parseLong(updateId));
|
||||||
encounterDiagnosis.setEncounterId(encounterId);
|
|
||||||
encounterDiagnosis.setConditionId(saveDiagnosisChildParam.getConditionId());
|
|
||||||
encounterDiagnosis.setMaindiseFlag(saveDiagnosisChildParam.getMaindiseFlag());
|
|
||||||
encounterDiagnosis.setDiagSrtNo(saveDiagnosisChildParam.getDiagSrtNo()); // 排序号
|
|
||||||
encounterDiagnosis.setMedTypeCode(saveDiagnosisChildParam.getMedTypeCode());// 医疗类型
|
|
||||||
encounterDiagnosis.setDiagnosisDesc(saveDiagnosisChildParam.getDiagnosisDesc()); // 诊断描述
|
|
||||||
encounterDiagnosis.setIptDiseTypeCode(saveDiagnosisChildParam.getIptDiseTypeCode()); // 患者疾病诊断类型代码
|
|
||||||
iEncounterDiagnosisService.saveOrUpdate(encounterDiagnosis);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
encounterDiagnosis.setEncounterId(encounterId);
|
||||||
|
encounterDiagnosis.setConditionId(saveDiagnosisChildParam.getConditionId());
|
||||||
|
encounterDiagnosis.setMaindiseFlag(saveDiagnosisChildParam.getMaindiseFlag());
|
||||||
|
encounterDiagnosis.setDiagSrtNo(saveDiagnosisChildParam.getDiagSrtNo()); // 排序号
|
||||||
|
encounterDiagnosis.setMedTypeCode(saveDiagnosisChildParam.getMedTypeCode());// 医疗类型
|
||||||
|
encounterDiagnosis.setDiagnosisDesc(saveDiagnosisChildParam.getDiagnosisDesc()); // 诊断描述
|
||||||
|
encounterDiagnosis.setIptDiseTypeCode(saveDiagnosisChildParam.getIptDiseTypeCode()); // 患者疾病诊断类型代码
|
||||||
|
encounterDiagnosis.setTcmFlag(Whether.YES.getValue());// 中医标识
|
||||||
|
encounterDiagnosis.setSyndromeGroupNo(saveDiagnosisChildParam.getSyndromeGroupNo());// 中医证候组号
|
||||||
|
iEncounterDiagnosisService.saveOrUpdate(encounterDiagnosis);
|
||||||
}
|
}
|
||||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"中医诊断"}));
|
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"中医诊断"}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.openhis.web.doctorstation.appservice.impl;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
@@ -251,6 +252,15 @@ public class DoctorStationDiagnosisAppServiceImpl implements IDoctorStationDiagn
|
|||||||
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
|
||||||
// 先删除再保存
|
// 先删除再保存
|
||||||
// iEncounterDiagnosisService.deleteEncounterDiagnosisInfos(encounterId);
|
// iEncounterDiagnosisService.deleteEncounterDiagnosisInfos(encounterId);
|
||||||
|
|
||||||
|
// 如果本次保存中有设置主诊断,则先清空该就诊下所有的主诊断标记,确保唯一性
|
||||||
|
boolean hasMain = diagnosisChildList.stream().anyMatch(d -> Integer.valueOf(1).equals(d.getMaindiseFlag()));
|
||||||
|
if (hasMain) {
|
||||||
|
iEncounterDiagnosisService.update(new LambdaUpdateWrapper<EncounterDiagnosis>()
|
||||||
|
.eq(EncounterDiagnosis::getEncounterId, encounterId)
|
||||||
|
.set(EncounterDiagnosis::getMaindiseFlag, 0));
|
||||||
|
}
|
||||||
|
|
||||||
// 保存诊断管理
|
// 保存诊断管理
|
||||||
Condition condition;
|
Condition condition;
|
||||||
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
|
||||||
@@ -285,11 +295,17 @@ public class DoctorStationDiagnosisAppServiceImpl implements IDoctorStationDiagn
|
|||||||
encounterDiagnosis.setId(Long.parseLong(s));
|
encounterDiagnosis.setId(Long.parseLong(s));
|
||||||
encounterDiagnosis.setEncounterId(encounterId);
|
encounterDiagnosis.setEncounterId(encounterId);
|
||||||
// encounterDiagnosis.setConditionId(saveDiagnosisChildParam.getConditionId());
|
// encounterDiagnosis.setConditionId(saveDiagnosisChildParam.getConditionId());
|
||||||
encounterDiagnosis.setMaindiseFlag(saveDiagnosisChildParam.getMaindiseFlag());
|
// 只有第一个ID(病)设置为主诊断标记,其他的(证)设置为0
|
||||||
|
if (i == 1) {
|
||||||
|
encounterDiagnosis.setMaindiseFlag(saveDiagnosisChildParam.getMaindiseFlag());
|
||||||
|
} else {
|
||||||
|
encounterDiagnosis.setMaindiseFlag(0);
|
||||||
|
}
|
||||||
encounterDiagnosis.setDiagSrtNo(saveDiagnosisChildParam.getDiagSrtNo()); // 排序号
|
encounterDiagnosis.setDiagSrtNo(saveDiagnosisChildParam.getDiagSrtNo()); // 排序号
|
||||||
encounterDiagnosis.setMedTypeCode(saveDiagnosisChildParam.getMedTypeCode());// 医疗类型
|
encounterDiagnosis.setMedTypeCode(saveDiagnosisChildParam.getMedTypeCode());// 医疗类型
|
||||||
encounterDiagnosis.setDiagnosisDesc(saveDiagnosisChildParam.getDiagnosisDesc()); // 诊断描述
|
encounterDiagnosis.setDiagnosisDesc(saveDiagnosisChildParam.getDiagnosisDesc()); // 诊断描述
|
||||||
encounterDiagnosis.setIptDiseTypeCode(saveDiagnosisChildParam.getIptDiseTypeCode()); // 患者疾病诊断类型代码
|
encounterDiagnosis.setIptDiseTypeCode(saveDiagnosisChildParam.getIptDiseTypeCode()); // 患者疾病诊断类型代码
|
||||||
|
encounterDiagnosis.setTcmFlag(Whether.YES.getValue());// 中医标识
|
||||||
iEncounterDiagnosisService.saveOrUpdate(encounterDiagnosis);
|
iEncounterDiagnosisService.saveOrUpdate(encounterDiagnosis);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,29 +143,35 @@ public class PatientInformationServiceImpl implements IPatientInformationService
|
|||||||
CommonConstants.FieldName.BusNo, CommonConstants.FieldName.PyStr, CommonConstants.FieldName.WbStr)),
|
CommonConstants.FieldName.BusNo, CommonConstants.FieldName.PyStr, CommonConstants.FieldName.WbStr)),
|
||||||
request);
|
request);
|
||||||
|
|
||||||
// 查询当前用户对应的医生信息
|
// 检查是否是精确ID查询(从门诊挂号页面跳转时使用)
|
||||||
LambdaQueryWrapper<com.openhis.administration.domain.Practitioner> practitionerQuery = new LambdaQueryWrapper<>();
|
boolean hasExactIdQuery = (patientBaseInfoDto.getId() != null);
|
||||||
practitionerQuery.eq(com.openhis.administration.domain.Practitioner::getUserId, userId);
|
|
||||||
// 使用list()避免TooManyResultsException异常,然后取第一个记录
|
|
||||||
List<com.openhis.administration.domain.Practitioner> practitionerList = practitionerService.list(practitionerQuery);
|
|
||||||
com.openhis.administration.domain.Practitioner practitioner = practitionerList != null && !practitionerList.isEmpty() ? practitionerList.get(0) : null;
|
|
||||||
|
|
||||||
// 如果当前用户是医生,添加医生患者过滤条件
|
// 只有非精确ID查询时,才添加医生患者过滤条件
|
||||||
if (practitioner != null) {
|
if (!hasExactIdQuery) {
|
||||||
// 查询该医生作为接诊医生(ADMITTER, code="1")和挂号医生(REGISTRATION_DOCTOR, code="12")的所有就诊记录的患者ID
|
// 查询当前用户对应的医生信息
|
||||||
List<Long> doctorPatientIds = patientManageMapper.getPatientIdsByPractitionerId(
|
LambdaQueryWrapper<com.openhis.administration.domain.Practitioner> practitionerQuery = new LambdaQueryWrapper<>();
|
||||||
practitioner.getId(),
|
practitionerQuery.eq(com.openhis.administration.domain.Practitioner::getUserId, userId);
|
||||||
Arrays.asList(ParticipantType.ADMITTER.getCode(), ParticipantType.REGISTRATION_DOCTOR.getCode()));
|
// 使用list()避免TooManyResultsException异常,然后取第一个记录
|
||||||
|
List<com.openhis.administration.domain.Practitioner> practitionerList = practitionerService.list(practitionerQuery);
|
||||||
|
com.openhis.administration.domain.Practitioner practitioner = practitionerList != null && !practitionerList.isEmpty() ? practitionerList.get(0) : null;
|
||||||
|
|
||||||
if (doctorPatientIds != null && !doctorPatientIds.isEmpty()) {
|
// 如果当前用户是医生,添加医生患者过滤条件
|
||||||
// 添加患者ID过滤条件 - 注意:这里使用列名而不是表别名
|
if (practitioner != null) {
|
||||||
queryWrapper.in("id", doctorPatientIds);
|
// 查询该医生作为接诊医生(ADMITTER, code="1")和挂号医生(REGISTRATION_DOCTOR, code="12")的所有就诊记录的患者ID
|
||||||
} else {
|
List<Long> doctorPatientIds = patientManageMapper.getPatientIdsByPractitionerId(
|
||||||
// 如果没有相关患者,返回空结果
|
practitioner.getId(),
|
||||||
queryWrapper.eq("id", -1); // 设置一个不存在的ID
|
Arrays.asList(ParticipantType.ADMITTER.getCode(), ParticipantType.REGISTRATION_DOCTOR.getCode()));
|
||||||
|
|
||||||
|
if (doctorPatientIds != null && !doctorPatientIds.isEmpty()) {
|
||||||
|
// 添加患者ID过滤条件 - 注意:这里使用列名而不是表别名
|
||||||
|
queryWrapper.in("id", doctorPatientIds);
|
||||||
|
} else {
|
||||||
|
// 如果没有相关患者,返回空结果
|
||||||
|
queryWrapper.eq("id", -1); // 设置一个不存在的ID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// 如果不是医生,查询所有患者
|
||||||
}
|
}
|
||||||
// 如果不是医生,查询所有患者
|
|
||||||
|
|
||||||
IPage<PatientBaseInfoDto> patientInformationPage
|
IPage<PatientBaseInfoDto> patientInformationPage
|
||||||
= patientManageMapper.getPatientPage(new Page<>(pageNo, pageSize), queryWrapper);
|
= patientManageMapper.getPatientPage(new Page<>(pageNo, pageSize), queryWrapper);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.core.common.core.domain.HisBaseEntity;
|
import com.core.common.core.domain.HisBaseEntity;
|
||||||
|
import com.openhis.common.annotation.Dict;
|
||||||
import com.openhis.common.enums.LocationStatus;
|
import com.openhis.common.enums.LocationStatus;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@@ -31,9 +32,17 @@ public class OperatingRoom extends HisBaseEntity {
|
|||||||
/** 手术室名称 */
|
/** 手术室名称 */
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
/** 手术室类型 */
|
||||||
|
@Dict(dictCode = "operating_room_type")
|
||||||
|
private Integer roomTypeEnum;
|
||||||
|
private String roomTypeEnum_dictText;
|
||||||
|
|
||||||
/** 所属机构ID */
|
/** 所属机构ID */
|
||||||
private Long organizationId;
|
private Long organizationId;
|
||||||
|
|
||||||
|
/** 所属机构名称 */
|
||||||
|
private String organizationName;
|
||||||
|
|
||||||
/** 位置描述 */
|
/** 位置描述 */
|
||||||
private String locationDescription;
|
private String locationDescription;
|
||||||
|
|
||||||
|
|||||||
@@ -113,116 +113,116 @@ export const constantRoutes = [
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
// 兼容系统业务管理路径
|
// 兼容系统业务管理路径
|
||||||
{
|
// {
|
||||||
path: '/system/ywgz',
|
// path: '/system/ywgz',
|
||||||
component: Layout,
|
// component: Layout,
|
||||||
redirect: '/system/ywgz/InvoiceManagement',
|
// redirect: '/system/ywgz/InvoiceManagement',
|
||||||
hidden: true,
|
// hidden: true,
|
||||||
children: [
|
// children: [
|
||||||
{
|
// {
|
||||||
path: 'InvoiceManagement',
|
// path: 'InvoiceManagement',
|
||||||
component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
|
// component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
|
||||||
name: 'SystemInvoiceManagement',
|
// name: 'SystemInvoiceManagement',
|
||||||
meta: { title: '发票管理' }
|
// meta: { title: '发票管理' }
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: '/maintainSystem',
|
// path: '/maintainSystem',
|
||||||
component: Layout,
|
// component: Layout,
|
||||||
redirect: '/maintainSystem/chargeConfig',
|
// redirect: '/maintainSystem/chargeConfig',
|
||||||
name: 'MaintainSystem',
|
// name: 'MaintainSystem',
|
||||||
meta: { title: '维护系统', icon: 'system' },
|
// meta: { title: '维护系统', icon: 'system' },
|
||||||
children: [
|
// children: [
|
||||||
{
|
// {
|
||||||
path: '',
|
// path: '',
|
||||||
redirect: 'chargeConfig'
|
// redirect: 'chargeConfig'
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'chargeConfig',
|
// path: 'chargeConfig',
|
||||||
component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
// component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
|
||||||
name: 'ChargeConfig',
|
// name: 'ChargeConfig',
|
||||||
meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
// meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'Inspection',
|
// path: 'Inspection',
|
||||||
component: () => import('@/views/maintainSystem/Inspection/index.vue'),
|
// component: () => import('@/views/maintainSystem/Inspection/index.vue'),
|
||||||
name: 'Inspection',
|
// name: 'Inspection',
|
||||||
meta: { title: '检验管理', icon: 'inspection' },
|
// meta: { title: '检验管理', icon: 'inspection' },
|
||||||
children: [
|
// children: [
|
||||||
{
|
// {
|
||||||
path: 'PackageManagement',
|
// path: 'PackageManagement',
|
||||||
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
// component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
|
||||||
name: 'PackageManagement',
|
// name: 'PackageManagement',
|
||||||
meta: { title: '套餐管理' }
|
// meta: { title: '套餐管理' }
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: '/system',
|
// path: '/system',
|
||||||
component: Layout,
|
// component: Layout,
|
||||||
redirect: '/system/user',
|
// redirect: '/system/user',
|
||||||
name: 'System',
|
// name: 'System',
|
||||||
meta: { title: '系统管理', icon: 'system' },
|
// meta: { title: '系统管理', icon: 'system' },
|
||||||
children: [
|
// children: [
|
||||||
{
|
// {
|
||||||
path: 'user',
|
// path: 'user',
|
||||||
component: () => import('@/views/system/user/index.vue'),
|
// component: () => import('@/views/system/user/index.vue'),
|
||||||
name: 'User',
|
// name: 'User',
|
||||||
meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] }
|
// meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'role',
|
// path: 'role',
|
||||||
component: () => import('@/views/system/role/index.vue'),
|
// component: () => import('@/views/system/role/index.vue'),
|
||||||
name: 'Role',
|
// name: 'Role',
|
||||||
meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] }
|
// meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'menu',
|
// path: 'menu',
|
||||||
component: () => import('@/views/system/menu/index.vue'),
|
// component: () => import('@/views/system/menu/index.vue'),
|
||||||
name: 'Menu',
|
// name: 'Menu',
|
||||||
meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] }
|
// meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'dept',
|
// path: 'dept',
|
||||||
component: () => import('@/views/system/dept/index.vue'),
|
// component: () => import('@/views/system/dept/index.vue'),
|
||||||
name: 'Dept',
|
// name: 'Dept',
|
||||||
meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] }
|
// meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'post',
|
// path: 'post',
|
||||||
component: () => import('@/views/system/post/index.vue'),
|
// component: () => import('@/views/system/post/index.vue'),
|
||||||
name: 'Post',
|
// name: 'Post',
|
||||||
meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] }
|
// meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'dict',
|
// path: 'dict',
|
||||||
component: () => import('@/views/system/dict/index.vue'),
|
// component: () => import('@/views/system/dict/index.vue'),
|
||||||
name: 'Dict',
|
// name: 'Dict',
|
||||||
meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] }
|
// meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'config',
|
// path: 'config',
|
||||||
component: () => import('@/views/system/config/index.vue'),
|
// component: () => import('@/views/system/config/index.vue'),
|
||||||
name: 'Config',
|
// name: 'Config',
|
||||||
meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] }
|
// meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'notice',
|
// path: 'notice',
|
||||||
component: () => import('@/views/system/notice/index.vue'),
|
// component: () => import('@/views/system/notice/index.vue'),
|
||||||
name: 'Notice',
|
// name: 'Notice',
|
||||||
meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] }
|
// meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: 'tenant',
|
// path: 'tenant',
|
||||||
component: () => import('@/views/system/tenant/index.vue'),
|
// component: () => import('@/views/system/tenant/index.vue'),
|
||||||
name: 'Tenant',
|
// name: 'Tenant',
|
||||||
meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] }
|
// meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] }
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: '/system/tenant-user',
|
path: '/system/tenant-user',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
|||||||
@@ -961,7 +961,20 @@ async function handleReadCard(value) {
|
|||||||
|
|
||||||
/** 跳转到患者档案页面 */
|
/** 跳转到患者档案页面 */
|
||||||
function goToPatientRecord() {
|
function goToPatientRecord() {
|
||||||
router.push('/patient/patientmgr');
|
// 如果已选择患者,则跳转到档案页面并定位到该患者
|
||||||
|
if (form.value.patientId) {
|
||||||
|
// 使用患者ID作为查询参数传递到档案页面
|
||||||
|
router.push({
|
||||||
|
path: '/patient/patientmgr',
|
||||||
|
query: {
|
||||||
|
patientId: form.value.patientId,
|
||||||
|
patientName: form.value.name
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 未选择患者时,直接跳转到档案页面
|
||||||
|
router.push('/patient/patientmgr');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 新增用户信息弹窗 */
|
/** 新增用户信息弹窗 */
|
||||||
|
|||||||
@@ -0,0 +1,431 @@
|
|||||||
|
## 门诊手术安排界面PRD文档
|
||||||
|
|
||||||
|
### 一、页面概述
|
||||||
|
|
||||||
|
**页面名称**:门诊手术安排界面
|
||||||
|
**页面目标**:提供手术室手术安排信息的录入、查询、编辑和删除功能,支持手术排班全流程管理
|
||||||
|
**适用场景**:门诊医生或手术室管理人员安排手术时使用
|
||||||
|
**页面类型**:表单页+列表页组合(主列表+弹窗表单)
|
||||||
|
|
||||||
|
**原型图地址:**https://static.pm-ai.cn/prototype/20260106/28ca9ee6ac20cfd8c867d3989ffd88f9/index.html
|
||||||
|
|
||||||
|
**核心功能**:
|
||||||
|
|
||||||
|
1. 手术申请单查询与筛选功能
|
||||||
|
2. 手术安排信息新增与编辑功能
|
||||||
|
3. 手术信息详细展示与表单填写
|
||||||
|
4. 手术数据导出功能
|
||||||
|
5. 手术申请单与手术安排单的关联操作
|
||||||
|
**用户价值**:通过该界面,医护人员可以高效完成手术排期工作,确保手术资源合理分配,减少人工操作错误,提高手术室管理效率,实现手术全流程的数字化管理。
|
||||||
|
|
||||||
|
**流程图:**
|
||||||
|
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
node_start(["Start"]) --> A["进入门诊手术安排界面"]
|
||||||
|
A --> B["顶部筛选区域操作"]
|
||||||
|
B --> C{"选择操作类型"}
|
||||||
|
C -- "查询" --> D["填写查询条件"]
|
||||||
|
D --> E["点击查询按钮"]
|
||||||
|
E --> F{"查询结果?"}
|
||||||
|
F -- "有数据" --> G["显示手术安排列表"]
|
||||||
|
F -- "无数据" --> H["显示无数据提示"]
|
||||||
|
G --> I["底部分页操作"]
|
||||||
|
I -- "编辑" --> J["打开带数据的弹窗"]
|
||||||
|
J --> K["修改字段"]
|
||||||
|
K --> L["点击保存"]
|
||||||
|
L --> M{"验证通过?"}
|
||||||
|
M -- "是" --> N["更新表格数据"]
|
||||||
|
M -- "否" --> O["显示错误提示"]
|
||||||
|
I -- "查看" --> P["打开只读详情弹窗"]
|
||||||
|
P --> Q{"是否要删除?"}
|
||||||
|
Q -- "是" --> T["弹出确认对话框"]
|
||||||
|
Q -- "否" --> S["关闭详情弹窗"]
|
||||||
|
I -- "删除" --> T["弹出确认对话框"]
|
||||||
|
T --> U{"确认删除?"}
|
||||||
|
U -- "是" --> V["更新列表显示"]
|
||||||
|
U -- "否" --> S
|
||||||
|
C -- "新增" --> W["打开空白手术安排弹窗"]
|
||||||
|
W --> X["填写手术信息"]
|
||||||
|
X --> Y{"是否关联手术申请?"}
|
||||||
|
Y -- "是" --> Z["打开手术申请查询弹窗"]
|
||||||
|
Z --> AA["填写查询条件并查询"]
|
||||||
|
AA --> AB{"验证通过?"}
|
||||||
|
AB -- "是" --> AC["保存数据到op_schedule表"]
|
||||||
|
AB -- "否" --> AD["高亮错误字段提示"]
|
||||||
|
AC --> AE["新增记录到表格首行"]
|
||||||
|
Y -- "否" --> AF["直接填写表单"]
|
||||||
|
AF --> AG["填写手术安排信息"]
|
||||||
|
AG --> L["点击保存"]
|
||||||
|
C -- "重置" --> AH["清空所有筛选条件"]
|
||||||
|
C -- "导出" --> AI["收集当前表格数据"]
|
||||||
|
AI --> AJ["生成CSV文件并下载"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 二、整体布局分析
|
||||||
|
|
||||||
|
**页面宽度**:自适应布局
|
||||||
|
**主要区域划分**:
|
||||||
|
|
||||||
|
1. 顶部筛选操作区
|
||||||
|
2. 中间表格列表区
|
||||||
|
3. 底部分页区
|
||||||
|
4. 手术安排弹窗(模态框)
|
||||||
|
5. 手术申请查询弹窗(模态框)
|
||||||
|
**布局方式**:上下布局为主,弹窗采用居中模态框布局
|
||||||
|
|
||||||
|
**布局特点**:上下布局风格的组件
|
||||||
|
**响应式要求**:
|
||||||
|
|
||||||
|
* 桌面端:完整展示所有筛选条件和表格列
|
||||||
|
|
||||||
|
### 三、页面区域详细描述
|
||||||
|
|
||||||
|
#### 1. 顶部筛选区
|
||||||
|
|
||||||
|
**区域位置**:页面顶部
|
||||||
|
**区域尺寸**:100%宽度,内边距16px
|
||||||
|
**区域功能**:手术申请单的筛选和快捷操作
|
||||||
|
**包含元素**:
|
||||||
|
|
||||||
|
* 安排时间选择器
|
||||||
|
+ 元素类型:日期选择输入框
|
||||||
|
+ 默认值:空
|
||||||
|
+ 交互行为:点击弹出日期选择器
|
||||||
|
* 卫生机构下拉框
|
||||||
|
+ 元素类型:下拉选择框
|
||||||
|
+ 默认值:当前登录用户所属机构名称
|
||||||
|
+ 选项:默认当前登录用户所属机构名称
|
||||||
|
* 申请科室下拉框
|
||||||
|
+ 元素类型:下拉选择框
|
||||||
|
+ 默认值:“请选择”
|
||||||
|
+ 选项:取值于科室管理的科室分类字段:门诊
|
||||||
|
* 姓名/拼音码输入框
|
||||||
|
+ 元素类型:文本输入框
|
||||||
|
+ 默认值:空
|
||||||
|
+ 占位文本:“姓名/拼音码”
|
||||||
|
* 查询按钮
|
||||||
|
+ 元素类型:主要操作按钮
|
||||||
|
+ 样式:蓝色背景,白色文字
|
||||||
|
+ 交互行为:点击执行表格数据筛选
|
||||||
|
* 重置按钮
|
||||||
|
+ 元素类型:次要按钮
|
||||||
|
+ 样式:灰色背景,黑色文字
|
||||||
|
+ 交互行为:点击清空所有筛选条件
|
||||||
|
* 新增按钮
|
||||||
|
+ 元素类型:主要操作按钮
|
||||||
|
+ 样式:蓝色背景,白色文字
|
||||||
|
+ 交互行为:点击打开新增手术安排弹窗
|
||||||
|
* 导出表格按钮
|
||||||
|
+ 元素类型:成功状态按钮
|
||||||
|
+ 样式:绿色背景,白色文字
|
||||||
|
+ 交互行为:点击导出当前表格数据为CSV文件
|
||||||
|
|
||||||
|
#### 2. 中部表格区
|
||||||
|
|
||||||
|
**区域位置**:筛选区下方
|
||||||
|
**区域尺寸**:100%宽度,自适应高度
|
||||||
|
**区域功能**:展示手术安排列表数据,提供行操作功能
|
||||||
|
**包含元素**:
|
||||||
|
|
||||||
|
* 手术安排数据表格
|
||||||
|
+ 列1:ID - 数字 - 示例值:100
|
||||||
|
+ 列2:卫生机构 - 文本 - 示例值:“演示医院”
|
||||||
|
+ 列3:姓名 - 文本 - 示例值:“张明娟”
|
||||||
|
+ 列4:就诊卡号 - 文本 - 示例值:“27364”
|
||||||
|
+ 列5:手术单号 - 文本 - 示例值:“202510270001”
|
||||||
|
+ 列6:手术名称 - 文本 - 示例值:“肠系膜固定术”
|
||||||
|
+ 列7:申请科室 - 文本 - 示例值:“ICU”
|
||||||
|
+ 列8:手术类型 - 文本 - 示例值:“急诊”
|
||||||
|
+ 列9:手术性质 - 文本 - 示例值:“急诊手术”
|
||||||
|
+ 列10:主刀医生 - 文本 - 示例值:“杨海”
|
||||||
|
+ 列11:麻醉方法 - 文本 - 示例值:“静吸复合全麻”
|
||||||
|
+ 列12:安排时间 - 日期时间 - 示例值:“2025-10-27 16:09:39”
|
||||||
|
+ 列13:操作人 - 文本 - 示例值:“演示测试”
|
||||||
|
+ 列14:操作 - 操作按钮组
|
||||||
|
- 编辑按钮:铅笔图标,点击打开编辑手术安排弹窗
|
||||||
|
- 查看按钮:眼睛图标,点击打开查看手术安排弹窗
|
||||||
|
- 删除按钮:垃圾桶图标,点击取消当前行手术安排记录(op_schedule.oper_status :3-取消)
|
||||||
|
* 表格交互:
|
||||||
|
+ 行悬停效果:浅灰色背景
|
||||||
|
+ 行选中效果:蓝色边框和浅蓝色背景
|
||||||
|
|
||||||
|
#### 3. 底部分页区
|
||||||
|
|
||||||
|
**区域位置**:页面底部
|
||||||
|
**区域功能**:显示数据总量和分页控制
|
||||||
|
**包含元素**:
|
||||||
|
|
||||||
|
* 总数显示
|
||||||
|
+ 元素类型:文本
|
||||||
|
+ 内容格式:“总数:X”
|
||||||
|
* 分页按钮组
|
||||||
|
+ 上一页按钮:"<"符号
|
||||||
|
+ 页码按钮:当前页码,激活状态为蓝色背景
|
||||||
|
+ 下一页按钮:">"符号
|
||||||
|
|
||||||
|
#### 4. 手术安排弹窗(模态框)
|
||||||
|
|
||||||
|
**区域位置**:居中覆盖全屏
|
||||||
|
**区域尺寸**:自适应
|
||||||
|
**区域功能**:展示和编辑手术安排详细信息
|
||||||
|
**包含元素**:
|
||||||
|
|
||||||
|
* 弹窗头部
|
||||||
|
+ 标题:“手术安排”
|
||||||
|
+ 操作按钮组:【查找】、【刷新】、【返回】、【保存】
|
||||||
|
|
||||||
|
【刷新】--重置手术安排界面的内容
|
||||||
|
|
||||||
|
* 表单内容区
|
||||||
|
+ 病人基本信息组:就诊卡号、姓名、性别、年龄等(只读,从手术申请界面引入病人信息)
|
||||||
|
+ 手术申请信息组:手术单号、手术名称、申请科室等(只读,从手术申请界面引入病人手术申请信息)
|
||||||
|
+ 手术安排组:安排时间、手术台次、手术间号等(填写)
|
||||||
|
+ 医护人员组:主刀医生、助手、护士等(填写)
|
||||||
|
+ 手术过程组:入室时间、麻醉时间、手术时间等(填写)
|
||||||
|
+ 备注信息组:对话信息、备注等(填写)
|
||||||
|
* 表单元素特点:
|
||||||
|
+ 只读字段:灰色背景,不可编辑
|
||||||
|
+ 必填字段:标有"*"号
|
||||||
|
+ 时间选择器:带时钟图标
|
||||||
|
+ 单选按钮组:水平排列
|
||||||
|
+ 宽文本域:可垂直调整高度
|
||||||
|
|
||||||
|
#### 5. 手术申请查询弹窗(模态框)
|
||||||
|
|
||||||
|
**区域位置**:居中覆盖全屏
|
||||||
|
**区域功能**:查询并选择手术申请单
|
||||||
|
**包含元素**:
|
||||||
|
|
||||||
|
* 查询条件区
|
||||||
|
+ 申请时间范围选择器
|
||||||
|
+ 申请科室下拉框
|
||||||
|
+ 主刀医生下拉框
|
||||||
|
+ 关键词搜索框
|
||||||
|
+ 查询按钮
|
||||||
|
* 结果表格区
|
||||||
|
+ 列1:ID - 数字 - 示例值:142
|
||||||
|
+ 列2:姓名 - 文本 - 示例值:“张一山”
|
||||||
|
+ 列3:手术单号 - 文本 - 示例值:“202504290001”
|
||||||
|
+ 列4:手术名称 - 文本 - 示例值:“腋臭切除术”
|
||||||
|
+ 列5:申请科室 - 文本 - 示例值:“外科”
|
||||||
|
+ 列6:手术类型 - 文本 - 示例值:“急诊”
|
||||||
|
+ 列7:手术等级 - 文本 - 示例值:“一级手术”
|
||||||
|
+ 列8:主刀医生 - 文本 - 示例值:“演示测试”
|
||||||
|
* 底部操作区
|
||||||
|
+ 取消按钮
|
||||||
|
+ 确认按钮
|
||||||
|
|
||||||
|
### 四、交互功能详细说明
|
||||||
|
|
||||||
|
#### 1. 手术申请查询功能
|
||||||
|
|
||||||
|
**触发方式**:点击"查找"按钮
|
||||||
|
**执行流程**:
|
||||||
|
|
||||||
|
1. 打开手术申请查询弹窗
|
||||||
|
2. 填写查询条件(可多条件组合)
|
||||||
|
3. 点击"查询"按钮获取结果
|
||||||
|
4. 选择需要的手术申请记录
|
||||||
|
5. 点击"确认"按钮带回数据(手术安排界面)
|
||||||
|
**反馈机制**:
|
||||||
|
|
||||||
|
* 查询无结果时显示提示信息
|
||||||
|
* 未选择记录时点击确认提示"请先选择一条手术申请记录"
|
||||||
|
**异常处理**:
|
||||||
|
* 网络异常时显示错误提示
|
||||||
|
* 查询超时自动重试一次
|
||||||
|
|
||||||
|
#### 2. 新增手术安排功能
|
||||||
|
|
||||||
|
**触发方式**:点击"新增"按钮
|
||||||
|
**执行流程**:
|
||||||
|
|
||||||
|
1. 打开空白的"手术安排"弹窗
|
||||||
|
2. 填写各项手术信息(可点击"查找"按钮关联手术申请)
|
||||||
|
3. 点击"保存"按钮提交数据—写入手术安排表(op_schedule)
|
||||||
|
4. 新记录添加到表格首行
|
||||||
|
|
||||||
|
·· ①、写入手术安排表(op_schedule)
|
||||||
|
|
||||||
|
②、更新门诊手术申请单主表(**outp_surgery_apply**) : confirm_time、confirm_op_id、status字段
|
||||||
|
|
||||||
|
UPDATE outp_surgery_apply
|
||||||
|
|
||||||
|
SET confirm_time = NOW(),
|
||||||
|
|
||||||
|
confirm_op_id = *#{confirmOpId},*
|
||||||
|
|
||||||
|
status = 1 *-- 更新状态为已排程*
|
||||||
|
|
||||||
|
WHERE apply_id = *#{applyId};*
|
||||||
|
|
||||||
|
**反馈机制**:
|
||||||
|
|
||||||
|
* 必填字段未填写时提示
|
||||||
|
* 保存成功显示提示信息
|
||||||
|
**异常处理**:
|
||||||
|
* 手术单号重复时提示并允许修改
|
||||||
|
* 表单验证不通过时高亮错误字段
|
||||||
|
|
||||||
|
#### 3. 编辑手术安排功能
|
||||||
|
|
||||||
|
**触发方式**:点击行操作中的"编辑"按钮
|
||||||
|
**执行流程**:
|
||||||
|
|
||||||
|
1. 打开带数据的"手术安排"弹窗
|
||||||
|
2. 修改需要调整的字段
|
||||||
|
3. 点击"保存"按钮更新数据
|
||||||
|
4. 表格中对应行数据更新
|
||||||
|
**反馈机制**:
|
||||||
|
|
||||||
|
* 保存成功显示"手术安排已更新"提示
|
||||||
|
**异常处理**:
|
||||||
|
* 数据冲突时提示并允许重新加载
|
||||||
|
|
||||||
|
#### 4. 删除手术申请单
|
||||||
|
|
||||||
|
**触发方式**:点击表格行中的"删除"按钮
|
||||||
|
**执行流程**:
|
||||||
|
|
||||||
|
1. 弹出确认对弹框输入取消原因
|
||||||
|
2. 确认后执行删除
|
||||||
|
3. 更新列表数据
|
||||||
|
|
||||||
|
①、更新手术安排表(op_schedule)status字段
|
||||||
|
```sql
|
||||||
|
UPDATE op_schedule
|
||||||
|
|
||||||
|
SET status = 3 *-- 更新状态为已取消*
|
||||||
|
|
||||||
|
WHERE schedule_id = *#{scheduleId};*
|
||||||
|
|
||||||
|
②、更新门诊手术申请单主表(**outp_surgery_apply**) cancel_time、cancel_reason 、status字段
|
||||||
|
|
||||||
|
UPDATE outp_surgery_apply
|
||||||
|
|
||||||
|
SET cancel_time = NOW(),
|
||||||
|
|
||||||
|
cancel_reason = *#{cancelReason},*
|
||||||
|
|
||||||
|
status = 2,
|
||||||
|
|
||||||
|
updated_time = NOW()
|
||||||
|
|
||||||
|
WHERE apply_id = *#{applyId};*
|
||||||
|
```
|
||||||
|
**反馈机制**:
|
||||||
|
|
||||||
|
* 成功:提示"已取消ID为XX的手术安排"
|
||||||
|
* 失败:提示具体错误原因
|
||||||
|
**异常处理**:
|
||||||
|
* 数据已被引用:提示"该手术申请已被引用,无法取消"
|
||||||
|
|
||||||
|
#### 5. 数据导出功能
|
||||||
|
|
||||||
|
**触发方式**:点击"导出表格"按钮
|
||||||
|
**执行流程**:
|
||||||
|
|
||||||
|
1. 收集当前表格显示的数据(含筛选结果)
|
||||||
|
2. 生成CSV格式文件
|
||||||
|
3. 自动下载文件
|
||||||
|
**反馈机制**:
|
||||||
|
|
||||||
|
* 下载完成后显示"表格数据已导出为CSV文件"提示
|
||||||
|
**异常处理**:
|
||||||
|
* 数据量过大时分批处理
|
||||||
|
* 导出失败时提示具体原因
|
||||||
|
|
||||||
|
### 五、数据结构说明
|
||||||
|
|
||||||
|
**关键数据字段**:
|
||||||
|
|
||||||
|
手术安排表(op_schedule)
|
||||||
|
|
||||||
|
|
||||||
|
| **字段名称** | **数据类型** | **是否为空** | **说明/典型值** | **外键/来源** |
|
||||||
|
| ----------------------- | ------------ | ------------ | ---------------------------------------------- | ----------------------------------------------- |
|
||||||
|
| schedule_id | BIGINT | N | 排程号(主键) | 自增 |
|
||||||
|
| apply_id | BIGINT | N | 关联申请单 | → outp_surgery_apply.apply_id |
|
||||||
|
| patient_id | BIGINT | N | 患者号 | 患者档案表主键 |
|
||||||
|
| visit_id | BIGINT | N | 就诊号 | 本次就诊记录表的主键 |
|
||||||
|
| oper_code | VARCHAR(12) | N | 手术编码 | 取值手术申请单 |
|
||||||
|
| oper_name | VARCHAR(200) | N | 手术名称 | 取值手术申请单 |
|
||||||
|
| preoperative_diagnosis | VARCHAR(200) | N | 术前诊断名称 | 取值手术申请单的术前诊断 |
|
||||||
|
| postoperative_diagnosis | VARCHAR(200) | Y | 术后诊断名称 | 术后医护填写,取值于系统管理-》诊断目录的字典库 |
|
||||||
|
| schedule_date | DATE | N | 实际排程日期 | 护士选择 |
|
||||||
|
| sequence_no | INT | N | 台次(当天第几台) | 护士录入 |
|
||||||
|
| is_first_surgery | TINYINT | N | 是否首次手术(0=否,1=是) | |
|
||||||
|
| is_allergy_medication | TINYINT | N | 是否过敏药物 (0=否,1=是) | |
|
||||||
|
| allergy_remark | VARCHAR(500) | Y | 过敏药物备注(详细描述 | |
|
||||||
|
| surgery_nature | VARCHAR(20) | N | 手术性质(如:择期、急诊、计划性) | 下拉选项取值于字典管理:手术性质 |
|
||||||
|
| surgery_site | VARCHAR(20) | N | 手术部位(如:右腕部、左膝关节) | 下拉选项取值于字典管理:手术部位 |
|
||||||
|
| admission_time | DATETIME | Y | 入室时间 | 患者进入手术室区域的时间 |
|
||||||
|
| entry_time | DATETIME | Y | 进室时间 | 患者进入具体手术间的时间 |
|
||||||
|
| room_code | VARCHAR(10) | N | 手术间号 | → his_or_room.room_code |
|
||||||
|
| table_no | CHAR(1) | N | 手术台(A/B) | 下拉选项取值于字典管理:手术台 |
|
||||||
|
| anes_method | VARCHAR(8) | N | 麻醉方法 | 取值手术申请单(可改) |
|
||||||
|
| anes_doctor1_code | VARCHAR(12) | N | 麻醉医生1 | 下拉选项取值于用户管理表角色是医生(存主键) |
|
||||||
|
| anes_doctor2_code | VARCHAR(12) | N | 麻醉医生2 | 下拉选项取值于用户管理表角色是医生(存主键) |
|
||||||
|
| anes_doctor3_code | VARCHAR(12) | N | 麻醉医生3 | 下拉选项取值于用户管理表角色是医生(存主键) |
|
||||||
|
| scrub_nurse_code | VARCHAR(12) | N | 洗手护士 | 下拉选项取值于用户管理表角色是护士(存主键) |
|
||||||
|
| circu_nurse1_code | VARCHAR(12) | N | 巡回护士1 | 下拉选项取值于用户管理表角色是护士(存主键) |
|
||||||
|
| circu_nurse2_code | VARCHAR(12) | N | 巡回护士2 | 下拉选项取值于用户管理表角色是护士(存主键) |
|
||||||
|
| scrub_nurse1_code | VARCHAR(12) | N | 器械护士1 | 下拉选项取值于用户管理表角色是护士(存主键) |
|
||||||
|
| scrub_nurse2_code | VARCHAR(12) | N | 器械护士2 | 下拉选项取值于用户管理表角色是护士(存主键) |
|
||||||
|
| surgeon_code | VARCHAR(12) | N | 主刀医生 | 下拉选项:默认取值手术申请单(可改) |
|
||||||
|
| assistant1_code | VARCHAR(12) | Y | 助手1 | 下拉选项:默认取值手术申请单(可改) |
|
||||||
|
| assistant2_code | VARCHAR(12) | Y | 助手2 | 下拉选项:默认取值手术申请单(可改) |
|
||||||
|
| Assistant3_code | VARCHAR(12) | Y | 助手3 | 下拉选项:默认取值手术申请单(可改) |
|
||||||
|
| start_time | DATETIME | Y | 切开时间 | 麻醉记录单回写 |
|
||||||
|
| end_time | DATETIME | Y | 手术结束时间 | 麻醉记录单回写 |
|
||||||
|
| anes_start | DATETIME | Y | 麻醉开始时间 | 麻醉记录单回写 |
|
||||||
|
| anes_end | DATETIME | Y | 麻醉结束时间 | 麻醉记录单回写 |
|
||||||
|
| oper_status | TINYINT | N | 手术状态(0-待手术,1-进行中,2-完成,3-取消) | 状态机 |
|
||||||
|
| implant_flag | TINYINT | N | 实际植入标志(0/1) | 手术中确认 |
|
||||||
|
| implant_serial | VARCHAR(300) | Y | 植入物序列号批号 | 扫码录入 |
|
||||||
|
| blood_loss | INT | Y | 出血量(ml) | 手术记录回写 |
|
||||||
|
| blood_trans | INT | Y | 输血量(ml) | 手术记录回写 |
|
||||||
|
| infection_diagnosis | VARCHAR(200) | Y | 感染诊断名称 | 常在患者出现感染症状后填写 |
|
||||||
|
| isolation_type | VARCHAR(50) | Y | 隔离种类 | |
|
||||||
|
| patient_weight | DECIMAL(5,2) | Y | 患者体重(单位:kg) | |
|
||||||
|
| patient_height | DECIMAL(5,2) | Y | 患者身高(单位:cm) | |
|
||||||
|
| communication_info | VARCHAR(500) | Y | 手术相关对话信息 | |
|
||||||
|
| remark | VARCHAR(500) | Y | 手术相关备注 | |
|
||||||
|
| create_time | DATETIME | N | 排程创建时间 | now()系统自动写入 |
|
||||||
|
| creator_id | VARCHAR(12) | N | 排程护士 | 创建手术安排时系统自动写入 |
|
||||||
|
|
||||||
|
### 六、开发实现要点
|
||||||
|
|
||||||
|
**样式规范**:
|
||||||
|
|
||||||
|
* 主色调:#1890FF(操作按钮/选中状态)
|
||||||
|
* 辅助色:#00BA7C(成功状态)
|
||||||
|
* 字体:14px/1.5 使用系统默认字体栈
|
||||||
|
|
||||||
|
**技术要求**:
|
||||||
|
|
||||||
|
1. 时间控件需兼容操作
|
||||||
|
2. 表格支持万级数据量流畅滚动
|
||||||
|
|
||||||
|
**注意事项**:
|
||||||
|
|
||||||
|
1. 手术间选择需实时校验冲突
|
||||||
|
2. 医生选择器需要支持拼音首字母检索
|
||||||
|
3. 所有时间字段需统一处理时区问题
|
||||||
|
|
||||||
|
### 七、特殊交互说明
|
||||||
|
|
||||||
|
1. **手术间号选择联动**:
|
||||||
|
* 显示该手术间号当前时间段的手术安排情况
|
||||||
|
* 下拉选项取值于手术室维护的基础数据。
|
||||||
|
2. **紧急手术标记**:
|
||||||
|
* 急诊手术类型需显示红色角标
|
||||||
|
* 自动优先排在手术申请队列最上方
|
||||||
|
3. **术后诊断名称**:
|
||||||
|
* 做成调取诊断目录字典库填写(可以通过拼音首字母/名称进行查找)
|
||||||
|
|
||||||
|
取值于如下如:
|
||||||
|
|
||||||
|

|
||||||
@@ -52,6 +52,8 @@
|
|||||||
<el-table-column label="序号" type="index" align="center" width="60" />
|
<el-table-column label="序号" type="index" align="center" width="60" />
|
||||||
<el-table-column label="手术室编码" align="center" prop="busNo" width="120" show-overflow-tooltip />
|
<el-table-column label="手术室编码" align="center" prop="busNo" width="120" show-overflow-tooltip />
|
||||||
<el-table-column label="手术室名称" align="center" prop="name" min-width="150" show-overflow-tooltip />
|
<el-table-column label="手术室名称" align="center" prop="name" min-width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column label="类型" align="center" prop="roomTypeEnum_dictText" width="100" />
|
||||||
|
<el-table-column label="所属科室" align="center" prop="organizationName" width="120" show-overflow-tooltip />
|
||||||
<el-table-column label="位置描述" align="center" prop="locationDescription" min-width="150" show-overflow-tooltip />
|
<el-table-column label="位置描述" align="center" prop="locationDescription" min-width="150" show-overflow-tooltip />
|
||||||
<el-table-column label="设备配置" align="center" prop="equipmentConfig" min-width="200" show-overflow-tooltip />
|
<el-table-column label="设备配置" align="center" prop="equipmentConfig" min-width="200" show-overflow-tooltip />
|
||||||
<el-table-column label="容纳人数" align="center" prop="capacity" width="100" />
|
<el-table-column label="容纳人数" align="center" prop="capacity" width="100" />
|
||||||
@@ -109,6 +111,18 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="类型" prop="roomTypeEnum">
|
||||||
|
<el-select v-model="form.roomTypeEnum" placeholder="请选择类型" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in roomTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="所属科室" prop="organizationId">
|
<el-form-item label="所属科室" prop="organizationId">
|
||||||
<el-select
|
<el-select
|
||||||
@@ -128,6 +142,9 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="状态" prop="statusEnum">
|
<el-form-item label="状态" prop="statusEnum">
|
||||||
<el-select v-model="form.statusEnum" placeholder="请选择状态" style="width: 100%">
|
<el-select v-model="form.statusEnum" placeholder="请选择状态" style="width: 100%">
|
||||||
@@ -196,6 +213,7 @@
|
|||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="手术室编码">{{ viewData.busNo }}</el-descriptions-item>
|
<el-descriptions-item label="手术室编码">{{ viewData.busNo }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="手术室名称">{{ viewData.name }}</el-descriptions-item>
|
<el-descriptions-item label="手术室名称">{{ viewData.name }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="类型">{{ viewData.roomTypeEnum_dictText }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="位置描述">{{ viewData.locationDescription }}</el-descriptions-item>
|
<el-descriptions-item label="位置描述">{{ viewData.locationDescription }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="容纳人数">{{ viewData.capacity }}</el-descriptions-item>
|
<el-descriptions-item label="容纳人数">{{ viewData.capacity }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="所属科室">{{ viewData.organizationName }}</el-descriptions-item>
|
<el-descriptions-item label="所属科室">{{ viewData.organizationName }}</el-descriptions-item>
|
||||||
@@ -260,6 +278,7 @@ const form = ref({
|
|||||||
id: undefined,
|
id: undefined,
|
||||||
busNo: undefined,
|
busNo: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
|
roomTypeEnum: undefined,
|
||||||
organizationId: undefined,
|
organizationId: undefined,
|
||||||
locationDescription: undefined,
|
locationDescription: undefined,
|
||||||
equipmentConfig: undefined,
|
equipmentConfig: undefined,
|
||||||
@@ -272,6 +291,13 @@ const form = ref({
|
|||||||
const operatingRoomRef = ref()
|
const operatingRoomRef = ref()
|
||||||
const viewData = ref({})
|
const viewData = ref({})
|
||||||
|
|
||||||
|
const roomTypeOptions = ref([
|
||||||
|
{ value: 1, label: '急诊手术室' },
|
||||||
|
{ value: 2, label: '择期手术室' },
|
||||||
|
{ value: 3, label: '日间手术室' },
|
||||||
|
{ value: 4, label: '复合手术室' }
|
||||||
|
])
|
||||||
|
|
||||||
const statusOptions = ref([
|
const statusOptions = ref([
|
||||||
{ value: 1, label: '启用' },
|
{ value: 1, label: '启用' },
|
||||||
{ value: 0, label: '停用' }
|
{ value: 0, label: '停用' }
|
||||||
@@ -344,6 +370,7 @@ function reset() {
|
|||||||
id: undefined,
|
id: undefined,
|
||||||
busNo: undefined,
|
busNo: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
|
roomTypeEnum: undefined,
|
||||||
organizationId: undefined,
|
organizationId: undefined,
|
||||||
locationDescription: undefined,
|
locationDescription: undefined,
|
||||||
equipmentConfig: undefined,
|
equipmentConfig: undefined,
|
||||||
|
|||||||
@@ -118,9 +118,14 @@
|
|||||||
<script setup name="patientManagement">
|
<script setup name="patientManagement">
|
||||||
import pcas from 'china-division/dist/pcas-code.json';
|
import pcas from 'china-division/dist/pcas-code.json';
|
||||||
import {nextTick, ref} from 'vue';
|
import {nextTick, ref} from 'vue';
|
||||||
|
import {useRoute} from 'vue-router';
|
||||||
|
import {useRouter} from 'vue-router';
|
||||||
import {addPatient, listPatient, lists, updatePatient} from './component/api';
|
import {addPatient, listPatient, lists, updatePatient} from './component/api';
|
||||||
import PatientAddDialog from '@/views/charge/outpatientregistration/components/patientAddDialog';
|
import PatientAddDialog from '@/views/charge/outpatientregistration/components/patientAddDialog';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const showSearch = ref(true);
|
const showSearch = ref(true);
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const title = ref('');
|
const title = ref('');
|
||||||
@@ -178,7 +183,9 @@ const data = reactive({
|
|||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
searchKey: undefined,
|
searchKey: undefined,
|
||||||
name: undefined
|
name: undefined,
|
||||||
|
patientId: undefined, // 新增: 专门用于数据库ID查询
|
||||||
|
searchType: 'name' // 新增: 查询类型, 'name'按姓名查询, 'patientId'按病人ID查询
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
||||||
@@ -242,13 +249,25 @@ const findNodeByCode = (data, code) => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 查询患者列表 */
|
/** 查询患者列表 - 基础查询方法,用于初始化等操作 */
|
||||||
function getList() {
|
function getList() {
|
||||||
|
// 执行查询
|
||||||
listPatient(queryParams.value).then((response) => {
|
listPatient(queryParams.value).then((response) => {
|
||||||
patientList.value = response.data.records;
|
patientList.value = response.data.records;
|
||||||
total.value = response.data.total;
|
total.value = response.data.total;
|
||||||
console.log('patientList======>', JSON.stringify(patientList.value));
|
console.log('patientList======>', JSON.stringify(patientList.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 初始化字典数据(仅在第一次加载时执行)
|
||||||
|
if (!listsFlag.value) {
|
||||||
|
getInitDictData();
|
||||||
|
listsFlag.value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化字典数据 - 分离字典数据加载逻辑 */
|
||||||
|
const listsFlag = ref(false);
|
||||||
|
function getInitDictData() {
|
||||||
lists().then((response) => {
|
lists().then((response) => {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
occupationtypeList.value = response.data.occupationType;
|
occupationtypeList.value = response.data.occupationType;
|
||||||
@@ -262,6 +281,86 @@ function getList() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 - 支持按姓名和病人ID两种查询方式 */
|
||||||
|
function handleQuery() {
|
||||||
|
queryParams.value.pageNo = 1;
|
||||||
|
queryParams.value.createTimeSTime =
|
||||||
|
dateRange.value && dateRange.value.length == 2 ? dateRange.value[0] : '';
|
||||||
|
queryParams.value.createTimeETime =
|
||||||
|
dateRange.value && dateRange.value.length == 2 ? dateRange.value[1] : '';
|
||||||
|
|
||||||
|
// 根据查询类型设置查询参数
|
||||||
|
if (queryParams.value.searchType === 'patientId') {
|
||||||
|
// 按病人ID查询(数据库ID) - 直接传递ID参数
|
||||||
|
const queryParamsCopy = {
|
||||||
|
pageNo: queryParams.value.pageNo,
|
||||||
|
pageSize: queryParams.value.pageSize,
|
||||||
|
id: queryParams.value.patientId,
|
||||||
|
searchKey: undefined
|
||||||
|
};
|
||||||
|
console.log('按数据库ID查询参数:', queryParamsCopy);
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
listPatient(queryParamsCopy).then((response) => {
|
||||||
|
patientList.value = response.data.records;
|
||||||
|
total.value = response.data.total;
|
||||||
|
console.log('查询结果:', response.data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 按姓名/拼音码/病人ID查询(兼容原有逻辑)
|
||||||
|
queryParams.value.id = undefined;
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
listPatient(queryParams.value).then((response) => {
|
||||||
|
patientList.value = response.data.records;
|
||||||
|
total.value = response.data.total;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
dateRange.value = [];
|
||||||
|
proxy.resetForm('queryRef');
|
||||||
|
queryParams.value.patientId = undefined;
|
||||||
|
queryParams.value.searchType = 'name';
|
||||||
|
queryParams.value.id = undefined;
|
||||||
|
queryParams.value.name = undefined;
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 从门诊挂号页面跳转时的精确查询 - 按数据库ID查询 */
|
||||||
|
function queryByPatientId(patientId) {
|
||||||
|
console.log('收到门诊挂号传递的patientId:', patientId);
|
||||||
|
|
||||||
|
// 直接构造查询参数,避免受到其他条件干扰
|
||||||
|
const exactQueryParams = {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
id: patientId, // 直接使用ID字段进行精确查询
|
||||||
|
searchKey: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('精确查询参数:', exactQueryParams);
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
listPatient(exactQueryParams).then((response) => {
|
||||||
|
patientList.value = response.data.records;
|
||||||
|
total.value = response.data.total;
|
||||||
|
console.log('按数据库ID查询结果:', JSON.stringify(patientList.value));
|
||||||
|
console.log('查询到的患者数量:', response.data.records.length);
|
||||||
|
|
||||||
|
// 如果查询成功,清空patientId以免影响后续查询
|
||||||
|
if (response.data.records && response.data.records.length > 0) {
|
||||||
|
console.log('查询成功,找到患者:', response.data.records[0].name);
|
||||||
|
} else {
|
||||||
|
console.warn('未找到匹配的患者,ID:', patientId);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('查询失败:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/** 表单重置 */
|
/** 表单重置 */
|
||||||
function reset() {
|
function reset() {
|
||||||
form.value = {
|
form.value = {
|
||||||
@@ -305,23 +404,6 @@ function handlePatientAdded(patientData) {
|
|||||||
// 患者添加成功后刷新列表
|
// 患者添加成功后刷新列表
|
||||||
getList();
|
getList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
function handleQuery() {
|
|
||||||
queryParams.value.pageNo = 1;
|
|
||||||
queryParams.value.createTimeSTime =
|
|
||||||
dateRange.value && dateRange.value.length == 2 ? dateRange.value[0] : '';
|
|
||||||
queryParams.value.createTimeETime =
|
|
||||||
dateRange.value && dateRange.value.length == 2 ? dateRange.value[1] : '';
|
|
||||||
// 执行查询
|
|
||||||
getList();
|
|
||||||
}
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
function resetQuery() {
|
|
||||||
dateRange.value = [];
|
|
||||||
proxy.resetForm('queryRef');
|
|
||||||
handleQuery();
|
|
||||||
}
|
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
patientAddRef.value.show(); // 使用与门诊挂号一致的方式显示新增患者组件
|
patientAddRef.value.show(); // 使用与门诊挂号一致的方式显示新增患者组件
|
||||||
@@ -640,7 +722,14 @@ function submitForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList();
|
// 检查是否从门诊挂号页面跳转过来,并携带了patientId参数
|
||||||
|
if (route.query.patientId) {
|
||||||
|
// 使用精确查询方法按数据库ID查询
|
||||||
|
queryByPatientId(route.query.patientId);
|
||||||
|
} else {
|
||||||
|
// 正常加载患者列表
|
||||||
|
getList();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "work",
|
"name": "his",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
179
中医诊断主诊断功能实现说明.md
Normal file
179
中医诊断主诊断功能实现说明.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
# 中医诊断主诊断功能实现说明
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
中医诊断在添加时无法设置主诊断标记,导致保存后无法正确标识主诊断。
|
||||||
|
|
||||||
|
## 问题原因
|
||||||
|
在 `addDiagnosisDialog.vue` 中保存中医诊断时,没有传递 `maindiseFlag`(主诊断标记)字段到后端。
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 1. 前端修改
|
||||||
|
|
||||||
|
#### 1.1 添加主诊断UI(addDiagnosisDialog.vue)
|
||||||
|
在诊断详情区域为每个中医诊断添加了主诊断复选框:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<el-checkbox
|
||||||
|
v-model="item.isMain"
|
||||||
|
label="主诊断"
|
||||||
|
:true-label="true"
|
||||||
|
:false-label="false"
|
||||||
|
border
|
||||||
|
size="small"
|
||||||
|
style="margin-right: 10px;"
|
||||||
|
@change="(value) => handleMaindise(value, index)"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.2 添加主诊断逻辑处理
|
||||||
|
|
||||||
|
**新增诊断时的默认行为:**
|
||||||
|
- 第一个添加的中医诊断自动设置为主诊断
|
||||||
|
- 后续添加的诊断默认不是主诊断
|
||||||
|
|
||||||
|
**主诊断唯一性校验:**
|
||||||
|
```javascript
|
||||||
|
function handleMaindise(value, index) {
|
||||||
|
if (value) {
|
||||||
|
// 检查是否已有其他主诊断
|
||||||
|
let mainCount = 0;
|
||||||
|
tcmDiagonsisList.value.forEach((item, idx) => {
|
||||||
|
if (item.isMain && idx !== index) {
|
||||||
|
mainCount++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (mainCount > 0) {
|
||||||
|
// 取消当前选择
|
||||||
|
tcmDiagonsisList.value[index].isMain = false;
|
||||||
|
proxy.$modal.msgWarning('只能有一条主诊断');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新保存列表中的主诊断标记
|
||||||
|
const syndromeGroupNo = tcmDiagonsisList.value[index].syndromeGroupNo;
|
||||||
|
tcmDiagonsisSaveList.value.forEach((item, idx) => {
|
||||||
|
if (item.syndromeGroupNo === syndromeGroupNo) {
|
||||||
|
// 每个证候组有两条记录(病和证),只有第一条(病)设置主诊断标记
|
||||||
|
if (idx % 2 === 0 || tcmDiagonsisSaveList.value[idx - 1]?.syndromeGroupNo !== syndromeGroupNo) {
|
||||||
|
item.maindiseFlag = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 取消主诊断
|
||||||
|
const syndromeGroupNo = tcmDiagonsisList.value[index].syndromeGroupNo;
|
||||||
|
tcmDiagonsisSaveList.value.forEach((item) => {
|
||||||
|
if (item.syndromeGroupNo === syndromeGroupNo) {
|
||||||
|
item.maindiseFlag = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.3 保存时包含主诊断字段
|
||||||
|
|
||||||
|
**新增诊断时:**
|
||||||
|
```javascript
|
||||||
|
tcmDiagonsisSaveList.value.push({
|
||||||
|
definitionId: row.id,
|
||||||
|
ybNo: row.ybNo,
|
||||||
|
syndromeGroupNo: timestamp.value,
|
||||||
|
verificationStatusEnum: 4,
|
||||||
|
medTypeCode: '11',
|
||||||
|
maindiseFlag: isFirstDiagnosis ? 1 : 0, // 添加主诊断标记
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**修改诊断时:**
|
||||||
|
```javascript
|
||||||
|
tcmDiagonsisSaveList.value.push({
|
||||||
|
conditionId: item.conditionId,
|
||||||
|
updateId: updateIds[0],
|
||||||
|
definitionId: item.illnessDefinitionId,
|
||||||
|
ybNo: item.ybNo,
|
||||||
|
syndromeGroupNo: item.syndromeGroupNo,
|
||||||
|
verificationStatusEnum: 4,
|
||||||
|
medTypeCode: '11',
|
||||||
|
diagSrtNo: item.diagSrtNo,
|
||||||
|
maindiseFlag: isMain ? 1 : 0, // 保留原有的主诊断标记
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 1.4 诊断列表显示(diagnosis.vue)
|
||||||
|
|
||||||
|
在获取中医诊断列表时,正确读取并显示主诊断标记:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
form.value.diagnosisList.push({
|
||||||
|
name: item.name + '-' + res.data.symptom[index].name,
|
||||||
|
diagSrtNo: item.diagSrtNo,
|
||||||
|
ybNo: item.ybNo,
|
||||||
|
medTypeCode: item.medTypeCode,
|
||||||
|
syndromeGroupNo: item.syndromeGroupNo,
|
||||||
|
typeName: '中医诊断',
|
||||||
|
conditionId: item.conditionId,
|
||||||
|
symptomConditionId: res.data.symptom[index].conditionId,
|
||||||
|
updateId: item.encounterDiagnosisId + '-' + res.data.symptom[index].encounterDiagnosisId,
|
||||||
|
illnessDefinitionId: item.definitionId,
|
||||||
|
symptomDefinitionId: res.data.symptom[index].definitionId,
|
||||||
|
symptomYbNo: res.data.symptom[index].ybNo,
|
||||||
|
maindiseFlag: item.maindiseFlag || 0, // 添加主诊断标记
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 后端支持
|
||||||
|
|
||||||
|
后端已经支持 `maindiseFlag` 字段的保存和读取:
|
||||||
|
|
||||||
|
**SaveDiagnosisChildParam.java:**
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 主诊断标记 (1:是,0:否)
|
||||||
|
*/
|
||||||
|
private Integer maindiseFlag;
|
||||||
|
```
|
||||||
|
|
||||||
|
**DoctorStationChineseMedicalAppServiceImpl.java:**
|
||||||
|
```java
|
||||||
|
encounterDiagnosis.setMaindiseFlag(saveDiagnosisChildParam.getMaindiseFlag());
|
||||||
|
```
|
||||||
|
|
||||||
|
## 业务规则
|
||||||
|
|
||||||
|
1. **主诊断标记位置**:主诊断标记在"病"上(每个病-证组合的第一条记录)
|
||||||
|
2. **主诊断唯一性**:中医诊断只能有一个主诊断
|
||||||
|
3. **与西医诊断的关系**:中医诊断和西医诊断可以各有一个主诊断(互不冲突)
|
||||||
|
4. **默认行为**:第一个添加的中医诊断自动设置为主诊断
|
||||||
|
|
||||||
|
## 修改文件清单
|
||||||
|
|
||||||
|
1. `openhis-ui-vue3/src/views/doctorstation/components/diagnosis/addDiagnosisDialog.vue`
|
||||||
|
- 添加主诊断复选框UI
|
||||||
|
- 添加主诊断逻辑处理函数
|
||||||
|
- 修改保存数据时包含 maindiseFlag 字段
|
||||||
|
|
||||||
|
2. `openhis-ui-vue3/src/views/doctorstation/components/diagnosis/diagnosis.vue`
|
||||||
|
- 修改获取中医诊断列表时读取 maindiseFlag 字段
|
||||||
|
- 修改传递给对话框的数据包含 maindiseFlag 字段
|
||||||
|
|
||||||
|
## 测试要点
|
||||||
|
|
||||||
|
1. ✅ 新增中医诊断时,第一个诊断自动设置为主诊断
|
||||||
|
2. ✅ 可以手动勾选/取消主诊断复选框
|
||||||
|
3. ✅ 只能有一个主诊断(尝试勾选第二个时会提示错误)
|
||||||
|
4. ✅ 保存后主诊断标记正确保存到数据库
|
||||||
|
5. ✅ 刷新页面后主诊断标记正确显示
|
||||||
|
6. ✅ 修改已有诊断时,主诊断标记正确回显
|
||||||
|
7. ✅ 中医诊断和西医诊断的主诊断互不影响
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 中医诊断是"病-证"成对出现的,主诊断标记只设置在"病"上
|
||||||
|
2. 证候记录的 maindiseFlag 始终为 0
|
||||||
|
3. 主诊断唯一性校验只在中医诊断内部进行,不影响西医诊断
|
||||||
|
|
||||||
|
## 完成时间
|
||||||
|
2026年1月9日
|
||||||
Reference in New Issue
Block a user