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 94988bfc..2dc94b6c 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 @@ -78,7 +78,6 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService { private IOperationRecordService operationRecordService; @Resource private IServiceRequestService serviceRequestService; - /** * 诊疗目录初期查询 * @@ -240,9 +239,8 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService { DiagnosisTreatmentSelParam.setPricingFlag(pricingFlagValue); } - // 分页查询 IPage diseaseTreatmentPage - = activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page(pageNo, pageSize), queryWrapper); + = activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<>(pageNo, pageSize), queryWrapper); diseaseTreatmentPage.getRecords().forEach(e -> { // 医保标记枚举类回显赋值 @@ -447,24 +445,17 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService { */ @Override public R editDiseaseTreatmentStop(List ids) { - - List ActivityDefinitionList = new CopyOnWriteArrayList<>(); - - // 取得更新值 - for (Long detail : ids) { - ActivityDefinition ActivityDefinition = new ActivityDefinition(); - ActivityDefinition.setId(detail); - ActivityDefinition.setStatusEnum(PublicationStatus.RETIRED.getValue()); - ActivityDefinitionList.add(ActivityDefinition); + List actList = new CopyOnWriteArrayList<>(); + for (Long id : ids) { + ActivityDefinition act = new ActivityDefinition(); + act.setId(id); + act.setStatusEnum(PublicationStatus.RETIRED.getValue()); + actList.add(act); } - // 插入操作记录 operationRecordService.addIdsOperationRecord(DbOpType.STOP.getCode(), CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids); - // 更新诊疗信息 - return activityDefinitionService.updateBatchById(ActivityDefinitionList) - ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"})) - : R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null)); - + activityDefinitionService.updateBatchById(actList); + return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"\u8bca\u7597\u76ee\u5f55"})); } /** @@ -475,24 +466,17 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService { */ @Override public R editDiseaseTreatmentStart(List ids) { - - List ActivityDefinitionList = new CopyOnWriteArrayList<>(); - - // 取得更新值 - for (Long detail : ids) { - ActivityDefinition ActivityDefinition = new ActivityDefinition(); - ActivityDefinition.setId(detail); - ActivityDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue()); - ActivityDefinitionList.add(ActivityDefinition); + List actList = new CopyOnWriteArrayList<>(); + for (Long id : ids) { + ActivityDefinition act = new ActivityDefinition(); + act.setId(id); + act.setStatusEnum(PublicationStatus.ACTIVE.getValue()); + actList.add(act); } - // 插入操作记录 operationRecordService.addIdsOperationRecord(DbOpType.START.getCode(), CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids); - // 更新诊疗信息 - return activityDefinitionService.updateBatchById(ActivityDefinitionList) - ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"})) - : R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null)); - + activityDefinitionService.updateBatchById(actList); + return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"诊疗目录"})); } /** diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/datadictionary/mapper/LabActivityDefinitionManageMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/datadictionary/mapper/LabActivityDefinitionManageMapper.java new file mode 100644 index 00000000..4926b094 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/datadictionary/mapper/LabActivityDefinitionManageMapper.java @@ -0,0 +1,51 @@ +package com.openhis.web.datadictionary.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * 检验项目定义管理 Mapper(操作 lab_activity_definition 表) + */ +@Repository +public interface LabActivityDefinitionManageMapper { + + /** + * 检验项目分页查询 + * + * @param page 分页参数 + * @param queryWrapper 查询条件 + * @return 分页结果 + */ + IPage getLabActivityDefinitionPage( + @Param("page") Page page, + @Param(Constants.WRAPPER) QueryWrapper queryWrapper); + + /** + * 检验项目详情 + * + * @param id 项目ID + * @param tenantId 租户ID + * @return 详情 + */ + DiagnosisTreatmentDto getLabActivityDefinitionOne(@Param("id") Long id, @Param("tenantId") Integer tenantId); + + /** + * 检验项目下拉列表(轻量级) + * + * @param statusEnum 状态 + * @param tenantId 租户ID + * @param searchKey 搜索关键词(可选) + * @return 列表 + */ + List getLabActivityDefinitionSimpleList( + @Param("statusEnum") Integer statusEnum, + @Param("tenantId") Integer tenantId, + @Param("searchKey") String searchKey); +} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/SaveDiagnosisChildParam.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/SaveDiagnosisChildParam.java index ce932917..5a4276e4 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/SaveDiagnosisChildParam.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/dto/SaveDiagnosisChildParam.java @@ -2,6 +2,7 @@ package com.openhis.web.doctorstation.dto; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import lombok.experimental.Accessors; @@ -73,12 +74,16 @@ public class SaveDiagnosisChildParam { /** * 诊断时间 + * 添加 pattern 以支持前端传来的 "yyyy/M/d HH:mm:ss" 格式 */ + @JsonFormat(pattern = "yyyy/M/d HH:mm:ss", timezone = "GMT+8") private Date diagnosisTime; /** * 发病时间 + * 同样添加 pattern 以防前端传来相同格式的发病时间 */ + @JsonFormat(pattern = "yyyy/M/d HH:mm:ss", timezone = "GMT+8") private Date onsetDate; /** 患者疾病诊断类型代码 */ diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/appservice/ILabActivityDefinitionAppService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/appservice/ILabActivityDefinitionAppService.java new file mode 100644 index 00000000..fd2ac541 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/appservice/ILabActivityDefinitionAppService.java @@ -0,0 +1,45 @@ +package com.openhis.web.lab.appservice; + +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam; +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto; +import com.core.common.core.domain.R; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * 检验项目 AppService 接口(独立操作 lab_activity_definition 表) + */ +public interface ILabActivityDefinitionAppService { + + /** + * 分页查询检验项目列表 + */ + R getLabActivityDefinitionPage(DiagnosisTreatmentSelParam selParam, String searchKey, + Integer pageNo, Integer pageSize, HttpServletRequest request); + + /** + * 根据id查询检验项目详情 + */ + R getLabActivityDefinitionOne(Long id); + + /** + * 新增检验项目 + */ + R addLabActivityDefinition(DiagnosisTreatmentUpDto dto); + + /** + * 编辑检验项目 + */ + R editLabActivityDefinition(DiagnosisTreatmentUpDto dto); + + /** + * 停用检验项目 + */ + R stopLabActivityDefinition(List ids); + + /** + * 启用检验项目 + */ + R startLabActivityDefinition(List ids); +} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/appservice/impl/LabActivityDefinitionAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/appservice/impl/LabActivityDefinitionAppServiceImpl.java new file mode 100644 index 00000000..39b3b001 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/appservice/impl/LabActivityDefinitionAppServiceImpl.java @@ -0,0 +1,189 @@ +package com.openhis.web.lab.appservice.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.core.domain.model.LoginUser; +import com.core.common.utils.*; +import com.core.common.utils.bean.BeanUtils; +import com.openhis.common.constant.PromptMsgConstant; +import com.openhis.common.enums.ActivityType; +import com.openhis.common.enums.PublicationStatus; +import com.openhis.common.enums.Whether; +import com.core.common.utils.ChineseConvertUtils; +import com.openhis.common.utils.EnumUtils; +import com.openhis.common.utils.HisQueryUtils; +import com.openhis.common.enums.AssignSeqEnum; +import com.openhis.lab.domain.LabActivityDefinition; +import com.openhis.lab.service.ILabActivityDefinitionService; +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentDto; +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam; +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto; +import com.openhis.web.lab.appservice.ILabActivityDefinitionAppService; +import com.openhis.web.datadictionary.mapper.LabActivityDefinitionManageMapper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * 检验项目 AppService 实现(独立操作 lab_activity_definition 表) + */ +@Service +public class LabActivityDefinitionAppServiceImpl implements ILabActivityDefinitionAppService { + + @Resource + private ILabActivityDefinitionService labActivityDefinitionService; + + @Resource + private LabActivityDefinitionManageMapper labActivityDefinitionManageMapper; + + @Resource + private AssignSeqUtil assignSeqUtil; + + @Override + public R getLabActivityDefinitionPage(DiagnosisTreatmentSelParam selParam, String searchKey, + Integer pageNo, Integer pageSize, HttpServletRequest request) { + if (selParam == null) { + selParam = new DiagnosisTreatmentSelParam(); + } + if (selParam.getStatusEnum() == null) { + selParam.setStatusEnum(PublicationStatus.ACTIVE.getValue()); + } + + // 临时移除需要手动拼别名条件的字段 + Long inspectionTypeIdValue = null; + if (selParam.getInspectionTypeId() != null) { + inspectionTypeIdValue = selParam.getInspectionTypeId(); + selParam.setInspectionTypeId(null); + } + Integer pricingFlagValue = null; + if (selParam.getPricingFlag() != null) { + pricingFlagValue = selParam.getPricingFlag(); + selParam.setPricingFlag(null); + } + + QueryWrapper queryWrapper = HisQueryUtils.buildQueryWrapper(selParam, + searchKey, new HashSet<>(Arrays.asList("T1.bus_no", "T1.name", "T1.py_str", "T1.wb_str")), request); + + if (inspectionTypeIdValue != null) { + queryWrapper.eq("T1.inspection_type_id", inspectionTypeIdValue); + selParam.setInspectionTypeId(inspectionTypeIdValue); + } + if (pricingFlagValue != null) { + queryWrapper.eq("T1.pricing_flag", pricingFlagValue); + selParam.setPricingFlag(pricingFlagValue); + } + + IPage page = labActivityDefinitionManageMapper + .getLabActivityDefinitionPage(new Page<>(pageNo, pageSize), queryWrapper); + + page.getRecords().forEach(e -> { + e.setYbFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbFlag())); + e.setYbMatchFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbMatchFlag())); + e.setTypeEnum_enumText(EnumUtils.getInfoByValue(ActivityType.class, e.getTypeEnum())); + e.setStatusEnum_enumText(EnumUtils.getInfoByValue(PublicationStatus.class, e.getStatusEnum())); + e.setPricingFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getPricingFlag())); + }); + + return R.ok(page); + } + + @Override + public R getLabActivityDefinitionOne(Long id) { + Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); + DiagnosisTreatmentDto dto = labActivityDefinitionManageMapper.getLabActivityDefinitionOne(id, tenantId); + return R.ok(dto); + } + + @Override + public R addLabActivityDefinition(DiagnosisTreatmentUpDto dto) { + if (dto.getOrgId() == null) { + dto.setOrgId(SecurityUtils.getLoginUser().getHospitalId()); + } + + LabActivityDefinition lab = new LabActivityDefinition(); + BeanUtils.copyProperties(dto, lab); + lab.setSortOrder(dto.getSortOrder()) + .setServiceRange(dto.getServiceRange()) + .setInspectionTypeId(dto.getInspectionTypeId()) + .setFeePackageId(dto.getFeePackageId()) + .setSubItemId(dto.getSubItemId()); + + if (StringUtils.isEmpty(lab.getBusNo())) { + lab.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_DEFINITION_NUM.getPrefix(), 10)); + } + lab.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(lab.getName())); + lab.setWbStr(ChineseConvertUtils.toWBFirstLetter(lab.getName())); + lab.setStatusEnum(PublicationStatus.ACTIVE.getValue()); + + // 设置创建者和租户ID + String createBy = "system"; + Integer tenantId = null; + try { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null) { + createBy = loginUser.getUsername(); + tenantId = loginUser.getTenantId(); + } + } catch (Exception e) { + // 使用默认值 + } + lab.setCreateBy(createBy); + lab.setTenantId(tenantId != null ? tenantId : 1); + if (lab.getCreateTime() == null) { + lab.setCreateTime(new java.util.Date()); + } + + return labActivityDefinitionService.addLabActivityDefinition(lab) + ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"})) + : R.fail(null, "检验编码已存在:" + lab.getBusNo()); + } + + @Override + public R editLabActivityDefinition(DiagnosisTreatmentUpDto dto) { + LabActivityDefinition lab = new LabActivityDefinition(); + BeanUtils.copyProperties(dto, lab); + lab.setSortOrder(dto.getSortOrder()) + .setServiceRange(dto.getServiceRange()) + .setInspectionTypeId(dto.getInspectionTypeId()) + .setFeePackageId(dto.getFeePackageId()) + .setSubItemId(dto.getSubItemId()) + .setPricingFlag(dto.getPricingFlag()); + lab.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(lab.getName())); + lab.setWbStr(ChineseConvertUtils.toWBFirstLetter(lab.getName())); + + return labActivityDefinitionService.updateById(lab) + ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"})) + : R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null)); + } + + @Override + public R stopLabActivityDefinition(List ids) { + List labList = new CopyOnWriteArrayList<>(); + for (Long id : ids) { + LabActivityDefinition lab = new LabActivityDefinition(); + lab.setId(id).setStatusEnum(PublicationStatus.RETIRED.getValue()); + labList.add(lab); + } + labActivityDefinitionService.updateBatchById(labList); + return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"})); + } + + @Override + public R startLabActivityDefinition(List ids) { + List labList = new CopyOnWriteArrayList<>(); + for (Long id : ids) { + LabActivityDefinition lab = new LabActivityDefinition(); + lab.setId(id).setStatusEnum(PublicationStatus.ACTIVE.getValue()); + labList.add(lab); + } + labActivityDefinitionService.updateBatchById(labList); + return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"检验项目"})); + } +} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/controller/InspectionTypeController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/controller/InspectionTypeController.java index 161024a1..3788df59 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/controller/InspectionTypeController.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/controller/InspectionTypeController.java @@ -94,7 +94,6 @@ public class InspectionTypeController extends BaseController { // 查询是否存在相同编码的记录 List existingRecords = inspectionTypeService.list(queryWrapper); - log.debug("检查编码唯一性:code={}, 数据库中存在记录数={}", inspectionType.getCode(), existingRecords.size()); if (!existingRecords.isEmpty()) { return AjaxResult.error("检验类型编码已存在"); @@ -119,8 +118,6 @@ public class InspectionTypeController extends BaseController { return toAjax(result); }); } catch (Exception e) { - log.error("新增检验类型失败:code={}, 错误信息:{}", inspectionType.getCode(), e.getMessage(), e); - // 捕获唯一性约束冲突异常 if (e.getMessage().contains("uk_inspection_type_code") || e.getMessage().contains("duplicate key value") || diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/controller/LabActivityDefinitionController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/controller/LabActivityDefinitionController.java new file mode 100644 index 00000000..437fdf9f --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/lab/controller/LabActivityDefinitionController.java @@ -0,0 +1,78 @@ +package com.openhis.web.lab.controller; + +import com.core.common.core.domain.R; +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam; +import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto; +import com.openhis.web.lab.appservice.ILabActivityDefinitionAppService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * 检验项目维护 Controller(独立操作 lab_activity_definition 表) + * 路径前缀:/lab/activity-definition + */ +@RestController +@RequestMapping("/lab/activity-definition") +@Slf4j +public class LabActivityDefinitionController { + + @Resource + private ILabActivityDefinitionAppService labActivityDefinitionAppService; + + /** + * 分页查询检验项目列表 + */ + @GetMapping("/page") + public R getPage(DiagnosisTreatmentSelParam selParam, + @RequestParam(value = "searchKey", defaultValue = "") String searchKey, + @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest request) { + return labActivityDefinitionAppService.getLabActivityDefinitionPage(selParam, searchKey, pageNo, pageSize, request); + } + + /** + * 根据id查询检验项目详情 + */ + @GetMapping("/one") + public R getOne(@RequestParam Long id) { + return labActivityDefinitionAppService.getLabActivityDefinitionOne(id); + } + + /** + * 新增检验项目 + */ + @PostMapping("/add") + public R add(@Validated @RequestBody DiagnosisTreatmentUpDto dto) { + return labActivityDefinitionAppService.addLabActivityDefinition(dto); + } + + /** + * 编辑检验项目 + */ + @PutMapping("/edit") + public R edit(@RequestBody DiagnosisTreatmentUpDto dto) { + return labActivityDefinitionAppService.editLabActivityDefinition(dto); + } + + /** + * 停用检验项目 + */ + @PutMapping("/stop") + public R stop(@RequestBody List ids) { + return labActivityDefinitionAppService.stopLabActivityDefinition(ids); + } + + /** + * 启用检验项目 + */ + @PutMapping("/start") + public R start(@RequestBody List ids) { + return labActivityDefinitionAppService.startLabActivityDefinition(ids); + } +} diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/datadictionary/LabActivityDefinitionManageMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/datadictionary/LabActivityDefinitionManageMapper.xml new file mode 100644 index 00000000..5caaa144 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/datadictionary/LabActivityDefinitionManageMapper.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/domain/InspectionPackageDetail.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/domain/InspectionPackageDetail.java index 69571001..c7fc1fa2 100644 --- a/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/domain/InspectionPackageDetail.java +++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/domain/InspectionPackageDetail.java @@ -55,7 +55,10 @@ public class InspectionPackageDetail { /** 单位 */ private String unit; - /** 单价 */ + /** 原始单价(未折扣前的价格,用于折扣变更时恢复原价) */ + private BigDecimal originalPrice; + + /** 单价(折后单价 = 原始单价 × 折扣比例) */ private BigDecimal unitPrice; /** 金额 */ diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/domain/LabActivityDefinition.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/domain/LabActivityDefinition.java new file mode 100644 index 00000000..3ec4205d --- /dev/null +++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/domain/LabActivityDefinition.java @@ -0,0 +1,106 @@ +package com.openhis.lab.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.core.common.core.domain.HisBaseEntity; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 检验项目定义实体(独立表 lab_activity_definition,不依赖 wor_activity_definition) + */ +@Data +@TableName("lab_activity_definition") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +public class LabActivityDefinition extends HisBaseEntity { + + /** 主键ID */ + @TableId(type = IdType.ASSIGN_ID) + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + /** 目录类别 */ + private String categoryCode; + + /** 编码 */ + private String busNo; + + /** 项目名称 */ + private String name; + + /** 项目名称拼音 */ + private String pyStr; + + /** 五笔拼音 */ + private String wbStr; + + /** 类型 */ + private Integer typeEnum; + + /** 使用单位 */ + private String permittedUnitCode; + + /** 所属科室 */ + @JsonSerialize(using = ToStringSerializer.class) + private Long orgId; + + /** 所在位置 */ + @JsonSerialize(using = ToStringSerializer.class) + private Long locationId; + + /** 医保标记 */ + private Integer ybFlag; + + /** 医保编码 */ + private String ybNo; + + /** 医保对码标记 */ + private Integer ybMatchFlag; + + /** 状态 */ + private Integer statusEnum; + + /** 身体部位 */ + private String bodySiteCode; + + /** 所需标本 */ + private String specimenCode; + + /** 说明 */ + private String descriptionText; + + /** 规则id */ + private Integer ruleId; + + /** 医保等级 */ + private Integer chrgitmLv; + + /** 子项json */ + private String childrenJson; + + /** 划价标记 */ + private Integer pricingFlag; + + /** 序号 */ + private Integer sortOrder; + + /** 服务范围 */ + private String serviceRange; + + /** 检验类型ID(关联 inspection_type 大类,逻辑关联无外键) */ + @JsonSerialize(using = ToStringSerializer.class) + private Long inspectionTypeId; + + /** 费用套餐ID(关联 inspection_basic_information,逻辑关联无外键) */ + @JsonSerialize(using = ToStringSerializer.class) + private Long feePackageId; + + /** 下级医技类型ID(关联 inspection_type 子类,逻辑关联无外键) */ + @JsonSerialize(using = ToStringSerializer.class) + private Long subItemId; +} diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/mapper/LabActivityDefinitionMapper.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/mapper/LabActivityDefinitionMapper.java new file mode 100644 index 00000000..b2bd6cee --- /dev/null +++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/mapper/LabActivityDefinitionMapper.java @@ -0,0 +1,13 @@ +package com.openhis.lab.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.openhis.lab.domain.LabActivityDefinition; +import org.springframework.stereotype.Repository; + +/** + * 检验项目定义 Mapper 接口 + */ +@Repository +public interface LabActivityDefinitionMapper extends BaseMapper { + +} diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/service/ILabActivityDefinitionService.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/service/ILabActivityDefinitionService.java new file mode 100644 index 00000000..a1dca52a --- /dev/null +++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/service/ILabActivityDefinitionService.java @@ -0,0 +1,18 @@ +package com.openhis.lab.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.openhis.lab.domain.LabActivityDefinition; + +/** + * 检验项目定义 Service 接口 + */ +public interface ILabActivityDefinitionService extends IService { + + /** + * 新增检验项目 + * + * @param labActivityDefinition 检验项目实体 + * @return 是否成功 + */ + boolean addLabActivityDefinition(LabActivityDefinition labActivityDefinition); +} diff --git a/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/service/impl/LabActivityDefinitionServiceImpl.java b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/service/impl/LabActivityDefinitionServiceImpl.java new file mode 100644 index 00000000..00f74ca4 --- /dev/null +++ b/openhis-server-new/openhis-domain/src/main/java/com/openhis/lab/service/impl/LabActivityDefinitionServiceImpl.java @@ -0,0 +1,63 @@ +package com.openhis.lab.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.core.common.utils.SecurityUtils; +import com.core.common.core.domain.model.LoginUser; +import com.openhis.lab.domain.LabActivityDefinition; +import com.openhis.lab.mapper.LabActivityDefinitionMapper; +import com.openhis.lab.service.ILabActivityDefinitionService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.List; + +/** + * 检验项目定义 Service 实现类 + */ +@Slf4j +@Service +public class LabActivityDefinitionServiceImpl + extends ServiceImpl + implements ILabActivityDefinitionService { + + /** + * 新增检验项目(检查编码唯一性) + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean addLabActivityDefinition(LabActivityDefinition labActivityDefinition) { + // 根据编码判断是否已存在 + List existing = baseMapper.selectList( + new LambdaQueryWrapper() + .eq(LabActivityDefinition::getBusNo, labActivityDefinition.getBusNo())); + if (!existing.isEmpty()) { + return false; + } + setRequiredFields(labActivityDefinition); + return baseMapper.insert(labActivityDefinition) == 1; + } + + /** + * 补全必填字段(create_by、tenant_id、create_time) + */ + private void setRequiredFields(LabActivityDefinition entity) { + String createBy = "system"; + Integer tenantId = 1; + try { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null) { + createBy = loginUser.getUsername(); + tenantId = loginUser.getTenantId() != null ? loginUser.getTenantId() : 1; + } + } catch (Exception ignored) { + } + entity.setCreateBy(createBy); + entity.setTenantId(tenantId); + if (entity.getCreateTime() == null) { + entity.setCreateTime(new Date()); + } + } +} diff --git a/openhis-server-new/openhis-domain/src/main/resources/mapper/lab/LabActivityDefinitionMapper.xml b/openhis-server-new/openhis-domain/src/main/resources/mapper/lab/LabActivityDefinitionMapper.xml new file mode 100644 index 00000000..0a34849f --- /dev/null +++ b/openhis-server-new/openhis-domain/src/main/resources/mapper/lab/LabActivityDefinitionMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/openhis-ui-vue3/src/api/lab/labActivityDefinition.js b/openhis-ui-vue3/src/api/lab/labActivityDefinition.js new file mode 100644 index 00000000..c39d5198 --- /dev/null +++ b/openhis-ui-vue3/src/api/lab/labActivityDefinition.js @@ -0,0 +1,60 @@ +import request from '@/utils/request'; + +/** + * 检验项目维护专属 API(操作 lab_activity_definition 表) + * 后端路径前缀:/lab/activity-definition + */ + +// 分页查询检验项目列表 +export function getLabActivityDefinitionPage(query) { + return request({ + url: '/lab/activity-definition/page', + method: 'get', + params: query, + }); +} + +// 查询检验项目详情 +export function getLabActivityDefinitionOne(id) { + return request({ + url: '/lab/activity-definition/one', + method: 'get', + params: { id }, + }); +} + +// 新增检验项目 +export function addLabActivityDefinition(data) { + return request({ + url: '/lab/activity-definition/add', + method: 'post', + data: data, + }); +} + +// 编辑检验项目 +export function editLabActivityDefinition(data) { + return request({ + url: '/lab/activity-definition/edit', + method: 'put', + data: data, + }); +} + +// 停用检验项目 +export function stopLabActivityDefinition(ids) { + return request({ + url: '/lab/activity-definition/stop', + method: 'put', + data: ids, + }); +} + +// 启用检验项目 +export function startLabActivityDefinition(ids) { + return request({ + url: '/lab/activity-definition/start', + method: 'put', + data: ids, + }); +} diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue index 1f0d10e5..ed8637cf 100644 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/diagnosis/diagnosis.vue @@ -293,7 +293,7 @@ function getList() { emits('diagnosisSave', false); } }); - getTcmDiagnosis({ encounterId: patientInfo.value.encounterId }).then((res) => { + getTcmDiagnosis({ encounterId: props.patientInfo.encounterId }).then((res) => { console.log('getTcmDiagnosis=======>', JSON.stringify(res.data.illness)); if (res.code == 200) { @@ -337,7 +337,6 @@ function init() { function handleImport() { if (!props.patientInfo || !props.patientInfo.encounterId) { - console.warn('患者就诊信息不完整,无法导入慢性病信息'); return; } @@ -355,8 +354,10 @@ function handleImport() { diagSrtNo: form.value.diagnosisList.length + 1, iptDiseTypeCode: 2, diagnosisDesc: '', - diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name, - diagnosisTime: new Date().toLocaleString('zh-CN') + diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name, + diagnosisTime: new Date().toLocaleString('zh-CN'), + //添加 patientId + patientId: props.patientInfo.patientId }, }); }); @@ -469,7 +470,6 @@ function handleAddDiagnosis() { * 添加诊断项 */ function addDiagnosisItem() { - console.log('执行添加诊断,当前列表长度:', form.value.diagnosisList.length); form.value.diagnosisList.push({ showPopover: false, name: undefined, @@ -479,12 +479,15 @@ function addDiagnosisItem() { iptDiseTypeCode: 2, diagnosisDesc: '', diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name, - diagnosisTime: new Date().toLocaleString('zh-CN') + diagnosisTime: new Date().toLocaleString('zh-CN'), + + // 新增这一行:为每个诊断项添加 patientId + patientId: props.patientInfo.patientId }); + if (form.value.diagnosisList.length == 1) { form.value.diagnosisList[0].maindiseFlag = 1; } - console.log('添加完成,新列表长度:', form.value.diagnosisList.length); } // 添加中医诊断 @@ -565,8 +568,6 @@ function handleMaindise(value, index) { * 保存诊断 */ function handleSaveDiagnosis() { - console.log('form.value.diagnosisList=======>', JSON.stringify(form.value.diagnosisList)); - for (let index = 0; index < (form.value.diagnosisList || []).length; index++) { const item = form.value.diagnosisList[index]; if (!item.diagSrtNo) { @@ -690,11 +691,13 @@ function handleNodeClick(data) { ybNo: data.ybNo, name: data.name, verificationStatusEnum: 4, - medTypeCode: undefined, // 不设默认值 + medTypeCode: undefined, diagSrtNo: form.value.diagnosisList.length + 1, definitionId: data.definitionId, diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name, - diagnosisTime: new Date().toLocaleString('zh-CN') + diagnosisTime: new Date().toLocaleString('zh-CN'), + // 添加 patientId + patientId: props.patientInfo.patientId }); if (form.value.diagnosisList.length == 1) { form.value.diagnosisList[0].maindiseFlag = 1; diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/index.vue b/openhis-ui-vue3/src/views/inpatientDoctor/home/index.vue index 200c29f9..ac02baab 100644 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/index.vue +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/index.vue @@ -151,6 +151,8 @@ const handleItemClick = (node) => { // 同时更新本地和全局状态,确保模块内组件和跨模块组件都能正确响应 updatePatientInfo(node); updateLocalPatientInfo(node); + // 关键修复:同步更新 currentPatientInfo,确保诊断组件能获取到 patientId 和 encounterId + currentPatientInfo.value = node; diagnosisRef.value?.getList(); diagnosisRef.value?.getDetail(node?.encounterId); diff --git a/openhis-ui-vue3/src/views/maintainSystem/Inspection/PackageManagement.vue b/openhis-ui-vue3/src/views/maintainSystem/Inspection/PackageManagement.vue index 7223cd6a..55850f61 100644 --- a/openhis-ui-vue3/src/views/maintainSystem/Inspection/PackageManagement.vue +++ b/openhis-ui-vue3/src/views/maintainSystem/Inspection/PackageManagement.vue @@ -431,9 +431,9 @@ async function loadData() { level: item.packageLevel || '', dept: item.department || '', user: item.userId || '', - amount: parseFloat(item.packageAmount || 0), + amount: parseFloat((parseFloat(item.packageAmount || 0) - parseFloat(item.serviceFee || 0)).toFixed(2)), fee: parseFloat(item.serviceFee || 0), - total: parseFloat(item.packageAmount || 0) + parseFloat(item.serviceFee || 0), + total: parseFloat(item.packageAmount || 0), combined: item.enablePackagePrice === true ? '是' : '否', display: item.showPackageName === true ? '是' : '否', enabled: item.isDisabled === true ? '否' : '是', diff --git a/openhis-ui-vue3/src/views/maintainSystem/Inspection/index.vue b/openhis-ui-vue3/src/views/maintainSystem/Inspection/index.vue index 282c1ce9..9ee72e11 100644 --- a/openhis-ui-vue3/src/views/maintainSystem/Inspection/index.vue +++ b/openhis-ui-vue3/src/views/maintainSystem/Inspection/index.vue @@ -816,11 +816,14 @@ import { } from '@/api/system/inspectionType'; import { getDiagnosisTreatmentList, - addDiagnosisTreatment, - editDiagnosisTreatment, - stopDiseaseTreatment, getDiseaseTreatmentInit } from '@/views/catalog/diagnosistreatment/components/diagnosistreatment'; +import { + getLabActivityDefinitionPage, + addLabActivityDefinition, + editLabActivityDefinition, + stopLabActivityDefinition +} from '@/api/lab/labActivityDefinition'; import {listLisGroup} from '@/api/system/checkType'; import { addInspectionPackage, @@ -1374,7 +1377,7 @@ const loadObservationItems = async (resetPage = false) => { } } - const response = await getDiagnosisTreatmentList(params); + const response = await getLabActivityDefinitionPage(params); if (response.code === 200) { let data = []; @@ -1643,25 +1646,37 @@ const cancelEditItem = (index) => { }; // 计算套餐金额和服务费 +// 规则: +// 单价 = 原始单价 × (折扣% / 100) +// 金额 = 折后单价 × 数量 +// 总金额 = 金额 + 服务费 +// 套餐金额 = 各行总金额之和 const calculateAmounts = () => { - // 更新每个项目的金额(金额 = 数量 × 单价,不受折扣影响)和总金额 + const discountRate = parseFloat(discount.value); + const hasDiscount = !isNaN(discountRate) && discountRate > 0; + packageItems.value.forEach(item => { - item.amount = parseFloat(((item.quantity || 1) * (item.unitPrice || 0.00)).toFixed(2)); - // serviceFee 由用户手动输入,不覆盖;只更新 totalAmount - item.totalAmount = parseFloat(((item.amount) + (item.serviceFee || 0)).toFixed(2)); + // 单价 = 原始单价 × 折扣比例 + const originalPrice = item.originalPrice != null ? item.originalPrice : item.unitPrice; + item.originalPrice = originalPrice; // 确保 originalPrice 始终保留 + if (hasDiscount) { + item.unitPrice = parseFloat((originalPrice * discountRate / 100).toFixed(2)); + } else { + item.unitPrice = parseFloat(originalPrice.toFixed(2)); + } + // 金额 = 折后单价 × 数量 + item.amount = parseFloat(((item.quantity || 1) * item.unitPrice).toFixed(2)); + // 总金额 = 金额 + 服务费 + item.totalAmount = parseFloat((item.amount + (item.serviceFee || 0)).toFixed(2)); }); // 汇总各明细行服务费到基本信息服务费(只读展示) serviceFee.value = parseFloat(packageItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0).toFixed(2)); - // 套餐总金额 = (各行金额之和 + 各行服务费之和) × 折扣比例 - const rawTotal = packageItems.value.reduce((sum, item) => sum + (item.amount || 0) + (item.serviceFee || 0), 0); - let finalTotal = rawTotal; - if (discount.value && !isNaN(parseFloat(discount.value)) && parseFloat(discount.value) > 0) { - const discountRate = parseFloat(discount.value) / 100; // 80 → 0.8,表示八折保留80% - finalTotal = rawTotal * discountRate; - } - packageAmount.value = parseFloat(finalTotal.toFixed(2)); + // 套餐金额 = 各行总金额之和 + packageAmount.value = parseFloat( + packageItems.value.reduce((sum, item) => sum + (item.totalAmount || 0), 0).toFixed(2) + ); }; const itemNameRefs = ref([]); @@ -2030,16 +2045,18 @@ const saveItem = async (item) => { // 判断是新增还是更新 if (typeof item.id === 'number') { // 临时ID(数字类型),新增 - const response = await addDiagnosisTreatment(submitData); + const response = await addLabActivityDefinition(submitData); if (response.code === 200) { ElMessage.success('添加成功'); + // 新增成功后跳到第1页,后端按id降序排列,最新数据在第1页首位 + inspectionCurrentPage.value = 1; await loadObservationItems(); } else { ElMessage.error(response.msg || '添加失败'); } } else { // 真实ID(字符串类型),更新 submitData.id = item.id; - const response = await editDiagnosisTreatment(submitData); + const response = await editLabActivityDefinition(submitData); if (response.code === 200) { ElMessage.success('更新成功'); await loadObservationItems(); @@ -2062,7 +2079,7 @@ const deleteItem = async (id) => { type: 'warning' }).then(async () => { try { - const response = await stopDiseaseTreatment([id]); + const response = await stopLabActivityDefinition([id]); if (response.code === 200) { ElMessage.success('删除成功'); await loadObservationItems(); @@ -2208,10 +2225,11 @@ const handleSave = () => { days: item.days, quantity: item.quantity, unit: item.unit, - unitPrice: item.unitPrice, + originalPrice: item.originalPrice != null ? item.originalPrice : item.unitPrice, // 原始单价 + unitPrice: item.unitPrice, // 折后单价 amount: item.amount, serviceFee: item.serviceFee || 0, - totalAmount: parseFloat(((item.amount || 0) + (item.serviceFee || 0)).toFixed(2)), + totalAmount: item.totalAmount, // 金额 + 服务费 origin: item.origin, createTime: new Date().toISOString(), updateTime: new Date().toISOString() @@ -2314,7 +2332,16 @@ const handleProjectInlineSearch = async (query, cb, row) => { const handleProjectInlineSelect = (selectedItem, row) => { row.name = selectedItem.name; row.spec = selectedItem.spec || ''; - row.unitPrice = parseFloat(selectedItem.retailPrice || 0); + // 保存原始单价,供折扣计算使用 + const originalPrice = parseFloat(selectedItem.retailPrice || 0); + row.originalPrice = originalPrice; + // 单价 = 原始单价 × 折扣比例 + const discountRate = parseFloat(discount.value); + if (!isNaN(discountRate) && discountRate > 0) { + row.unitPrice = parseFloat((originalPrice * discountRate / 100).toFixed(2)); + } else { + row.unitPrice = originalPrice; + } row.unit = selectedItem.permittedUnitCode_dictText || selectedItem.unit || '次'; if (!row.quantity) row.quantity = 1; row.amount = parseFloat((row.unitPrice * row.quantity).toFixed(2)); @@ -2557,21 +2584,39 @@ const loadInspectionPackage = async (packageId) => { remarks.value = basicData.remarks || ''; // 填充明细数据(必须映射 id,否则取消编辑时会被误判为新增行删除) - packageItems.value = detailData.map(item => ({ - id: item.detailId || item.id, - name: item.itemName || item.name, - dosage: item.dosage || '', - route: item.route || '', - frequency: item.frequency || '', - days: item.days || '', - quantity: item.quantity || 1, - unit: item.unit || '', - unitPrice: parseFloat(item.unitPrice || 0), - amount: parseFloat(item.amount || 0), - serviceFee: parseFloat(item.serviceFee || 0), - totalAmount: parseFloat(item.totalAmount || 0), - origin: item.origin || '' - })); + const loadedDiscount = parseFloat(basicData.discount); + packageItems.value = detailData.map(item => { + const savedOriginalPrice = parseFloat(item.originalPrice || 0); + const savedUnitPrice = parseFloat(item.unitPrice || 0); + // 恢复原始单价: + // 1. 后端有 originalPrice 时直接用 + // 2. 旧数据无 originalPrice 时,通过折扣反推:originalPrice = unitPrice / (discount/100) + let originalPrice; + if (savedOriginalPrice > 0) { + originalPrice = savedOriginalPrice; + } else if (!isNaN(loadedDiscount) && loadedDiscount > 0 && loadedDiscount !== 100) { + originalPrice = parseFloat((savedUnitPrice / (loadedDiscount / 100)).toFixed(2)); + } else { + // 折扣为空或100(原价),originalPrice = unitPrice + originalPrice = savedUnitPrice; + } + return { + id: item.detailId || item.id, + name: item.itemName || item.name, + dosage: item.dosage || '', + route: item.route || '', + frequency: item.frequency || '', + days: item.days || '', + quantity: item.quantity || 1, + unit: item.unit || '', + originalPrice, + unitPrice: savedUnitPrice, + amount: parseFloat(item.amount || 0), + serviceFee: parseFloat(item.serviceFee || 0), + totalAmount: parseFloat(item.totalAmount || 0), + origin: item.origin || '' + }; + }); // 恢复监听 isLoadingPackage.value = false;