Merge remote-tracking branch 'origin/develop' into zhaoyun
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
package com.healthlink.his.web.empi.appservice;
|
||||
|
||||
import com.healthlink.his.administration.domain.Patient;
|
||||
import com.healthlink.his.empi.domain.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface IEmpiAppService {
|
||||
EmpiPerson registerPerson(EmpiPerson p);
|
||||
void mergePersons(Long primaryId, List<Long> secondaryIds);
|
||||
@@ -9,4 +12,7 @@ public interface IEmpiAppService {
|
||||
EmpiPerson findByIdCard(String idCardNo);
|
||||
List<EmpiPersonIdMapping> getMappings(String globalId);
|
||||
Map<String, Object> getStatistics();
|
||||
}
|
||||
List<Patient> findLinkedPatients(String globalId);
|
||||
List<Patient> findLinkedPatientsByIdCard(String idCardNo);
|
||||
List<EmpiPerson> listPersons(String name, String idCardNo);
|
||||
}
|
||||
@@ -1,54 +1,116 @@
|
||||
package com.healthlink.his.web.empi.appservice.impl;
|
||||
import com.healthlink.his.empi.domain.*;
|
||||
import com.healthlink.his.empi.service.*;
|
||||
import com.healthlink.his.web.empi.appservice.IEmpiAppService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.healthlink.his.administration.domain.Patient;
|
||||
import com.healthlink.his.administration.service.IPatientService;
|
||||
import com.healthlink.his.empi.domain.EmpiPerson;
|
||||
import com.healthlink.his.empi.domain.EmpiPersonIdMapping;
|
||||
import com.healthlink.his.empi.service.IEmpiPersonIdMappingService;
|
||||
import com.healthlink.his.empi.service.IEmpiPersonService;
|
||||
import com.healthlink.his.web.empi.appservice.IEmpiAppService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class EmpiAppServiceImpl implements IEmpiAppService {
|
||||
@Autowired private IEmpiPersonService personService;
|
||||
@Autowired private IEmpiPersonIdMappingService mappingService;
|
||||
@Autowired private IPatientService patientService;
|
||||
|
||||
@Override
|
||||
public EmpiPerson registerPerson(EmpiPerson p) {
|
||||
p.setGlobalId(UUID.randomUUID().toString().replace("-", "").substring(0, 16).toUpperCase());
|
||||
p.setMergeStatus("ACTIVE"); personService.save(p); return p;
|
||||
p.setMergeStatus("ACTIVE");
|
||||
personService.save(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergePersons(Long primaryId, List<Long> secondaryIds) {
|
||||
EmpiPerson primary = personService.getById(primaryId);
|
||||
for (Long secId : secondaryIds) {
|
||||
EmpiPerson sec = personService.getById(secId);
|
||||
if (sec == null) continue;
|
||||
List<EmpiPersonIdMapping> mappings = mappingService.list(new LambdaQueryWrapper<EmpiPersonIdMapping>()
|
||||
.eq(EmpiPersonIdMapping::getGlobalId, personService.getById(secId).getGlobalId()));
|
||||
.eq(EmpiPersonIdMapping::getGlobalId, sec.getGlobalId()));
|
||||
for (EmpiPersonIdMapping m : mappings) {
|
||||
m.setGlobalId(primary.getGlobalId());
|
||||
mappingService.updateById(m);
|
||||
}
|
||||
EmpiPerson sec = personService.getById(secId);
|
||||
sec.setMergeStatus("MERGED"); personService.updateById(sec);
|
||||
sec.setMergeStatus("MERGED");
|
||||
personService.updateById(sec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmpiPerson findByGlobalId(String globalId) {
|
||||
return personService.getOne(new LambdaQueryWrapper<EmpiPerson>().eq(EmpiPerson::getGlobalId, globalId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmpiPerson findByIdCard(String idCardNo) {
|
||||
return personService.getOne(new LambdaQueryWrapper<EmpiPerson>().eq(EmpiPerson::getIdCardNo, idCardNo));
|
||||
return personService.getOne(new LambdaQueryWrapper<EmpiPerson>().eq(EmpiPerson::getIdCardNo, idCardNo).last("LIMIT 1"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmpiPersonIdMapping> getMappings(String globalId) {
|
||||
return mappingService.list(new LambdaQueryWrapper<EmpiPersonIdMapping>().eq(EmpiPersonIdMapping::getGlobalId, globalId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getStatistics() {
|
||||
Map<String, Object> r = new HashMap<>();
|
||||
r.put("totalPersons", personService.count());
|
||||
r.put("activePersons", personService.count(new LambdaQueryWrapper<EmpiPerson>().eq(EmpiPerson::getMergeStatus, "ACTIVE")));
|
||||
r.put("mergedPersons", personService.count(new LambdaQueryWrapper<EmpiPerson>().eq(EmpiPerson::getMergeStatus, "MERGED")));
|
||||
long total = personService.count();
|
||||
long activeCount = personService.count(new LambdaQueryWrapper<EmpiPerson>().eq(EmpiPerson::getMergeStatus, "ACTIVE"));
|
||||
long mergedCount = personService.count(new LambdaQueryWrapper<EmpiPerson>().eq(EmpiPerson::getMergeStatus, "MERGED"));
|
||||
r.put("totalPersons", total);
|
||||
r.put("activePersons", activeCount);
|
||||
r.put("mergedPersons", mergedCount);
|
||||
r.put("totalMappings", mappingService.count());
|
||||
r.put("pendingMerges", total > 0 ? total - activeCount - mergedCount : 0);
|
||||
r.put("duplicateRate", total > 0 ? Math.round((double) mergedCount / total * 10000) / 100.0 : 0);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过全局ID查询关联的院内患者记录
|
||||
*/
|
||||
public List<Patient> findLinkedPatients(String globalId) {
|
||||
List<EmpiPersonIdMapping> mappings = mappingService.list(
|
||||
new LambdaQueryWrapper<EmpiPersonIdMapping>().eq(EmpiPersonIdMapping::getGlobalId, globalId));
|
||||
if (mappings.isEmpty()) return Collections.emptyList();
|
||||
|
||||
List<Long> patientIds = mappings.stream()
|
||||
.map(EmpiPersonIdMapping::getLocalPatientId)
|
||||
.collect(Collectors.toList());
|
||||
return patientService.listByIds(patientIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过身份证号查询关联的院内患者记录
|
||||
*/
|
||||
public List<Patient> findLinkedPatientsByIdCard(String idCardNo) {
|
||||
EmpiPerson person = findByIdCard(idCardNo);
|
||||
if (person == null) return Collections.emptyList();
|
||||
return findLinkedPatients(person.getGlobalId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询EMPI患者列表
|
||||
*/
|
||||
@Override
|
||||
public List<EmpiPerson> listPersons(String name, String idCardNo) {
|
||||
LambdaQueryWrapper<EmpiPerson> wrapper = new LambdaQueryWrapper<>();
|
||||
if (name != null && !name.isEmpty()) {
|
||||
wrapper.like(EmpiPerson::getName, name);
|
||||
}
|
||||
if (idCardNo != null && !idCardNo.isEmpty()) {
|
||||
wrapper.like(EmpiPerson::getIdCardNo, idCardNo);
|
||||
}
|
||||
wrapper.orderByDesc(EmpiPerson::getId);
|
||||
return personService.list(wrapper);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
package com.healthlink.his.web.empi.controller;
|
||||
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.healthlink.his.empi.domain.*;
|
||||
import com.healthlink.his.web.empi.appservice.IEmpiAppService;
|
||||
@@ -7,19 +8,69 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
@Tag(name = "患者主索引(EMPI)") @RestController @RequestMapping("/api/v1/empi")
|
||||
|
||||
@Tag(name = "患者主索引(EMPI)")
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/empi")
|
||||
public class EmpiController {
|
||||
@Autowired private IEmpiAppService empiAppService;
|
||||
@Operation(summary = "注册患者") @PostMapping("/person")
|
||||
public AjaxResult register(@RequestBody EmpiPerson p) { return AjaxResult.success(empiAppService.registerPerson(p)); }
|
||||
@Operation(summary = "合并患者") @PostMapping("/merge")
|
||||
public AjaxResult merge(@RequestParam Long primaryId, @RequestParam List<Long> secondaryIds) { empiAppService.mergePersons(primaryId, secondaryIds); return AjaxResult.success(); }
|
||||
@Operation(summary = "按全局ID查询") @GetMapping("/person/global/{globalId}")
|
||||
public AjaxResult findByGlobalId(@PathVariable String globalId) { return AjaxResult.success(empiAppService.findByGlobalId(globalId)); }
|
||||
@Operation(summary = "按身份证查询") @GetMapping("/person/idcard/{idCardNo}")
|
||||
public AjaxResult findByIdCard(@PathVariable String idCardNo) { return AjaxResult.success(empiAppService.findByIdCard(idCardNo)); }
|
||||
@Operation(summary = "ID映射") @GetMapping("/mappings/{globalId}")
|
||||
public AjaxResult mappings(@PathVariable String globalId) { return AjaxResult.success(empiAppService.getMappings(globalId)); }
|
||||
@Operation(summary = "统计") @GetMapping("/statistics")
|
||||
public AjaxResult statistics() { return AjaxResult.success(empiAppService.getStatistics()); }
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private IEmpiAppService empiAppService;
|
||||
|
||||
@Operation(summary = "注册患者")
|
||||
@PostMapping("/person")
|
||||
public AjaxResult register(@RequestBody EmpiPerson p) {
|
||||
return AjaxResult.success(empiAppService.registerPerson(p));
|
||||
}
|
||||
|
||||
@Operation(summary = "合并患者")
|
||||
@PostMapping("/merge")
|
||||
public AjaxResult merge(@RequestParam Long primaryId, @RequestParam List<Long> secondaryIds) {
|
||||
empiAppService.mergePersons(primaryId, secondaryIds);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "按全局ID查询EMPI")
|
||||
@GetMapping("/person/global/{globalId}")
|
||||
public AjaxResult findByGlobalId(@PathVariable String globalId) {
|
||||
return AjaxResult.success(empiAppService.findByGlobalId(globalId));
|
||||
}
|
||||
|
||||
@Operation(summary = "按身份证查询EMPI")
|
||||
@GetMapping("/person/idcard/{idCardNo}")
|
||||
public AjaxResult findByIdCard(@PathVariable String idCardNo) {
|
||||
return AjaxResult.success(empiAppService.findByIdCard(idCardNo));
|
||||
}
|
||||
|
||||
@Operation(summary = "ID映射")
|
||||
@GetMapping("/mappings/{globalId}")
|
||||
public AjaxResult mappings(@PathVariable String globalId) {
|
||||
return AjaxResult.success(empiAppService.getMappings(globalId));
|
||||
}
|
||||
|
||||
@Operation(summary = "统计")
|
||||
@GetMapping("/statistics")
|
||||
public AjaxResult statistics() {
|
||||
return AjaxResult.success(empiAppService.getStatistics());
|
||||
}
|
||||
|
||||
@Operation(summary = "通过全局ID查询关联的院内患者记录")
|
||||
@GetMapping("/linked-patients/global/{globalId}")
|
||||
public AjaxResult findLinkedPatientsByGlobalId(@PathVariable String globalId) {
|
||||
return AjaxResult.success(empiAppService.findLinkedPatients(globalId));
|
||||
}
|
||||
|
||||
@Operation(summary = "通过身份证号查询关联的院内患者记录")
|
||||
@GetMapping("/linked-patients/idcard/{idCardNo}")
|
||||
public AjaxResult findLinkedPatientsByIdCard(@PathVariable String idCardNo) {
|
||||
return AjaxResult.success(empiAppService.findLinkedPatientsByIdCard(idCardNo));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询EMPI患者列表")
|
||||
@GetMapping("/persons")
|
||||
public AjaxResult listPersons(
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String idCardNo) {
|
||||
return AjaxResult.success(empiAppService.listPersons(name, idCardNo));
|
||||
}
|
||||
}
|
||||
@@ -366,7 +366,15 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
|
||||
// 根据执行状态过滤医嘱列表
|
||||
List<InpatientAdviceDto> filteredList = new ArrayList<>();
|
||||
if (EventStatus.COMPLETED.getValue().equals(exeStatus)) {
|
||||
if (EventStatus.PREPARATION.getValue().equals(exeStatus)) {
|
||||
// 待执行 - 过滤出没有已执行记录的医嘱(Bug #663修复)
|
||||
filteredList = inpatientAdviceList.stream().filter(
|
||||
advice -> advice.getExePerformRecordList() == null || advice.getExePerformRecordList().isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
// 更新分页数据
|
||||
inpatientAdvicePage.setRecords(filteredList);
|
||||
inpatientAdvicePage.setTotal(filteredList.size());
|
||||
} else if (EventStatus.COMPLETED.getValue().equals(exeStatus)) {
|
||||
// 已执行 - 过滤出有执行记录的医嘱
|
||||
filteredList = inpatientAdviceList.stream().filter(
|
||||
advice -> advice.getExePerformRecordList() != null && !advice.getExePerformRecordList().isEmpty())
|
||||
|
||||
@@ -29,7 +29,9 @@ import com.healthlink.his.web.patientmanage.dto.PatientBaseInfoDto;
|
||||
import com.healthlink.his.web.patientmanage.dto.PatientIdInfoDto;
|
||||
import com.healthlink.his.web.patientmanage.dto.PatientInfoInitDto;
|
||||
import com.healthlink.his.web.patientmanage.mapper.PatientManageMapper;
|
||||
import com.healthlink.his.empi.event.PatientSavedEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
@@ -54,6 +56,9 @@ public class PatientInformationServiceImpl implements IPatientInformationService
|
||||
@Autowired
|
||||
PatientManageMapper patientManageMapper;
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private IPatientService patientService;
|
||||
|
||||
@@ -379,9 +384,13 @@ public class PatientInformationServiceImpl implements IPatientInformationService
|
||||
.set(Patient::getEducationLevel, patient.getEducationLevel())
|
||||
.set(Patient::getCompanyAddress, patient.getCompanyAddress());
|
||||
patientService.update(updateWrapper);
|
||||
// 发布患者保存事件,触发EMPI同步
|
||||
eventPublisher.publishEvent(new PatientSavedEvent(this, patient, false));
|
||||
} else {
|
||||
// 新增操作
|
||||
patientService.save(patient);
|
||||
// 发布患者保存事件,触发EMPI同步
|
||||
eventPublisher.publishEvent(new PatientSavedEvent(this, patient, true));
|
||||
}
|
||||
|
||||
return patient;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
-- V2026_0616_1: EMPI核心表 — empi_person + empi_person_id_mapping
|
||||
-- 补充 V20 中遗漏的两张EMPI核心表
|
||||
|
||||
-- 1. EMPI主索引表(全局患者主记录)
|
||||
CREATE TABLE IF NOT EXISTS empi_person (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
global_id VARCHAR(32) NOT NULL,
|
||||
id_card_no VARCHAR(20),
|
||||
patient_name VARCHAR(50),
|
||||
gender VARCHAR(10),
|
||||
birth_date DATE,
|
||||
phone VARCHAR(20),
|
||||
address TEXT,
|
||||
merge_status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
source_system VARCHAR(50),
|
||||
create_by VARCHAR(64),
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
update_by VARCHAR(64),
|
||||
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
tenant_id INT DEFAULT 0,
|
||||
delete_flag VARCHAR(1) NOT NULL DEFAULT '0'
|
||||
);
|
||||
COMMENT ON TABLE empi_person IS 'EMPI患者主索引';
|
||||
COMMENT ON COLUMN empi_person.global_id IS '全局唯一患者ID';
|
||||
COMMENT ON COLUMN empi_person.merge_status IS '合并状态(ACTIVE/MERGED)';
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_ep_global ON empi_person(global_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ep_idcard ON empi_person(id_card_no);
|
||||
CREATE INDEX IF NOT EXISTS idx_ep_name ON empi_person(patient_name);
|
||||
|
||||
-- 2. EMPI ID映射表(全局ID与院内系统患者ID的映射关系)
|
||||
CREATE TABLE IF NOT EXISTS empi_person_id_mapping (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
global_id VARCHAR(32) NOT NULL,
|
||||
local_patient_id BIGINT NOT NULL,
|
||||
source_system VARCHAR(50) NOT NULL,
|
||||
id_type VARCHAR(20) NOT NULL,
|
||||
id_value VARCHAR(100) NOT NULL,
|
||||
create_by VARCHAR(64),
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
update_by VARCHAR(64),
|
||||
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
tenant_id INT DEFAULT 0,
|
||||
delete_flag VARCHAR(1) NOT NULL DEFAULT '0'
|
||||
);
|
||||
COMMENT ON TABLE empi_person_id_mapping IS 'EMPI患者ID映射表';
|
||||
COMMENT ON COLUMN empi_person_id_mapping.global_id IS 'EMPI全局患者ID';
|
||||
COMMENT ON COLUMN empi_person_id_mapping.local_patient_id IS '院内患者ID';
|
||||
COMMENT ON COLUMN empi_person_id_mapping.source_system IS '来源系统编码';
|
||||
COMMENT ON COLUMN empi_person_id_mapping.id_type IS '标识类型(MRN/INSURANCE/CARD等)';
|
||||
COMMENT ON COLUMN empi_person_id_mapping.id_value IS '标识值';
|
||||
CREATE INDEX IF NOT EXISTS idx_epim_global ON empi_person_id_mapping(global_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_epim_local ON empi_person_id_mapping(local_patient_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_epim_source ON empi_person_id_mapping(source_system);
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.healthlink.his.empi.event;
|
||||
|
||||
import com.healthlink.his.administration.domain.Patient;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
public class PatientSavedEvent extends ApplicationEvent {
|
||||
private final Patient patient;
|
||||
private final boolean isNew;
|
||||
|
||||
public PatientSavedEvent(Object source, Patient patient, boolean isNew) {
|
||||
super(source);
|
||||
this.patient = patient;
|
||||
this.isNew = isNew;
|
||||
}
|
||||
|
||||
public Patient getPatient() { return patient; }
|
||||
public boolean isNew() { return isNew; }
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.healthlink.his.empi.listener;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.healthlink.his.administration.domain.Patient;
|
||||
import com.healthlink.his.empi.domain.EmpiPerson;
|
||||
import com.healthlink.his.empi.domain.EmpiPersonIdMapping;
|
||||
import com.healthlink.his.empi.event.PatientSavedEvent;
|
||||
import com.healthlink.his.empi.service.IEmpiPersonIdMappingService;
|
||||
import com.healthlink.his.empi.service.IEmpiPersonService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class EmpiSyncListener {
|
||||
|
||||
@Autowired
|
||||
private IEmpiPersonService empiPersonService;
|
||||
|
||||
@Autowired
|
||||
private IEmpiPersonIdMappingService empiPersonIdMappingService;
|
||||
|
||||
@EventListener
|
||||
public void onPatientSaved(PatientSavedEvent event) {
|
||||
Patient patient = event.getPatient();
|
||||
try {
|
||||
if (event.isNew()) {
|
||||
syncNewPatient(patient);
|
||||
} else {
|
||||
syncUpdatedPatient(patient);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("EMPI同步失败, patientId={}, error={}", patient.getId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncNewPatient(Patient patient) {
|
||||
String idCard = patient.getIdCard();
|
||||
EmpiPerson existingPerson = null;
|
||||
if (idCard != null && !idCard.isEmpty()) {
|
||||
existingPerson = empiPersonService.getOne(
|
||||
new LambdaQueryWrapper<EmpiPerson>()
|
||||
.eq(EmpiPerson::getIdCardNo, idCard)
|
||||
.eq(EmpiPerson::getMergeStatus, "ACTIVE"));
|
||||
}
|
||||
|
||||
if (existingPerson == null) {
|
||||
EmpiPerson person = new EmpiPerson();
|
||||
person.setGlobalId(UUID.randomUUID().toString().replace("-", "").substring(0, 16).toUpperCase());
|
||||
person.setIdCardNo(idCard);
|
||||
person.setName(patient.getName());
|
||||
person.setGender(patient.getGenderEnum() != null && patient.getGenderEnum() == 1 ? "M" : "F");
|
||||
person.setBirthDate(patient.getBirthDate());
|
||||
person.setPhone(patient.getPhone());
|
||||
person.setAddress(patient.getAddress());
|
||||
person.setMergeStatus("ACTIVE");
|
||||
person.setSourceSystem("HIS");
|
||||
empiPersonService.save(person);
|
||||
existingPerson = person;
|
||||
log.info("EMPI主索引创建: globalId={}, patientId={}", existingPerson.getGlobalId(), patient.getId());
|
||||
}
|
||||
|
||||
createMappingIfNeeded(existingPerson.getGlobalId(), patient);
|
||||
}
|
||||
|
||||
private void syncUpdatedPatient(Patient patient) {
|
||||
EmpiPersonIdMapping mapping = empiPersonIdMappingService.getOne(
|
||||
new LambdaQueryWrapper<EmpiPersonIdMapping>()
|
||||
.eq(EmpiPersonIdMapping::getLocalPatientId, patient.getId()));
|
||||
|
||||
if (mapping != null) {
|
||||
EmpiPerson person = empiPersonService.getOne(
|
||||
new LambdaQueryWrapper<EmpiPerson>()
|
||||
.eq(EmpiPerson::getGlobalId, mapping.getGlobalId()));
|
||||
if (person != null) {
|
||||
person.setName(patient.getName());
|
||||
person.setGender(patient.getGenderEnum() != null && patient.getGenderEnum() == 1 ? "M" : "F");
|
||||
person.setBirthDate(patient.getBirthDate());
|
||||
person.setPhone(patient.getPhone());
|
||||
person.setAddress(patient.getAddress());
|
||||
empiPersonService.updateById(person);
|
||||
}
|
||||
} else {
|
||||
syncNewPatient(patient);
|
||||
}
|
||||
}
|
||||
|
||||
private void createMappingIfNeeded(String globalId, Patient patient) {
|
||||
EmpiPersonIdMapping existing = empiPersonIdMappingService.getOne(
|
||||
new LambdaQueryWrapper<EmpiPersonIdMapping>()
|
||||
.eq(EmpiPersonIdMapping::getGlobalId, globalId)
|
||||
.eq(EmpiPersonIdMapping::getLocalPatientId, patient.getId()));
|
||||
|
||||
if (existing == null) {
|
||||
EmpiPersonIdMapping mapping = new EmpiPersonIdMapping();
|
||||
mapping.setGlobalId(globalId);
|
||||
mapping.setLocalPatientId(patient.getId());
|
||||
mapping.setSourceSystem("HIS");
|
||||
mapping.setIdType("MRN");
|
||||
mapping.setIdValue(patient.getBusNo() != null ? patient.getBusNo() : String.valueOf(patient.getId()));
|
||||
empiPersonIdMappingService.save(mapping);
|
||||
log.info("EMPI映射创建: globalId={}, patientId={}", globalId, patient.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// EMPI基础操作
|
||||
export function registerPerson(data) { return request({ url: '/api/v1/empi/person', method: 'post', data }) }
|
||||
export function mergePersons(primaryId, secondaryIds) { return request({ url: '/api/v1/empi/merge', method: 'post', params: { primaryId, secondaryIds: secondaryIds.join(',') } }) }
|
||||
export function findByGlobalId(globalId) { return request({ url: '/api/v1/empi/person/global/' + globalId, method: 'get' }) }
|
||||
export function findByIdCard(idCardNo) { return request({ url: '/api/v1/empi/person/idcard/' + idCardNo, method: 'get' }) }
|
||||
export function getMappings(globalId) { return request({ url: '/api/v1/empi/mappings/' + globalId, method: 'get' }) }
|
||||
export function getStatistics() { return request({ url: '/api/v1/empi/statistics', method: 'get' }) }
|
||||
export function listPersons(params) { return request({ url: '/api/v1/empi/persons', method: 'get', params }) }
|
||||
|
||||
// 关联院内患者查询
|
||||
export function findLinkedPatientsByGlobalId(globalId) { return request({ url: '/api/v1/empi/linked-patients/global/' + globalId, method: 'get' }) }
|
||||
export function findLinkedPatientsByIdCard(idCardNo) { return request({ url: '/api/v1/empi/linked-patients/idcard/' + idCardNo, method: 'get' }) }
|
||||
|
||||
// EMPI增强功能
|
||||
export function getPhotos(patientId) { return request({ url: '/empi-enhanced/photo/list', method: 'get', params: { patientId } }) }
|
||||
export function addPhoto(data) { return request({ url: '/empi-enhanced/photo/add', method: 'post', data }) }
|
||||
export function getFamilyMembers(patientId) { return request({ url: '/empi-enhanced/family/list', method: 'get', params: { patientId } }) }
|
||||
@@ -14,4 +21,4 @@ export function addFamilyMember(data) { return request({ url: '/empi-enhanced/fa
|
||||
export function deleteFamilyMember(id) { return request({ url: '/empi-enhanced/family/delete', method: 'delete', params: { id } }) }
|
||||
export function getMergeLogPage(params) { return request({ url: '/empi-enhanced/merge-log/page', method: 'get', params }) }
|
||||
export function addMergeLog(data) { return request({ url: '/empi-enhanced/merge-log/add', method: 'post', data }) }
|
||||
export function undoMergeLog(data) { return request({ url: '/empi-enhanced/merge-log/undo', method: 'post', data }) }
|
||||
export function undoMergeLog(data) { return request({ url: '/empi-enhanced/merge-log/undo', method: 'post', data }) }
|
||||
@@ -1,29 +1,105 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card>
|
||||
<template #header><span>患者合并管理</span></template>
|
||||
<template #header>
|
||||
<div style="display:flex;justify-content:space-between;align-items:center">
|
||||
<span>患者合并管理</span>
|
||||
<el-button type="primary" :disabled="!primaryPatient" @click="handleMerge">
|
||||
合并选中患者 ({{ selectedRows.length }})
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :inline="true" class="mb8">
|
||||
<el-form-item label="主患者ID"><el-input v-model="primaryId" placeholder="主患者ID" /></el-form-item>
|
||||
<el-form-item label="待合并ID"><el-input v-model="secondaryIds" placeholder="逗号分隔多个ID" /></el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="searchName" placeholder="患者姓名" clearable @keyup.enter="loadPatients" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号">
|
||||
<el-input v-model="searchIdCard" placeholder="身份证号" clearable @keyup.enter="loadPatients" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleMerge">合并</el-button>
|
||||
<el-button type="primary" @click="loadPatients">查询</el-button>
|
||||
<el-button @click="searchName=''; searchIdCard=''; loadPatients()">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<el-card class="mt8">
|
||||
<template #header><span>合并日志</span></template>
|
||||
<el-table v-loading="loading" :data="mergeLogs">
|
||||
<el-table-column label="主患者" prop="primaryPatientName" width="120" />
|
||||
<el-table-column label="被合并患者" prop="secondaryPatientName" width="120" />
|
||||
<el-table-column label="合并原因" prop="mergeReason" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="操作人" prop="operatorName" width="100" />
|
||||
<el-table-column label="合并时间" prop="mergeTime" width="170" />
|
||||
<el-table-column label="状态" prop="status" width="90">
|
||||
<template #default="s"><el-tag :type="s.row.status==='ACTIVE'?'success':'info'">{{ s.row.status === 'ACTIVE' ? '有效' : '已撤销' }}</el-tag></template>
|
||||
<el-alert type="info" :closable="false" style="margin-bottom:12px">
|
||||
先点击"设为主患者"选一个保留的,再勾选要合并的其他患者,最后点右上角合并按钮
|
||||
</el-alert>
|
||||
<el-table v-loading="loading" :data="patientList" border stripe @selection-change="handleSelectionChange" row-key="id">
|
||||
<el-table-column type="selection" width="50" :selectable="canSelect" />
|
||||
<el-table-column prop="id" label="ID" width="60" />
|
||||
<el-table-column prop="globalId" label="全局ID" width="160" />
|
||||
<el-table-column prop="name" label="姓名" width="100">
|
||||
<template #default="{row}">
|
||||
<span :style="primaryPatient && primaryPatient.id === row.id ? 'color:#409eff;font-weight:bold' : ''">
|
||||
{{ row.name }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="gender" label="性别" width="60">
|
||||
<template #default="{row}">{{ row.gender === 'M' ? '男' : row.gender === 'F' ? '女' : row.gender }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="birthDate" label="出生日期" width="110">
|
||||
<template #default="{row}">{{ row.birthDate ? row.birthDate.substring(0,10) : '' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="idCardNo" label="身份证号" width="180" />
|
||||
<el-table-column prop="phone" label="电话" width="130" />
|
||||
<el-table-column prop="mergeStatus" label="状态" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.mergeStatus === 'ACTIVE' ? 'success' : row.mergeStatus === 'MERGED' ? 'info' : 'warning'" size="small">
|
||||
{{ row.mergeStatus === 'ACTIVE' ? '正常' : row.mergeStatus === 'MERGED' ? '已合并' : '待处理' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="s">
|
||||
<el-button link type="warning" v-if="s.row.status==='ACTIVE'" @click="handleUndo(s.row)">撤销</el-button>
|
||||
<template #default="{row}">
|
||||
<el-button link type="primary" size="small"
|
||||
:type="primaryPatient && primaryPatient.id === row.id ? 'success' : ''"
|
||||
@click="setPrimary(row)">
|
||||
{{ primaryPatient && primaryPatient.id === row.id ? '已选为主' : '设为主患者' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="confirmVisible" title="确认合并" width="500px">
|
||||
<el-descriptions title="主患者(保留)" :column="2" border size="small">
|
||||
<el-descriptions-item label="姓名">{{ primaryPatient?.name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="全局ID">{{ primaryPatient?.globalId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="身份证">{{ primaryPatient?.idCardNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="电话">{{ primaryPatient?.phone }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-divider />
|
||||
<p style="font-weight:bold;margin-bottom:8px">将被合并的患者({{ selectedRows.length }}人):</p>
|
||||
<el-table :data="selectedRows" border size="small" max-height="200">
|
||||
<el-table-column prop="name" label="姓名" width="80" />
|
||||
<el-table-column prop="globalId" label="全局ID" width="160" />
|
||||
<el-table-column prop="idCardNo" label="身份证号" width="180" />
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<el-button @click="confirmVisible = false">取消</el-button>
|
||||
<el-button type="danger" @click="doMerge">确认合并</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-card style="margin-top:16px">
|
||||
<template #header><span>合并日志</span></template>
|
||||
<el-table v-loading="logLoading" :data="mergeLogs" border stripe>
|
||||
<el-table-column label="主患者" prop="sourcePatientId" width="120">
|
||||
<template #default="{row}">{{ getPatientName(row.sourcePatientId) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="被合并" prop="targetPatientId" width="120">
|
||||
<template #default="{row}">{{ getPatientName(row.targetPatientId) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" prop="mergeType" width="80" />
|
||||
<el-table-column label="原因" prop="mergeReason" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="操作人" prop="mergeBy" width="90" />
|
||||
<el-table-column label="时间" prop="mergeTime" width="170" />
|
||||
<el-table-column label="状态" prop="status" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.status==='MERGED'?'success':'info'" size="small">
|
||||
{{ row.status === 'MERGED' ? '已合并' : '已撤回' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -33,22 +109,73 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { mergePersons, getMergeLogPage, undoMergeLog } from '../api'
|
||||
import { mergePersons, getMergeLogPage, listPersons } from '../api'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const loading = ref(false); const mergeLogs = ref([])
|
||||
const primaryId = ref(''); const secondaryIds = ref('')
|
||||
const loading = ref(false)
|
||||
const logLoading = ref(false)
|
||||
const patientList = ref([])
|
||||
const mergeLogs = ref([])
|
||||
const searchName = ref('')
|
||||
const searchIdCard = ref('')
|
||||
const primaryPatient = ref(null)
|
||||
const selectedRows = ref([])
|
||||
const confirmVisible = ref(false)
|
||||
const tableRef = ref(null)
|
||||
|
||||
const loadLogs = async () => { loading.value = true; const res = await getMergeLogPage({ pageNo: 1, pageSize: 20 }); mergeLogs.value = res.data?.records || []; loading.value = false }
|
||||
const handleMerge = async () => {
|
||||
if (!primaryId.value || !secondaryIds.value) { ElMessage.warning('请填写ID'); return }
|
||||
await ElMessageBox.confirm('确认合并?', '提示', { type: 'warning' })
|
||||
await mergePersons(primaryId.value, secondaryIds.value.split(',').map(Number))
|
||||
ElMessage.success('合并成功'); primaryId.value = ''; secondaryIds.value = ''; loadLogs()
|
||||
const loadPatients = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await listPersons({ name: searchName.value, idCardNo: searchIdCard.value })
|
||||
patientList.value = res.data || []
|
||||
} catch (e) {
|
||||
patientList.value = []
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
const handleUndo = async (row) => {
|
||||
await ElMessageBox.confirm('确认撤销合并?', '提示', { type: 'warning' })
|
||||
await undoMergeLog({ id: row.id, operatorName: '管理员' }); ElMessage.success('已撤销'); loadLogs()
|
||||
|
||||
const loadLogs = async () => {
|
||||
logLoading.value = true
|
||||
const res = await getMergeLogPage({ pageNo: 1, pageSize: 20 })
|
||||
mergeLogs.value = res.data?.records || []
|
||||
logLoading.value = false
|
||||
}
|
||||
onMounted(() => loadLogs())
|
||||
</script>
|
||||
|
||||
const canSelect = (row) => row.mergeStatus !== 'MERGED'
|
||||
|
||||
const handleSelectionChange = (selection) => {
|
||||
selectedRows.value = selection.filter(r => r.id !== primaryPatient.value?.id)
|
||||
}
|
||||
|
||||
const setPrimary = (row) => {
|
||||
primaryPatient.value = row
|
||||
ElMessage.info('主患者已设为: ' + row.name)
|
||||
}
|
||||
|
||||
const handleMerge = () => {
|
||||
if (!primaryPatient.value) { ElMessage.warning('请先选择主患者'); return }
|
||||
if (selectedRows.value.length === 0) { ElMessage.warning('请勾选要合并的患者'); return }
|
||||
confirmVisible.value = true
|
||||
}
|
||||
|
||||
const doMerge = async () => {
|
||||
try {
|
||||
await mergePersons(primaryPatient.value.id, selectedRows.value.map(r => r.id))
|
||||
ElMessage.success('合并成功')
|
||||
confirmVisible.value = false
|
||||
primaryPatient.value = null
|
||||
selectedRows.value = []
|
||||
loadPatients()
|
||||
loadLogs()
|
||||
} catch (e) {
|
||||
ElMessage.error('合并失败')
|
||||
}
|
||||
}
|
||||
|
||||
const getPatientName = (id) => {
|
||||
const p = patientList.value.find(x => x.id === id)
|
||||
return p ? p.name : id
|
||||
}
|
||||
|
||||
onMounted(() => { loadPatients(); loadLogs() })
|
||||
</script>
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20" class="mb8">
|
||||
<el-col :span="6"><el-card shadow="hover"><el-statistic title="总患者数" :value="stats.totalPatients || 0" /></el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="hover"><el-statistic title="已合并" :value="stats.mergedPatients || 0" /></el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="hover"><el-statistic title="总患者数" :value="stats.totalPersons || 0" /></el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="hover"><el-statistic title="已合并" :value="stats.mergedPersons || 0" /></el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="hover"><el-statistic title="待合并" :value="stats.pendingMerges || 0" /></el-card></el-col>
|
||||
<el-col :span="6"><el-card shadow="hover"><el-statistic title="重复率" :value="stats.duplicateRate || 0" suffix="%" /></el-card></el-col>
|
||||
</el-row>
|
||||
@@ -18,25 +18,66 @@
|
||||
<el-form-item label="身份证号"><el-input v-model="searchForm.idCardNo" placeholder="身份证号" clearable /></el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="searchForm={};patientData=null">重置</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-descriptions v-if="patientData" :column="2" border>
|
||||
<el-descriptions-item label="全局ID">{{ patientData.globalId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="姓名">{{ patientData.patientName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="姓名">{{ patientData.name }}</el-descriptions-item>
|
||||
<el-descriptions-item label="性别">{{ patientData.gender === 'M' ? '男' : '女' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出生日期">{{ patientData.birthDate }}</el-descriptions-item>
|
||||
<el-descriptions-item label="身份证号">{{ patientData.idCardNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="手机号">{{ patientData.phone }}</el-descriptions-item>
|
||||
<el-descriptions-item label="地址" :span="2">{{ patientData.address }}</el-descriptions-item>
|
||||
<el-descriptions-item label="来源系统">{{ patientData.sourceSystem }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag :type="patientData.mergeStatus === 'ACTIVE' ? 'success' : 'warning'" size="small">
|
||||
{{ patientData.mergeStatus === 'ACTIVE' ? '正常' : '已合并' }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-empty v-else description="请输入查询条件" />
|
||||
</el-card>
|
||||
|
||||
<!-- 关联院内患者记录 -->
|
||||
<el-card v-if="linkedPatients.length > 0" style="margin-top:16px">
|
||||
<template #header>
|
||||
<span>关联院内患者记录 ({{ linkedPatients.length }})</span>
|
||||
</template>
|
||||
<el-table :data="linkedPatients" border stripe>
|
||||
<el-table-column prop="id" label="院内ID" width="100" />
|
||||
<el-table-column prop="busNo" label="病历号" width="140" />
|
||||
<el-table-column prop="name" label="姓名" width="100" />
|
||||
<el-table-column prop="genderEnum" label="性别" width="60">
|
||||
<template #default="{row}">{{ row.genderEnum === 1 ? '男' : '女' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="birthDate" label="出生日期" width="120">
|
||||
<template #default="{row}">{{ row.birthDate ? row.birthDate.substring(0,10) : '' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="phone" label="电话" width="130" />
|
||||
<el-table-column prop="idCard" label="身份证号" width="180" />
|
||||
<el-table-column prop="address" label="地址" min-width="150" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- ID映射列表 -->
|
||||
<el-card v-if="mappings.length > 0" style="margin-top:16px">
|
||||
<template #header>
|
||||
<span>ID映射关系</span>
|
||||
</template>
|
||||
<el-table :data="mappings" border stripe>
|
||||
<el-table-column prop="globalId" label="全局ID" width="180" />
|
||||
<el-table-column prop="localPatientId" label="院内患者ID" width="120" />
|
||||
<el-table-column prop="sourceSystem" label="来源系统" width="100" />
|
||||
<el-table-column prop="idType" label="标识类型" width="100" />
|
||||
<el-table-column prop="idValue" label="标识值" min-width="150" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog title="注册患者" v-model="dialogVisible" width="600px">
|
||||
<el-form :model="formData" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="姓名"><el-input v-model="formData.patientName" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="姓名"><el-input v-model="formData.name" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="性别">
|
||||
<el-select v-model="formData.gender"><el-option v-for="d in sys_user_sex" :key="d.value" :label="d.label" :value="d.value" /></el-select>
|
||||
</el-form-item></el-col>
|
||||
@@ -57,23 +98,58 @@
|
||||
<script setup>
|
||||
import { useDict } from '@/utils/dict'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { registerPerson, findByGlobalId, findByIdCard, getStatistics } from '../api'
|
||||
import {
|
||||
registerPerson, findByGlobalId, findByIdCard, getStatistics,
|
||||
findLinkedPatientsByGlobalId, findLinkedPatientsByIdCard, getMappings
|
||||
} from '../api'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const { sys_user_sex } = useDict('sys_user_sex')
|
||||
const stats = ref({})
|
||||
const searchForm = reactive({ globalId: '', idCardNo: '' })
|
||||
const patientData = ref(null)
|
||||
const linkedPatients = ref([])
|
||||
const mappings = ref([])
|
||||
const dialogVisible = ref(false)
|
||||
const formData = ref({})
|
||||
|
||||
const loadStats = async () => { const res = await getStatistics(); stats.value = res.data || {} }
|
||||
|
||||
const handleSearch = async () => {
|
||||
if (searchForm.globalId) { const res = await findByGlobalId(searchForm.globalId); patientData.value = res.data }
|
||||
else if (searchForm.idCardNo) { const res = await findByIdCard(searchForm.idCardNo); patientData.value = res.data }
|
||||
else { ElMessage.warning('请输入查询条件') }
|
||||
linkedPatients.value = []
|
||||
mappings.value = []
|
||||
if (searchForm.globalId) {
|
||||
const res = await findByGlobalId(searchForm.globalId)
|
||||
patientData.value = res.data
|
||||
if (res.data) {
|
||||
const lp = await findLinkedPatientsByGlobalId(searchForm.globalId)
|
||||
linkedPatients.value = lp.data || []
|
||||
const mp = await getMappings(searchForm.globalId)
|
||||
mappings.value = mp.data || []
|
||||
}
|
||||
} else if (searchForm.idCardNo) {
|
||||
const res = await findByIdCard(searchForm.idCardNo)
|
||||
patientData.value = res.data
|
||||
if (res.data) {
|
||||
const lp = await findLinkedPatientsByIdCard(searchForm.idCardNo)
|
||||
linkedPatients.value = lp.data || []
|
||||
const mp = await getMappings(res.data.globalId)
|
||||
mappings.value = mp.data || []
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning('请输入查询条件')
|
||||
}
|
||||
}
|
||||
|
||||
const handleReset = () => {
|
||||
searchForm.globalId = ''
|
||||
searchForm.idCardNo = ''
|
||||
patientData.value = null
|
||||
linkedPatients.value = []
|
||||
mappings.value = []
|
||||
}
|
||||
|
||||
const handleRegister = () => { formData.value = {}; dialogVisible.value = true }
|
||||
const submitForm = async () => { await registerPerson(formData.value); ElMessage.success('注册成功'); dialogVisible.value = false; loadStats() }
|
||||
onMounted(() => loadStats())
|
||||
</script>
|
||||
</script>
|
||||
Reference in New Issue
Block a user