@@ -1041,6 +1064,121 @@ onMounted(() => {
});
+// ==============================
+// 【修复】级联下拉框逻辑 (包含直接请求代码)
+// ==============================
+
+// 1. 定义响应式数据
+const parentTypeOptions = ref([]);
+
+// 2. 【核心】直接发送请求的方法
+// 这里直接使用 request 工具,不依赖外部 api 文件
+const fetchInspectionTypesRequest = (params) => {
+ return request({
+ url: '/system/inspection-type/list', // 你的后端接口地址
+ method: 'get',
+ params: params
+ });
+};
+
+// 3. 加载所有顶级大类
+const loadParentTypes = async () => {
+ try {
+ // 【发送请求】不传参数,获取所有数据
+ const res = await fetchInspectionTypesRequest({});
+
+ let allData = [];
+ // 兼容多种返回格式
+ if (res.code === 200) {
+ if(res.data && Array.isArray(res.data)) allData = res.data;
+ else if(res.data && res.data.rows) allData = res.data.rows;
+ else if(res.data && res.data.data && Array.isArray(res.data.data)) allData = res.data.data;
+ }
+
+ // 过滤:只保留 parentId 为 null/undefined 的记录作为“大类”
+ parentTypeOptions.value = allData.filter(item =>
+ item.parentId === null || item.parentId === undefined || item.parentId === ''
+ );
+ } catch (error) {
+ ElMessage.error('网络异常,加载大类失败');
+ }
+};
+
+// 4. 处理大类改变,联动加载子类
+const handleParentChange = async (selectedId, row) => {
+ // A. 更新当前行的显示名称
+ const selected = parentTypeOptions.value.find(t => t.id === selectedId);
+ row.inspectionTypeName = selected ? selected.name : '';
+
+ // B. 【重要】重置下级数据
+ row.subItemId = '';
+ row.subItemName = '';
+ row.subItemOptions = [];
+
+ if (!selectedId) return;
+
+ // C. 设置加载状态
+ row.loadingSubItems = true;
+
+ try {
+ // 【发送请求】传入 parentId 参数获取子类
+ const res = await fetchInspectionTypesRequest({ parentId: selectedId });
+
+ let subData = [];
+ if (res.code === 200) {
+ if(res.data && Array.isArray(res.data)) subData = res.data;
+ else if(res.data && res.data.rows) subData = res.data.rows;
+ else if(res.data && res.data.data && Array.isArray(res.data.data)) subData = res.data.data;
+
+ row.subItemOptions = subData;
+
+ // 可选优化:如果子类只有一个,自动选中
+ if (subData.length === 1) {
+ row.subItemId = subData[0].id;
+ row.subItemName = subData[0].name;
+ }
+ } else {
+ ElMessage.info('该分类下暂无子项目');
+ }
+ } catch (error) {
+ ElMessage.error('加载子项目失败');
+ } finally {
+ row.loadingSubItems = false;
+ }
+};
+
+// 5. 点击编辑按钮时触发
+const handleEditRow = (row) => {
+ if (editingRowId.value && editingRowId.value !== row.id) {
+ ElMessage.warning('请先保存或取消当前正在编辑的行');
+ return;
+ }
+
+ editingRowId.value = row.id;
+
+ // 初始化行内属性
+ if (!row.subItemOptions) row.subItemOptions = [];
+ row.loadingSubItems = false;
+
+ // 回显名称
+ if (row.inspectionTypeId && !row.inspectionTypeName) {
+ const p = parentTypeOptions.value.find(i => i.id === row.inspectionTypeId);
+ if (p) row.inspectionTypeName = p.name;
+ }
+
+ if (row.subItemId && row.subItemOptions.length > 0) {
+ const s = row.subItemOptions.find(i => i.id === row.subItemId);
+ if (s) row.subItemName = s.name;
+ }
+};
+
+onMounted(() => {
+ // ... 其他初始化代码
+ loadParentTypes(); // <--- 确保这一行存在
+ // ...
+});
+
+
// 样本类型数据
const sampleTypes = ref([
{ value: '血液', label: '血液' },
@@ -1154,7 +1292,7 @@ const loadObservationItems = async (resetPage = false) => {
testType: item.inspectionTypeId_dictText || item.testType || '', // 优先使用字典翻译字段
inspectionTypeId: item.inspectionTypeId || null, // 检验类型ID
package: '',
- sampleType: item.specimenCode_dictText || '',
+ sampleType: item.specimenCode || '',
amount: parseFloat(item.retailPrice || 0),
sortOrder: item.sortOrder || null,
serviceRange: item.serviceRange || '全部',
@@ -1782,7 +1920,7 @@ const saveItem = async (item) => {
return;
}
- if (!item.testType) {
+ if (!item.inspectionTypeId) {
ElMessage.error('检验类型不能为空');
return;
}
From 557f626c05fbc2138af075f4c415c5d240c17e7d Mon Sep 17 00:00:00 2001
From: wangjian963 <15215920+aprilry@user.noreply.gitee.com>
Date: Wed, 18 Mar 2026 18:04:29 +0800
Subject: [PATCH 5/9] =?UTF-8?q?=E4=BC=9A=E8=AF=8A=E7=AE=A1=E7=90=86-?=
=?UTF-8?q?=E3=80=8B=E9=97=A8=E8=AF=8A=E4=BC=9A=E8=AF=8A=E7=94=B3=E8=AF=B7?=
=?UTF-8?q?=E7=A1=AE=E8=AE=A4=EF=BC=9A=E8=A1=A5=E4=B8=8A=E5=AD=97=E6=AE=B5?=
=?UTF-8?q?=E2=80=9C=E4=BC=9A=E8=AF=8A=E7=A1=AE=E8=AE=A4=E5=8F=82=E5=8A=A0?=
=?UTF-8?q?=E5=8C=BB=E5=B8=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../consultationmanagement/consultationconfirmation/index.vue | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/openhis-ui-vue3/src/views/consultationmanagement/consultationconfirmation/index.vue b/openhis-ui-vue3/src/views/consultationmanagement/consultationconfirmation/index.vue
index 8258a41f..20dfd501 100644
--- a/openhis-ui-vue3/src/views/consultationmanagement/consultationconfirmation/index.vue
+++ b/openhis-ui-vue3/src/views/consultationmanagement/consultationconfirmation/index.vue
@@ -135,6 +135,10 @@
+
+
+
+
Date: Thu, 19 Mar 2026 09:19:03 +0800
Subject: [PATCH 6/9] 221,222,223,224,227,228,229,230,231
---
.../impl/DoctorScheduleAppServiceImpl.java | 40 ++-
.../controller/DoctorScheduleController.java | 3 +-
.../impl/OrganizationAppServiceImpl.java | 74 ++--
.../basedatamanage/dto/OrganizationDto.java | 13 +-
.../impl/DiagTreatMAppServiceImpl.java | 11 +-
.../DoctorScheduleMapper.xml | 15 +
.../administration/domain/Organization.java | 5 +
.../mapper/OrganizationMapper.java | 24 +-
.../domain/DoctorSchedule.java | 3 +
.../domain/DoctorScheduleWithDateDto.java | 3 +
.../administration/OrganizationMapper.xml | 51 ++-
.../appoinmentmanage/deptManage/index.vue | 334 +++++++++++-------
12 files changed, 387 insertions(+), 189 deletions(-)
diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/DoctorScheduleAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/DoctorScheduleAppServiceImpl.java
index c628202a..68e313a7 100644
--- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/DoctorScheduleAppServiceImpl.java
+++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/appservice/impl/DoctorScheduleAppServiceImpl.java
@@ -118,6 +118,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
newSchedule.setIsStopped(doctorSchedule.getIsStopped() != null ? doctorSchedule.getIsStopped() : false);
newSchedule.setStopReason(doctorSchedule.getStopReason() != null ? doctorSchedule.getStopReason() : "");
newSchedule.setDeptId(doctorSchedule.getDeptId());
+ newSchedule.setRegType(doctorSchedule.getRegType() != null ? doctorSchedule.getRegType() : 0);
newSchedule.setDoctorId(doctorSchedule.getDoctorId());
// 不设置id字段,让数据库自动生成
@@ -183,6 +184,7 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
newSchedule.setIsStopped(doctorSchedule.getIsStopped() != null ? doctorSchedule.getIsStopped() : false);
newSchedule.setStopReason(doctorSchedule.getStopReason() != null ? doctorSchedule.getStopReason() : "");
newSchedule.setDeptId(doctorSchedule.getDeptId());
+ newSchedule.setRegType(doctorSchedule.getRegType() != null ? doctorSchedule.getRegType() : 0);
newSchedule.setDoctorId(doctorSchedule.getDoctorId());
// 不设置id字段,让数据库自动生成
@@ -213,14 +215,48 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
}
}
+ @Transactional
@Override
public R> updateDoctorSchedule(DoctorSchedule doctorSchedule) {
if (ObjectUtil.isEmpty(doctorSchedule) || ObjectUtil.isEmpty(doctorSchedule.getId())) {
return R.fail("医生排班ID不能为空");
}
- // 注意:此为核心更新,暂未处理号源池和号源槽的同步更新
+
int result = doctorScheduleMapper.updateDoctorSchedule(doctorSchedule);
- return result > 0 ? R.ok(result) : R.fail("更新排班信息失败");
+ if (result <= 0) {
+ return R.fail("更新排班信息失败");
+ }
+
+ // 同步更新号源池,避免查询联表时医生/诊室等字段看起来“未更新”
+ boolean needSyncPool = doctorSchedule.getDoctorId() != null
+ || doctorSchedule.getDoctor() != null
+ || doctorSchedule.getClinic() != null
+ || doctorSchedule.getStartTime() != null
+ || doctorSchedule.getEndTime() != null
+ || doctorSchedule.getLimitNumber() != null
+ || doctorSchedule.getStopReason() != null
+ || doctorSchedule.getRegType() != null
+ || doctorSchedule.getRegisterFee() != null;
+
+ if (needSyncPool) {
+ schedulePoolService.lambdaUpdate()
+ .eq(SchedulePool::getScheduleId, doctorSchedule.getId())
+ .set(doctorSchedule.getDoctorId() != null, SchedulePool::getDoctorId, doctorSchedule.getDoctorId())
+ .set(doctorSchedule.getDoctor() != null, SchedulePool::getDoctorName, doctorSchedule.getDoctor())
+ .set(doctorSchedule.getClinic() != null, SchedulePool::getClinicRoom, doctorSchedule.getClinic())
+ .set(doctorSchedule.getStartTime() != null, SchedulePool::getStartTime, doctorSchedule.getStartTime())
+ .set(doctorSchedule.getEndTime() != null, SchedulePool::getEndTime, doctorSchedule.getEndTime())
+ .set(doctorSchedule.getLimitNumber() != null, SchedulePool::getTotalQuota,
+ doctorSchedule.getLimitNumber())
+ .set(doctorSchedule.getStopReason() != null, SchedulePool::getStopReason, doctorSchedule.getStopReason())
+ .set(doctorSchedule.getRegType() != null, SchedulePool::getRegType, String.valueOf(doctorSchedule.getRegType()))
+ .set(doctorSchedule.getRegisterFee() != null, SchedulePool::getFee, doctorSchedule.getRegisterFee() / 100.0)
+ .set(doctorSchedule.getRegisterFee() != null, SchedulePool::getInsurancePrice,
+ doctorSchedule.getRegisterFee() / 100.0)
+ .update();
+ }
+
+ return R.ok(result);
}
/**
diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/controller/DoctorScheduleController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/controller/DoctorScheduleController.java
index 2a7e8bf6..57d102d8 100644
--- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/controller/DoctorScheduleController.java
+++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/appointmentmanage/controller/DoctorScheduleController.java
@@ -53,7 +53,6 @@ public class DoctorScheduleController {
/*
* 新增医生排班(带具体日期)
- *
* */
@PostMapping("/add-with-date")
public R> addDoctorScheduleWithDate(@RequestBody DoctorSchedule doctorSchedule) {
@@ -77,7 +76,7 @@ public class DoctorScheduleController {
* */
@DeleteMapping("/delete/{doctorScheduleId}")
public R> removeDoctorSchedule(@PathVariable Integer doctorScheduleId){
- return R.ok(doctorScheduleAppService.removeDoctorSchedule(doctorScheduleId));
+ return doctorScheduleAppService.removeDoctorSchedule(doctorScheduleId);
}
/*
diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationAppServiceImpl.java
index 5c50cccf..a2f6e6be 100644
--- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationAppServiceImpl.java
+++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationAppServiceImpl.java
@@ -1,12 +1,14 @@
package com.openhis.web.basedatamanage.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.StringUtils;
import com.openhis.administration.domain.Organization;
+import com.openhis.administration.mapper.OrganizationMapper;
import com.openhis.administration.service.IOrganizationService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
@@ -35,12 +37,15 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
@Resource
private AssignSeqUtil assignSeqUtil;
+ @Resource
+ private OrganizationMapper organizationMapper;
+
@Override
public Page getOrganizationTree(Integer pageNo, Integer pageSize, String name, Integer typeEnum,
List classEnumList,
String sortField, String sortOrder, HttpServletRequest request) {
- // 使用Page对象进行分页查询
+ // 使用 Page 对象进行分页查询
Page page = new Page<>(pageNo, pageSize);
// 创建查询条件
@@ -54,7 +59,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
queryWrapper.eq(Organization::getTypeEnum, typeEnum);
}
if (classEnumList != null && !classEnumList.isEmpty()) {
- // 使用OR条件来匹配class_enum字段中包含任一值的记录
+ // 使用 OR 条件来匹配 class_enum 字段中包含任一值的记录
queryWrapper.and(wrapper -> {
for (int i = 0; i < classEnumList.size(); i++) {
String classEnum = classEnumList.get(i);
@@ -63,18 +68,18 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
wrapper.and(subWrapper -> {
subWrapper.eq(Organization::getClassEnum, classEnum) // 精确匹配
.or() // 或者
- .likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
+ .likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
.or() // 或者
.likeLeft(Organization::getClassEnum, "," + classEnum) // 以",值"结尾
.or() // 或者
.like(Organization::getClassEnum, "," + classEnum + ","); // 在中间,被逗号包围
});
} else {
- // 后续条件使用OR连接
+ // 后续条件使用 OR 连接
wrapper.or(subWrapper -> {
subWrapper.eq(Organization::getClassEnum, classEnum) // 精确匹配
.or() // 或者
- .likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
+ .likeRight(Organization::getClassEnum, classEnum + ",") // 以"值,"开头
.or() // 或者
.likeLeft(Organization::getClassEnum, "," + classEnum) // 以",值"结尾
.or() // 或者
@@ -88,7 +93,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
// 执行分页查询
Page resultPage = organizationService.page(page, queryWrapper);
- // 将查询结果转为DTO并构建树结构
+ // 将查询结果转为 DTO 并构建树结构
List organizationList = resultPage.getRecords();
List orgTree = buildTree(organizationList);
@@ -109,7 +114,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
* @return tree
*/
private List buildTree(List records) {
- // 按b_no的层级排序,确保父节点先处理
+ // 按 b_no 的层级排序,确保父节点先处理
List sortedRecords = records.stream()
.sorted(Comparator.comparingInt(r -> r.getBusNo().split("\\.").length)).collect(Collectors.toList());
@@ -131,7 +136,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
// 根节点
tree.add(node);
} else {
- // 获取父节点的b_no(去掉最后一部分)
+ // 获取父节点的 b_no(去掉最后一部分)
String parentBNo = String.join(".", Arrays.copyOf(parts, parts.length - 1));
OrganizationDto parent = nodeMap.get(parentBNo);
@@ -149,7 +154,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
/**
* 机构信息详情
*
- * @param orgId 机构信息id
+ * @param orgId 机构信息 id
* @return 机构信息详情
*/
@Override
@@ -159,7 +164,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, new Object[] { "机构信息" }));
}
- // 转换为DTO对象,确保数据格式一致
+ // 转换为 DTO 对象,确保数据格式一致
OrganizationDto organizationDto = new OrganizationDto();
BeanUtils.copyProperties(organization, organizationDto);
organizationDto
@@ -181,7 +186,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
@Override
public R> addOrEditOrganization(OrganizationDto organizationDto) {
- // 新增organization信息
+ // 新增 organization 信息
Organization organization = new Organization();
BeanUtils.copyProperties(organizationDto, organization);
@@ -191,9 +196,9 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
} else {
// 活动标识:有效
organization.setActiveFlag(AccountStatus.ACTIVE.getValue());
- // 采番bus_no三位
+ // 采番 bus_no 三位
String code = assignSeqUtil.getSeq(AssignSeqEnum.ORGANIZATION_BUS_NO.getPrefix(), 3);
- // 如果传了上级科室 把当前的code拼到后边
+ // 如果传了上级科室 把当前的 code 拼到后边
if (StringUtils.isNotEmpty(organization.getBusNo())) {
organization.setBusNo(String.format(CommonConstants.Common.MONTAGE_FORMAT, organization.getBusNo(),
CommonConstants.Common.POINT, code));
@@ -203,7 +208,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
// 生成待发送的机构信息
organizationService.save(organization);
}
- // 返回机构id
+ // 返回机构 id
return R.ok(organization.getId(),
MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] { "机构信息更新添加" }));
}
@@ -211,7 +216,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
/**
* 删除机构
*
- * @param orgIds 机构信息id
+ * @param orgIds 机构信息 id
* @return 操作结果
*/
@Override
@@ -232,7 +237,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
/**
* 机构启用
*
- * @param orgId 机构信息id
+ * @param orgId 机构信息 id
* @return 操作结果
*/
@Override
@@ -247,7 +252,7 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
/**
* 机构停用
*
- * @param orgId 机构信息id
+ * @param orgId 机构信息 id
* @return 操作结果
*/
@Override
@@ -299,38 +304,27 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
*/
@Override
public R> getRegisterOrganizations(Integer pageNo, Integer pageSize, String name, String orgName) {
- // 使用Page对象进行分页查询
+ // 使用 Page 对象进行分页查询
Page page = new Page<>(pageNo != null ? pageNo : 1, pageSize != null ? pageSize : 10);
- // 创建查询条件,只查询register_flag为1的组织机构
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(Organization::getRegisterFlag, 1); // 只获取挂号科室
- queryWrapper.eq(Organization::getDeleteFlag, "0"); // 确保未删除
+ // 使用 Mapper 方法关联查询 sys_tenant 表获取租户名称
+ IPage resultPage = organizationMapper.selectRegisterOrganizationsWithTenant(
+ page,
+ 1, // register_flag = 1
+ "0", // delete_flag = '0'
+ name,
+ orgName
+ );
- // 添加名称过滤条件
- if (StringUtils.isNotEmpty(name)) {
- queryWrapper.like(Organization::getName, name);
- }
-
- // 如果有机构名称筛选
- if (StringUtils.isNotEmpty(orgName)) {
- // 这里假设 orgName 是父机构名称,如果需要更复杂的关联查询可在此扩展
- // 当前逻辑暂保持与原逻辑一致的过滤方式或根据需求调整
- }
-
- // 按编码排序
- queryWrapper.orderByAsc(Organization::getBusNo);
-
- // 执行分页查询
- Page resultPage = organizationService.page(page, queryWrapper);
-
- // 转换为DTO对象并设置字典文本
+ // 转换为 DTO 对象并设置字典文本
List organizationDtoList = resultPage.getRecords().stream().map(org -> {
OrganizationDto dto = new OrganizationDto();
BeanUtils.copyProperties(org, dto);
dto.setTypeEnum_dictText(EnumUtils.getInfoByValue(OrganizationType.class, dto.getTypeEnum()));
dto.setClassEnum_dictText(formatClassEnumDictText(dto.getClassEnum()));
dto.setActiveFlag_dictText(EnumUtils.getInfoByValue(AccountStatus.class, dto.getActiveFlag()));
+ // 设置租户名称
+ dto.setOrgName(org.getTenantName());
return dto;
}).collect(Collectors.toList());
diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/dto/OrganizationDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/dto/OrganizationDto.java
index 28a17579..43ef819c 100644
--- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/dto/OrganizationDto.java
+++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/dto/OrganizationDto.java
@@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
-import lombok.ToString;
import java.util.ArrayList;
import java.util.List;
@@ -60,18 +59,20 @@ public class OrganizationDto {
private Integer displayOrder;
/** 子集合 */
- @ToString.Exclude
private List children = new ArrayList<>();
-
+
/** 挂号科室标记 */
private Integer registerFlag;
-
+
/** 科室位置 */
private String location;
-
+
/** 科室简介 */
private String intro;
-
+
/** 备注 */
private String remark;
+
+ /** 租户名称 */
+ private String orgName;
}
diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/datadictionary/appservice/impl/DiagTreatMAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/datadictionary/appservice/impl/DiagTreatMAppServiceImpl.java
index 569d95a8..9a59a2ee 100644
--- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/datadictionary/appservice/impl/DiagTreatMAppServiceImpl.java
+++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/datadictionary/appservice/impl/DiagTreatMAppServiceImpl.java
@@ -280,24 +280,19 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
}
/**
- * 获取诊查项目列表(医保类型为02)
+ * 获取诊查项目列表(医保类型为02,返回全量数据)
*
- * @param orgId 科室ID
+ * @param orgId 科室ID(兼容保留,不参与过滤)
* @return 诊查项目列表
*/
@Override
public R> getClinicItems(Long orgId) {
- // 构建查询条件,只查询医保类型为02(诊查费)的项目
+ // 构建查询条件,只查询医保类型为02(诊察费)的项目,不按科室过滤
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("T2.yb_type", "02"); // 使用T2表的yb_type字段,避免歧义
queryWrapper.eq("T1.delete_flag", "0"); // 只查询未删除的记录
queryWrapper.eq("T2.instance_table", "wor_activity_definition"); // 确保关联正确
- // 如果提供了科室ID,则过滤该科室的项目
- if (orgId != null) {
- queryWrapper.eq("T1.org_id", orgId); // 使用机构ID进行过滤
- }
-
// 分页查询,设置一个较大的页大小以获取所有诊查项目
IPage diseaseTreatmentPage
= activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page(1, 100), queryWrapper);
diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/appointmentmanage/DoctorScheduleMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/appointmentmanage/DoctorScheduleMapper.xml
index c8e2f766..f9558c1d 100644
--- a/openhis-server-new/openhis-application/src/main/resources/mapper/appointmentmanage/DoctorScheduleMapper.xml
+++ b/openhis-server-new/openhis-application/src/main/resources/mapper/appointmentmanage/DoctorScheduleMapper.xml
@@ -23,6 +23,7 @@
is_stopped,
stop_reason,
dept_id,
+ reg_type,
doctor_id
, create_time
, update_time
@@ -43,6 +44,7 @@
#{isStopped},
#{stopReason},
#{deptId},
+ #{regType},
#{doctorId}
, #{createTime}
, #{updateTime}
@@ -68,6 +70,7 @@
is_stopped = #{isStopped},
stop_reason = #{stopReason},
dept_id = #{deptId},
+ reg_type = #{regType},
doctor_id = #{doctorId},
update_time = #{updateTime}
@@ -97,12 +100,16 @@
ds.is_stopped AS is_stopped,
ds.stop_reason AS stop_reason,
ds.dept_id AS dept_id,
+ ds.reg_type AS reg_type,
sp.doctor_id AS doctor_id,
sp.schedule_date AS schedule_date
FROM adm_doctor_schedule ds
LEFT JOIN adm_schedule_pool sp ON sp.schedule_id = ds.id
+ AND sp.delete_flag = '0'
LEFT JOIN adm_organization org ON ds.dept_id = org.id
+ AND org.delete_flag = '0'
WHERE ds.dept_id = #{deptId}
+ AND ds.delete_flag = '0'
AND sp.schedule_date BETWEEN #{startDate}::date AND #{endDate}::date
ORDER BY sp.schedule_date, ds.time_period
@@ -129,12 +136,16 @@
ds.is_stopped AS is_stopped,
ds.stop_reason AS stop_reason,
ds.dept_id AS dept_id,
+ ds.reg_type AS reg_type,
sp.doctor_id AS doctor_id,
sp.schedule_date AS schedule_date
FROM adm_doctor_schedule ds
INNER JOIN adm_schedule_pool sp ON sp.schedule_id = ds.id
+ AND sp.delete_flag = '0'
LEFT JOIN adm_organization org ON ds.dept_id = org.id
+ AND org.delete_flag = '0'
WHERE sp.schedule_date = #{today}::date
+ AND ds.delete_flag = '0'
AND (ds.is_stopped = false OR ds.is_stopped IS NULL)
ORDER BY ds.time_period
@@ -161,12 +172,16 @@
ds.is_stopped AS is_stopped,
ds.stop_reason AS stop_reason,
ds.dept_id AS dept_id,
+ ds.reg_type AS reg_type,
sp.doctor_id AS doctor_id,
sp.schedule_date AS schedule_date
FROM adm_doctor_schedule ds
INNER JOIN adm_schedule_pool sp ON sp.schedule_id = ds.id
+ AND sp.delete_flag = '0'
LEFT JOIN adm_organization org ON ds.dept_id = org.id
+ AND org.delete_flag = '0'
WHERE sp.schedule_date = #{today}::date
+ AND ds.delete_flag = '0'
AND sp.doctor_id = #{doctorId}
AND (ds.is_stopped = false OR ds.is_stopped IS NULL)
ORDER BY ds.time_period
diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/domain/Organization.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/domain/Organization.java
index b6475da2..5539a54e 100644
--- a/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/domain/Organization.java
+++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/domain/Organization.java
@@ -1,6 +1,7 @@
package com.openhis.administration.domain;
import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.core.common.core.domain.HisBaseEntity;
@@ -91,4 +92,8 @@ public class Organization extends HisBaseEntity {
/** 备注 */
private String remark;
+
+ /** 租户名称(从 sys_tenant 表关联查询,非数据库字段) */
+ @TableField(exist = false)
+ private String tenantName;
}
diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/mapper/OrganizationMapper.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/mapper/OrganizationMapper.java
index db8266ad..e32f25fe 100644
--- a/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/mapper/OrganizationMapper.java
+++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/mapper/OrganizationMapper.java
@@ -1,6 +1,8 @@
package com.openhis.administration.mapper;
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.openhis.administration.domain.Organization;
import com.openhis.administration.dto.OrgDataDto;
import org.apache.ibatis.annotations.Param;
@@ -9,7 +11,7 @@ import org.springframework.stereotype.Repository;
import java.util.List;
/**
- * 机构管理Mapper接口
+ * 机构管理 Mapper 接口
*
* @author system
* @date 2025-02-20
@@ -25,5 +27,21 @@ public interface OrganizationMapper extends BaseMapper {
**/
List searchOrgDataByHealth();
-
-}
\ No newline at end of file
+ /**
+ * 分页查询挂号科室列表,关联租户表获取租户名称
+ * @param page 分页对象
+ * @param registerFlag 挂号标记
+ * @param deleteFlag 删除标记
+ * @param name 机构名称
+ * @param orgName 机构名称筛选
+ * @return 分页结果
+ */
+ @InterceptorIgnore(tenantLine = "true")
+ IPage selectRegisterOrganizationsWithTenant(
+ IPage page,
+ @Param("registerFlag") Integer registerFlag,
+ @Param("deleteFlag") String deleteFlag,
+ @Param("name") String name,
+ @Param("orgName") String orgName
+ );
+}
diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorSchedule.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorSchedule.java
index 0766f4d5..4c4c3c64 100644
--- a/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorSchedule.java
+++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorSchedule.java
@@ -72,6 +72,9 @@ public class DoctorSchedule extends HisBaseEntity {
/** 关联科室id */
private Long deptId;
+ /** 号别:0=普通,1=专家 */
+ private Integer regType;
+
/** 医生ID - 不映射到数据库表字段,仅作传输使用 */
private Long doctorId;
diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorScheduleWithDateDto.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorScheduleWithDateDto.java
index b41b978f..309aa380 100644
--- a/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorScheduleWithDateDto.java
+++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/appointmentmanage/domain/DoctorScheduleWithDateDto.java
@@ -61,6 +61,9 @@ public class DoctorScheduleWithDateDto {
/** 关联科室ID */
private Long deptId;
+ /** 号别:0=普通,1=专家 */
+ private Integer regType;
+
/** 医生姓名 */
private String doctorName;
diff --git a/openhis-server-new/openhis-domain/src/main/resources/mapper/administration/OrganizationMapper.xml b/openhis-server-new/openhis-domain/src/main/resources/mapper/administration/OrganizationMapper.xml
index dcd00ea0..2c68408b 100644
--- a/openhis-server-new/openhis-domain/src/main/resources/mapper/administration/OrganizationMapper.xml
+++ b/openhis-server-new/openhis-domain/src/main/resources/mapper/administration/OrganizationMapper.xml
@@ -14,5 +14,54 @@
GROUP BY heal.offered_org_id)
+
+
-
\ No newline at end of file
+
diff --git a/openhis-ui-vue3/src/views/appoinmentmanage/deptManage/index.vue b/openhis-ui-vue3/src/views/appoinmentmanage/deptManage/index.vue
index 3761bca0..468275e4 100644
--- a/openhis-ui-vue3/src/views/appoinmentmanage/deptManage/index.vue
+++ b/openhis-ui-vue3/src/views/appoinmentmanage/deptManage/index.vue
@@ -331,7 +331,7 @@
type="danger"
size="small"
@click="handleDeleteSchedule(scope.row)"
- :disabled="!isEditMode"
+ :disabled="!isEditMode || isLastDraftRowInSlot(scope.row)"
>
删除
@@ -430,7 +430,7 @@ const currentDept = ref(null)
// 筛选参数
const filterParams = ref({
- orgName: '演示医院',
+ orgName: '',
deptName: '测试内科',
clinicRoomName: '', // 添加诊室名称过滤字段
startDate: new Date(),
@@ -505,9 +505,9 @@ const fetchDoctorList = async (orgId) => {
console.log('原始医生数据:', doctorList)
- // 将医生数据按类型分组
- const ordinaryDoctors = []
- const expertDoctors = []
+ // 医生下拉统一展示:普通/专家都显示同一批医生
+ // 排班回显仍按 schedule.regType 过滤,不受这里影响
+ const allDoctors = []
doctorList.forEach(doctor => {
// 不再单独检查医生的org_id是否与当前科室匹配
@@ -520,29 +520,26 @@ const fetchDoctorList = async (orgId) => {
orgId: doctor.orgId
}
- ordinaryDoctors.push(doctorInfo)
-
- // 如果有专家类型的判断逻辑,可以在这里添加
- // 示例:如果职称包含"主任"或"教授"等关键词,则归为专家
- if (doctor.drProfttlCode && (doctor.drProfttlCode.includes('主任') || doctor.drProfttlCode.includes('教授'))) {
- expertDoctors.push(doctorInfo)
- }
+ allDoctors.push(doctorInfo)
})
- // 更新医生选项
- doctorOptions.value['普通'] = ordinaryDoctors
- doctorOptions.value['专家'] = expertDoctors.length > 0 ? expertDoctors : [...ordinaryDoctors]
+ const uniqueDoctors = Array.from(
+ new Map(allDoctors.map(doc => [doc.id, doc])).values()
+ )
+
+ // 更新医生选项
+ doctorOptions.value['普通'] = uniqueDoctors
+ doctorOptions.value['专家'] = uniqueDoctors
- console.log('最终的医生列表:', doctorOptions.value)
} else {
- console.error('获取医生列表失败:', response.msg)
+
doctorOptions.value = {
'普通': [],
'专家': []
}
}
} catch (error) {
- console.error('获取医生列表异常:', error)
+
doctorOptions.value = {
'普通': [],
'专家': []
@@ -693,7 +690,7 @@ const fetchClinicItems = async (deptId = null) => {
// 根据排班类型获取医生选项
const getDoctorOptions = (appointmentType) => {
- return doctorOptions.value[appointmentType] || doctorOptions.value['普通']
+ return doctorOptions.value[appointmentType] || []
}
// 排班列表数据
@@ -772,10 +769,6 @@ const fetchOrganizationList = async () => {
}
});
- // 添加默认的机构选项(如"中联医院"、"演示医院"等)
- const defaultOrgs = ['中联医院', '演示医院']; // 可以根据需要添加更多默认选项
- defaultOrgs.forEach(org => uniqueOrgNames.add(org));
-
// 将机构名称转换为下拉选项格式
organizationOptions.value = Array.from(uniqueOrgNames).map((orgName, index) => ({
id: index, // 使用索引作为ID,因为我们只需要名称
@@ -783,36 +776,27 @@ const fetchOrganizationList = async () => {
orgName: orgName
}));
} else {
- console.error('获取卫生机构列表失败:', response.msg)
- // 如果获取数据失败,至少显示默认选项
- const defaultOrgs = ['中联医院', '演示医院'];
- organizationOptions.value = defaultOrgs.map((orgName, index) => ({
- id: index,
- name: orgName,
- orgName: orgName
- }));
+ organizationOptions.value = []
}
} catch (error) {
- console.error('获取卫生机构列表失败:', error)
- // 如果出现异常,至少显示默认选项
- const defaultOrgs = ['中联医院', '演示医院'];
- organizationOptions.value = defaultOrgs.map((orgName, index) => ({
- id: index,
- name: orgName,
- orgName: orgName
- }));
+ organizationOptions.value = []
}
}
// 获取科室列表(通用方法)
const fetchDeptList = async (apiFunction) => {
try {
- // 复制查询参数
+ // 统一查询参数口径:后端使用 name 作为科室名称条件
const params = {
- ...queryParams.value,
- pageNum: pagination.value.currentPage, // 修正为 pageNum
+ pageNum: pagination.value.currentPage,
pageSize: pagination.value.pageSize
};
+ if (queryParams.value.orgName) {
+ params.orgName = queryParams.value.orgName;
+ }
+ if (queryParams.value.deptName) {
+ params.name = queryParams.value.deptName;
+ }
// 同时获取配置数据,分页大小与主列表保持一致
// 这样既解决了 9999 导致的性能问题,又保证了当前显示行的数据完整性
@@ -899,9 +883,9 @@ const getDeptList = async () => {
}
// 查询
-const handleQuery = () => {
+const handleQuery = async () => {
pagination.value.currentPage = 1;
- fetchDeptList(getRegisterOrganizations); // 使用挂号科室API
+ await fetchDeptList(getRegisterOrganizations); // 使用挂号科室API
}
// 处理卫生机构选择变化
@@ -914,13 +898,14 @@ const handleOrgChange = async (orgName) => {
}
// 重置
-const handleReset = () => {
+const handleReset = async () => {
queryParams.value = {
orgName: '',
deptName: ''
}
pagination.value.currentPage = 1
- getDeptList()
+ await fetchDepartmentOptions()
+ await getDeptList()
}
// 预约设置弹窗显示
@@ -1015,85 +1000,104 @@ const reloadScheduleData = async () => {
const row = currentDept.value
if (!row) return
- // 使用组件级别的 workTimeConfig
const weekSchedule = generateWeekSchedule(filterParams.value.startDate, workTimeConfig.value)
-
- // 计算当前周的起止日期,用于联表查询
const startDateStr = formatDateStr(filterParams.value.startDate)
const endDate = new Date(filterParams.value.startDate)
endDate.setDate(endDate.getDate() + 6)
const endDateStr = formatDateStr(endDate)
- // 获取该科室在指定日期范围内的排班数据(联表查询 adm_schedule_pool 获取具体日期)
try {
const response = await getDoctorScheduleListByDeptIdAndDateRange(row.id, startDateStr, endDateStr)
if (response.code === 200) {
const actualData = response.data
- const deptSchedules = Array.isArray(actualData) ? actualData : (actualData && actualData.code === 200 ? actualData.data || [] : [])
+ const deptSchedules = Array.isArray(actualData)
+ ? actualData
+ : (actualData && actualData.code === 200 ? actualData.data || [] : [])
+ const selectedRegType = filterParams.value.appointmentType === '专家' ? 1 : 0
+ const filteredSchedules = deptSchedules.filter(schedule => Number(schedule.regType) === selectedRegType)
- // 以 "具体日期-时段" 为 key 创建映射表,替代原来的 "星期-时段"
+ // 同日期同时段可能存在多条排班,按 key 聚合成数组
const scheduleMap = {}
- deptSchedules.forEach(schedule => {
- // scheduleDate 来自 adm_schedule_pool.schedule_date,是具体的出诊日期
+ filteredSchedules.forEach(schedule => {
const key = `${schedule.scheduleDate}-${schedule.timePeriod}`
- scheduleMap[key] = schedule
- })
-
- // 将现有排班数据合并到周计划中(以具体日期匹配)
- weekSchedule.forEach(slot => {
- // slot.date 是前端生成的具体日期(yyyy-MM-dd),与后端的 scheduleDate 一致
- const key = `${slot.date}-${slot.timeSlot}`
- const existingSchedule = scheduleMap[key]
-
- if (existingSchedule) {
- // 更新匹配的时段数据
- slot.doctorName = existingSchedule.doctor
- slot.doctorId = String(existingSchedule.doctorId) // 确保为字符串
-
- // --- 容错逻辑:校验医生ID是否在当前医生列表中 ---
- const allAvailableDoctors = [...doctorOptions.value['普通'], ...doctorOptions.value['专家']];
- const matchedDoctorById = allAvailableDoctors.find(doc => doc.id === slot.doctorId);
-
- if (!matchedDoctorById) {
- // 尝试根据医生姓名进行匹配
- const matchedDoctorByName = allAvailableDoctors.find(doc => doc.label === slot.doctorName);
- if (matchedDoctorByName) {
- slot.doctorId = matchedDoctorByName.id;
- console.warn(`【调试警告】排班记录doctorId ${existingSchedule.doctorId} (姓名: ${existingSchedule.doctor}) 与当前医生列表不匹配。已根据姓名修正为ID: ${matchedDoctorByName.id}`);
- } else {
- slot.doctorId = null;
- slot.doctorName = '';
- console.error(`【调试错误】排班记录doctorId ${existingSchedule.doctorId} 和医生姓名 "${existingSchedule.doctor}" 都未在当前医生列表中找到。`);
- }
- }
- // --- 结束容错逻辑 ---
-
- slot.room = existingSchedule.clinic
- slot.startTime = existingSchedule.startTime
- slot.endTime = existingSchedule.endTime
- slot.maxNumber = existingSchedule.limitNumber
- slot.appointmentItem = existingSchedule.registerItem
- slot.registrationFee = existingSchedule.registerFee
- slot.clinicItem = existingSchedule.diagnosisItem
- slot.treatmentFee = existingSchedule.diagnosisFee
- slot.online = existingSchedule.isOnline
- slot.stopClinic = existingSchedule.isStopped
- slot.stopReason = existingSchedule.stopReason
- slot.backendId = existingSchedule.id // 保存后端ID
+ if (!scheduleMap[key]) {
+ scheduleMap[key] = []
}
+ scheduleMap[key].push(schedule)
})
+
+ const allAvailableDoctors = [...doctorOptions.value['普通'], ...doctorOptions.value['专家']]
+ const mergedSchedule = []
+
+ const applyScheduleToSlot = (targetSlot, existingSchedule) => {
+ targetSlot.doctorName = existingSchedule.doctorName || existingSchedule.doctor || ''
+ targetSlot.doctorId = existingSchedule.doctorId != null ? String(existingSchedule.doctorId) : null
+
+ const matchedDoctorById = allAvailableDoctors.find(doc => doc.id === targetSlot.doctorId)
+ if (!matchedDoctorById && targetSlot.doctorName) {
+ const matchedDoctorByName = allAvailableDoctors.find(doc => doc.label === targetSlot.doctorName)
+ if (matchedDoctorByName) {
+ targetSlot.doctorId = matchedDoctorByName.id
+ }
+ }
+
+ targetSlot.room = existingSchedule.clinic || existingSchedule.clinicRoom || ''
+ targetSlot.startTime = existingSchedule.startTime
+ targetSlot.endTime = existingSchedule.endTime
+ targetSlot.maxNumber = existingSchedule.limitNumber
+ targetSlot.appointmentItem = existingSchedule.registerItem
+ targetSlot.registrationFee = existingSchedule.registerFee
+ targetSlot.clinicItem = existingSchedule.diagnosisItem
+ targetSlot.treatmentFee = existingSchedule.diagnosisFee
+ targetSlot.online = existingSchedule.isOnline
+ targetSlot.stopClinic = existingSchedule.isStopped
+ targetSlot.stopReason = existingSchedule.stopReason
+ targetSlot.regType = existingSchedule.regType
+ targetSlot.backendId = existingSchedule.id
+ }
+
+ weekSchedule.forEach(slot => {
+ const key = `${slot.date}-${slot.timeSlot}`
+ const existingSchedules = scheduleMap[key] || []
+
+ if (existingSchedules.length === 0) {
+ mergedSchedule.push(slot)
+ return
+ }
+
+ existingSchedules.forEach((existingSchedule, index) => {
+ const targetSlot = index === 0
+ ? slot
+ : {
+ ...slot,
+ id: `${slot.id}-dup-${existingSchedule.id || index}`,
+ doctorName: '',
+ doctorId: null,
+ room: '',
+ maxNumber: '',
+ appointmentItem: '',
+ registrationFee: 0,
+ clinicItem: '',
+ treatmentFee: 0,
+ online: true,
+ stopClinic: false,
+ stopReason: ''
+ }
+ applyScheduleToSlot(targetSlot, existingSchedule)
+ mergedSchedule.push(targetSlot)
+ })
+ })
+
+ scheduleList.value = mergedSchedule
+ return
}
} catch (error) {
console.error('获取科室排班数据失败:', error)
ElMessage.error('获取科室排班数据失败')
}
- // 设置排班列表
- console.log("【调试信息】即将渲染的排班数据:", JSON.parse(JSON.stringify(weekSchedule.filter(s => s.doctorId))));
scheduleList.value = weekSchedule
}
-
-// 编辑
const handleEdit = async (row) => {
// 设置当前科室和模式
currentDept.value = row
@@ -1101,7 +1105,7 @@ const handleEdit = async (row) => {
scheduleDialogTitle.value = `编辑科室排班 - ${row.name || row.deptName}`
// 动态设置筛选参数
- filterParams.value.orgName = row.orgName || '中联医院'
+ filterParams.value.orgName = row.orgName || row.organizationName || row.org || ''
filterParams.value.deptName = row.name || row.deptName
// 首先获取科室工作时间配置
@@ -1152,7 +1156,7 @@ const handleView = async (row) => {
scheduleDialogTitle.value = `查看科室排班 - ${row.name || row.deptName}`
// 动态设置筛选参数
- filterParams.value.orgName = row.orgName || '中联医院'
+ filterParams.value.orgName = row.orgName || row.organizationName || row.org || ''
filterParams.value.deptName = row.name || row.deptName
// 首先获取科室工作时间配置
@@ -1249,20 +1253,14 @@ const searchClinicRooms = async (query) => {
const doctorMapping = {}
// 排班类型变化处理
-const handleAppointmentTypeChange = () => {
- // 当排班类型改变时,自动匹配对应的医生
+const handleAppointmentTypeChange = async () => {
+ if (currentDept.value) {
+ await reloadScheduleData()
+ return
+ }
scheduleList.value.forEach(item => {
- if (item.doctorName) {
- // 获取新类型对应的医生列表
- const newTypeDoctors = getDoctorOptions(filterParams.value.appointmentType)
- // 检查当前医生是否在新类型列表中
- const doctorExists = newTypeDoctors.some(doctor => doctor.value === item.doctorName)
-
- if (!doctorExists) {
- // 如果当前医生不在新类型列表中,则清空
- item.doctorName = ''
- }
- }
+ item.doctorId = null
+ item.doctorName = ''
})
}
@@ -1302,14 +1300,84 @@ const handleDoctorChange = (selectedId, row) => {
row.doctorName = '';
return;
}
- const allDoctors = [...doctorOptions.value['普通'], ...doctorOptions.value['专家']];
- const selectedDoctor = allDoctors.find(doc => doc.id === String(selectedId));
+ const typeDoctors = getDoctorOptions(filterParams.value.appointmentType)
+ const selectedDoctor = typeDoctors.find(doc => doc.id === String(selectedId));
if (selectedDoctor) {
row.doctorName = selectedDoctor.label;
}
}
+const resolveDoctorName = (row) => {
+ if (row.doctorName && row.doctorName.trim() !== '') {
+ return row.doctorName.trim()
+ }
+ if (!row.doctorId) {
+ return ''
+ }
+ const allDoctors = [...doctorOptions.value['普通'], ...doctorOptions.value['专家']]
+ const matched = allDoctors.find(doc => doc.id === String(row.doctorId))
+ return matched ? matched.label : ''
+}
+
// 添加排班
+// 删除后兜底:当某天某时段被删空时,补一条重置行,保证可继续填写
+const createResetScheduleRow = (row) => {
+ const regTypeValue = Number(row.regType)
+ return {
+ id: `reset-${Date.now()}-${Math.random()}`,
+ date: row.date,
+ weekday: row.weekday,
+ timeSlot: row.timeSlot,
+ startTime: row.startTime || '08:00',
+ endTime: row.endTime || '12:00',
+ doctorName: '',
+ doctorId: null,
+ room: '',
+ maxNumber: '',
+ appointmentItem: '',
+ registrationFee: 0,
+ clinicItem: '',
+ treatmentFee: 0,
+ online: true,
+ stopClinic: false,
+ stopReason: '',
+ regType: Number.isNaN(regTypeValue) ? 0 : regTypeValue,
+ isNew: true
+ }
+}
+
+const ensureResetRowAfterDelete = (row, insertIndex) => {
+ const hasSameSlot = scheduleList.value.some(item =>
+ item.date === row.date && item.timeSlot === row.timeSlot
+ )
+ if (hasSameSlot) {
+ return
+ }
+
+ const resetRow = createResetScheduleRow(row)
+ if (insertIndex >= 0 && insertIndex <= scheduleList.value.length) {
+ scheduleList.value.splice(insertIndex, 0, resetRow)
+ return
+ }
+ scheduleList.value.push(resetRow)
+}
+
+const isDraftScheduleRow = (row) => {
+ return !row.backendId || row.isNew
+}
+
+const isLastDraftRowInSlot = (row) => {
+ if (!isDraftScheduleRow(row)) {
+ return false
+ }
+
+ const sameSlotRows = scheduleList.value.filter(item =>
+ item.date === row.date && item.timeSlot === row.timeSlot
+ )
+ const draftRows = sameSlotRows.filter(item => isDraftScheduleRow(item))
+ return draftRows.length <= 1
+}
+
const handleAddSchedule = (row) => {
// 创建新的排班记录,基于当前行的日期和时段
const newSchedule = {
@@ -1346,6 +1414,11 @@ const handleAddSchedule = (row) => {
// 删除排班
const handleDeleteSchedule = (row) => {
+ if (isLastDraftRowInSlot(row)) {
+ ElMessage.warning('当前时段需保留最后一条待填写记录,不能删除')
+ return
+ }
+
ElMessageBox.confirm('确定要删除这条排班记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@@ -1354,15 +1427,17 @@ const handleDeleteSchedule = (row) => {
// 如果是已保存的记录(有后端ID),调用删除接口
if (row.backendId && !row.isNew) {
deleteDoctorSchedule(row.backendId).then(res => {
- if (res.code === 200) {
+ const removed = res?.data?.data === true || res?.data === true
+ if (res.code === 200 && removed) {
// 从列表中移除
const index = scheduleList.value.findIndex(item => item.id === row.id)
if (index !== -1) {
scheduleList.value.splice(index, 1)
+ ensureResetRowAfterDelete(row, index)
}
ElMessage.success('删除成功')
} else {
- ElMessage.error(res.msg || '删除失败')
+ ElMessage.error(res.msg || '删除失败,记录可能未真正删除')
}
}).catch(error => {
console.error('删除排班失败:', error)
@@ -1373,6 +1448,7 @@ const handleDeleteSchedule = (row) => {
const index = scheduleList.value.findIndex(item => item.id === row.id)
if (index !== -1) {
scheduleList.value.splice(index, 1)
+ ensureResetRowAfterDelete(row, index)
ElMessage.success('删除成功')
}
}
@@ -1445,7 +1521,7 @@ const handleEditSchedule = (row) => {
}
// 设置科室信息
- filterParams.value.orgName = '中联医院' // 假设固定机构名称
+ filterParams.value.orgName = currentDept.value?.orgName || currentDept.value?.organizationName || currentDept.value?.org || ''
filterParams.value.deptName = '未知科室' // 这里可能需要根据实际情况设置
// 设置排班列表
@@ -1505,12 +1581,12 @@ const handleSave = async () => {
try {
// 验证必填字段 - 只验证用户真正填写了信息的记录
const filledSchedules = scheduleList.value.filter(item => {
- // 只有当用户为某一行选择了医生,我们才认为他打算保存此条记录
- return item.doctorName && item.doctorName.trim() !== '';
+ // 已有排班可能只有 doctorId,没有 doctorName,二者任一存在都视为可保存记录
+ return !!resolveDoctorName(item) || !!item.doctorId;
});
const incompleteSchedules = filledSchedules.filter(item => {
- const isDoctorValid = item.doctorName && item.doctorName.trim() !== '';
+ const isDoctorValid = !!resolveDoctorName(item) || !!item.doctorId;
const isRoomValid = item.room && item.room.trim() !== '';
const isStartTimeValid = item.startTime && typeof item.startTime === 'string';
const isEndTimeValid = item.endTime && typeof item.endTime === 'string';
@@ -1526,10 +1602,13 @@ const handleSave = async () => {
// 转换数据格式
const schedulesToProcess = filledSchedules.map(item => {
+ const regTypeValue = Number(
+ item.regType ?? (filterParams.value.appointmentType === '专家' ? 1 : 0)
+ );
const scheduleData = {
weekday: item.weekday,
timePeriod: item.timeSlot,
- doctor: item.doctorName,
+ doctor: resolveDoctorName(item),
doctorId: item.doctorId,
clinic: item.room,
startTime: item.startTime,
@@ -1543,6 +1622,7 @@ const handleSave = async () => {
isStopped: item.stopClinic,
stopReason: item.stopClinic ? (item.stopReason || '') : '',
deptId: currentDept.value?.id || null,
+ regType: Number.isNaN(regTypeValue) ? 0 : regTypeValue,
scheduledDate: item.date // 添加具体日期字段
};
if (item.backendId) {
@@ -2002,4 +2082,4 @@ onMounted(async () => {
:deep(.el-dialog__body) {
padding: 20px;
}
-
\ No newline at end of file
+
From 0a8428a4ca7a49955efd92f17337ee5343ef4258 Mon Sep 17 00:00:00 2001
From: Ranyunqiao <2499115710@qq.com>
Date: Thu, 19 Mar 2026 09:54:38 +0800
Subject: [PATCH 7/9] =?UTF-8?q?241=20=E6=A3=80=E6=9F=A5=E9=A1=B9=E7=9B=AE?=
=?UTF-8?q?=E8=AE=BE=E7=BD=AE-=E3=80=8B=E5=A5=97=E9=A4=90=E8=AE=BE?=
=?UTF-8?q?=E7=BD=AE=EF=BC=9A=E9=A1=B9=E7=9B=AE=E5=90=8D=E7=A7=B0=E5=AD=97?=
=?UTF-8?q?=E6=AE=B5=E6=A3=80=E7=B4=A2=E4=B8=8D=E5=87=BA=E2=80=9C=E5=BE=84?=
=?UTF-8?q?=E7=9B=B4=E8=82=A0B=E8=B6=85=E6=A3=80=E6=9F=A5=E2=80=9D?=
=?UTF-8?q?=E8=AF=8A=E7=96=97=E6=94=B6=E8=B4=B9=E9=A1=B9=E7=9B=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../checkprojectSettings/components/PackageSettings.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue b/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue
index 9fb0751b..e37919c5 100644
--- a/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue
+++ b/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue
@@ -685,7 +685,7 @@ onMounted(async () => {
}
// 加载诊疗项目列表(优先使用缓存)
- await loadDiagnosisTreatmentList(false)
+ await loadDiagnosisTreatmentList(true)
// 初始化一行空数据
if(props.mode === 'add'){
From 6ed41eb513bcba929f570fc0a1b160e1f94f39ea Mon Sep 17 00:00:00 2001
From: Ranyunqiao <2499115710@qq.com>
Date: Thu, 19 Mar 2026 10:11:02 +0800
Subject: [PATCH 8/9] =?UTF-8?q?240=20=E6=A3=80=E6=9F=A5=E9=A1=B9=E7=9B=AE?=
=?UTF-8?q?=E8=AE=BE=E7=BD=AE-=E3=80=8B=E6=A3=80=E6=9F=A5=E9=83=A8?=
=?UTF-8?q?=E4=BD=8D=EF=BC=9A=E6=9C=8D=E5=8A=A1=E8=8C=83=E5=9B=B4=E5=AD=97?=
=?UTF-8?q?=E6=AE=B5=E4=B8=8B=E6=8B=89=E9=80=89=E9=A1=B9=E5=8F=96=E5=80=BC?=
=?UTF-8?q?=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../checkprojectSettings/index.vue | 21 ++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/index.vue b/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/index.vue
index a24407fb..af1350ca 100644
--- a/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/index.vue
+++ b/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/index.vue
@@ -534,19 +534,19 @@
{{ item.number || '999999' }}
-|
+ |
-
+
- {{ getCheckTypeLabelForMethodPart(item.checkType) || '无' }}
+ {{ getServiceScopeLabel(item.serviceScope) || '无' }}
|
@@ -667,6 +667,8 @@ const checkTypeOptions = ref([]);
const inspectionTypeDicts = ref([]);
// 完整的服务范围字典数据
const serviceScopeDicts = ref([]);
+ // 服务范围下拉选项
+ const serviceScopeOptions = ref([]);
const checkMethods = ref([]);
// 根据字典值获取检查类型标签
@@ -926,6 +928,11 @@ onMounted(async () => {
inspectionTypeDicts.value = [];
}
+ // 获取服务范围字典
+ const scopeRes = await getDicts('scope_of_services');
+ serviceScopeDicts.value = scopeRes?.data || [];
+
+
// 从检查类型维护页面获取检查类型数据,用于检查方法和检查部位的下拉选项
await loadCheckTypeOptionsForMethodPart();
From 266b06114a02867170beb3b84525ea86ae0f0185 Mon Sep 17 00:00:00 2001
From: Ranyunqiao <2499115710@qq.com>
Date: Thu, 19 Mar 2026 10:21:24 +0800
Subject: [PATCH 9/9] =?UTF-8?q?=E9=87=8D=E6=96=B0=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../checkprojectSettings/components/PackageSettings.vue | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue b/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue
index e37919c5..18f17fac 100644
--- a/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue
+++ b/openhis-ui-vue3/src/views/maintainSystem/checkprojectSettings/components/PackageSettings.vue
@@ -941,8 +941,7 @@ function initializeSearchList(row) {
// 项目搜索处理(支持首字母和模糊搜索)
function handleProjectSearch(query, row) {
- console.log('搜索关键字:', query)
-
+
if (!query || query.trim() === '') {
row.filteredList = diagnosisTreatmentList.value
return
|