103 增加医生个人报卡管理界面(需求)
This commit is contained in:
@@ -12,6 +12,8 @@ import com.core.common.utils.SecurityUtils;
|
|||||||
import com.core.common.core.domain.model.LoginUser;
|
import com.core.common.core.domain.model.LoginUser;
|
||||||
import com.openhis.infectious.domain.InfectiousAudit;
|
import com.openhis.infectious.domain.InfectiousAudit;
|
||||||
import com.openhis.infectious.domain.InfectiousCard;
|
import com.openhis.infectious.domain.InfectiousCard;
|
||||||
|
import com.openhis.administration.domain.Practitioner;
|
||||||
|
import com.openhis.administration.service.IPractitionerService;
|
||||||
import com.openhis.web.cardmanagement.appservice.ICardManageAppService;
|
import com.openhis.web.cardmanagement.appservice.ICardManageAppService;
|
||||||
import com.openhis.web.cardmanagement.dto.*;
|
import com.openhis.web.cardmanagement.dto.*;
|
||||||
import com.openhis.web.cardmanagement.mapper.InfectiousAuditMapper;
|
import com.openhis.web.cardmanagement.mapper.InfectiousAuditMapper;
|
||||||
@@ -52,6 +54,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
|
|
||||||
private final InfectiousCardMapper infectiousCardMapper;
|
private final InfectiousCardMapper infectiousCardMapper;
|
||||||
private final InfectiousAuditMapper infectiousAuditMapper;
|
private final InfectiousAuditMapper infectiousAuditMapper;
|
||||||
|
private final IPractitionerService iPractitionerService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardStatisticsDto getStatistics() {
|
public CardStatisticsDto getStatistics() {
|
||||||
@@ -74,7 +77,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 状态
|
// 状态
|
||||||
if (StringUtils.hasText(queryParams.getStatus())) {
|
if (queryParams.getStatus() != null) {
|
||||||
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +130,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
if (card == null) {
|
if (card == null) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
List<InfectiousAudit> records = infectiousAuditMapper.selectByCardId(card.getId());
|
List<InfectiousAudit> records = infectiousAuditMapper.selectByCardId(card.getCardNo());
|
||||||
return records.stream().map(this::convertAuditToDto).collect(Collectors.toList());
|
return records.stream().map(this::convertAuditToDto).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,16 +148,16 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
for (String cardNo : batchAuditDto.getCardNos()) {
|
for (String cardNo : batchAuditDto.getCardNos()) {
|
||||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||||
if (card == null) continue;
|
if (card == null) continue;
|
||||||
if ("2".equals(card.getStatus()) || "3".equals(card.getStatus())) continue;
|
if (Integer.valueOf(2).equals(card.getStatus()) || Integer.valueOf(3).equals(card.getStatus())) continue;
|
||||||
|
|
||||||
// 更新状态为已审核
|
// 更新状态为已审核
|
||||||
String oldStatus = card.getStatus();
|
Integer oldStatus = card.getStatus();
|
||||||
card.setStatus("2");
|
card.setStatus(2);
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
|
|
||||||
// 创建审核记录
|
// 创建审核记录
|
||||||
createAuditRecord(card.getId(), oldStatus, "2", "1", batchAuditDto.getAuditOpinion(),
|
createAuditRecord(card.getCardNo(), oldStatus, 2, 1, batchAuditDto.getAuditOpinion(),
|
||||||
null, auditorId, auditorName, true, batchAuditDto.getCardNos().size());
|
null, auditorId, auditorName, true, batchAuditDto.getCardNos().size());
|
||||||
successCount++;
|
successCount++;
|
||||||
}
|
}
|
||||||
@@ -176,17 +179,17 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
for (String cardNo : batchReturnDto.getCardNos()) {
|
for (String cardNo : batchReturnDto.getCardNos()) {
|
||||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||||
if (card == null) continue;
|
if (card == null) continue;
|
||||||
if ("2".equals(card.getStatus()) || "3".equals(card.getStatus())) continue;
|
if (Integer.valueOf(2).equals(card.getStatus()) || Integer.valueOf(3).equals(card.getStatus())) continue;
|
||||||
|
|
||||||
// 更新状态为退回 (审核失败)
|
// 更新状态为退回 (审核失败)
|
||||||
String oldStatus = card.getStatus();
|
Integer oldStatus = card.getStatus();
|
||||||
card.setStatus("5");
|
card.setStatus(5);
|
||||||
card.setReturnReason(batchReturnDto.getReturnReason());
|
card.setReturnReason(batchReturnDto.getReturnReason());
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
|
|
||||||
// 创建审核记录
|
// 创建审核记录
|
||||||
createAuditRecord(card.getId(), oldStatus, "5", "3", null,
|
createAuditRecord(card.getCardNo(), oldStatus, 5, 3, null,
|
||||||
batchReturnDto.getReturnReason(), auditorId, auditorName, true, batchReturnDto.getCardNos().size());
|
batchReturnDto.getReturnReason(), auditorId, auditorName, true, batchReturnDto.getCardNos().size());
|
||||||
successCount++;
|
successCount++;
|
||||||
}
|
}
|
||||||
@@ -206,13 +209,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
String auditorName = SecurityUtils.getUsername();
|
String auditorName = SecurityUtils.getUsername();
|
||||||
|
|
||||||
// 更新状态
|
// 更新状态
|
||||||
String oldStatus = card.getStatus();
|
Integer oldStatus = card.getStatus();
|
||||||
card.setStatus("2");
|
card.setStatus(2);
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
|
|
||||||
// 创建审核记录
|
// 创建审核记录
|
||||||
createAuditRecord(card.getId(), oldStatus, "2", "2", auditDto.getAuditOpinion(),
|
createAuditRecord(card.getCardNo(), oldStatus, 2, 2, auditDto.getAuditOpinion(),
|
||||||
null, auditorId, auditorName, false, 1);
|
null, auditorId, auditorName, false, 1);
|
||||||
|
|
||||||
return R.ok("审核通过");
|
return R.ok("审核通过");
|
||||||
@@ -230,14 +233,14 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
String auditorName = SecurityUtils.getUsername();
|
String auditorName = SecurityUtils.getUsername();
|
||||||
|
|
||||||
// 更新状态
|
// 更新状态
|
||||||
String oldStatus = card.getStatus();
|
Integer oldStatus = card.getStatus();
|
||||||
card.setStatus("5");
|
card.setStatus(5);
|
||||||
card.setReturnReason(returnDto.getReturnReason());
|
card.setReturnReason(returnDto.getReturnReason());
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
|
|
||||||
// 创建审核记录
|
// 创建审核记录
|
||||||
createAuditRecord(card.getId(), oldStatus, "5", "4", null,
|
createAuditRecord(card.getCardNo(), oldStatus, 5, 4, null,
|
||||||
returnDto.getReturnReason(), auditorId, auditorName, false, 1);
|
returnDto.getReturnReason(), auditorId, auditorName, false, 1);
|
||||||
|
|
||||||
return R.ok("已退回");
|
return R.ok("已退回");
|
||||||
@@ -251,7 +254,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
if (queryParams.getRegistrationSource() != null) {
|
if (queryParams.getRegistrationSource() != null) {
|
||||||
wrapper.eq(InfectiousCard::getRegistrationSource, queryParams.getRegistrationSource());
|
wrapper.eq(InfectiousCard::getRegistrationSource, queryParams.getRegistrationSource());
|
||||||
}
|
}
|
||||||
if (StringUtils.hasText(queryParams.getStatus())) {
|
if (queryParams.getStatus() != null) {
|
||||||
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
||||||
}
|
}
|
||||||
if (StringUtils.hasText(queryParams.getPatientName())) {
|
if (StringUtils.hasText(queryParams.getPatientName())) {
|
||||||
@@ -292,7 +295,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
row.createCell(1).setCellValue(card.getPatName());
|
row.createCell(1).setCellValue(card.getPatName());
|
||||||
row.createCell(2).setCellValue("1".equals(card.getSex()) ? "男" : "2".equals(card.getSex()) ? "女" : "未知");
|
row.createCell(2).setCellValue("1".equals(card.getSex()) ? "男" : "2".equals(card.getSex()) ? "女" : "未知");
|
||||||
row.createCell(3).setCellValue(card.getAge() != null ? card.getAge() + "岁" : "");
|
row.createCell(3).setCellValue(card.getAge() != null ? card.getAge() + "岁" : "");
|
||||||
row.createCell(4).setCellValue(card.getDiseaseName());
|
row.createCell(4).setCellValue(card.getDiseaseCode());
|
||||||
row.createCell(5).setCellValue(card.getDeptName());
|
row.createCell(5).setCellValue(card.getDeptName());
|
||||||
row.createCell(6).setCellValue(card.getCreateTime() != null ? dateFormat.format(card.getCreateTime()) : "");
|
row.createCell(6).setCellValue(card.getCreateTime() != null ? dateFormat.format(card.getCreateTime()) : "");
|
||||||
row.createCell(7).setCellValue(getStatusText(card.getStatus()));
|
row.createCell(7).setCellValue(getStatusText(card.getStatus()));
|
||||||
@@ -316,7 +319,19 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DoctorCardStatisticsDto getDoctorCardStatistics() {
|
public DoctorCardStatisticsDto getDoctorCardStatistics() {
|
||||||
Long doctorId = SecurityUtils.getUserId();
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
|
||||||
|
// 通过 sys_user 表的 user_id 查询医生表 (adm_practitioner) 获取医生 ID
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null) {
|
||||||
|
DoctorCardStatisticsDto dto = new DoctorCardStatisticsDto();
|
||||||
|
dto.setTotalCount(0);
|
||||||
|
dto.setPendingFailedCount(0);
|
||||||
|
dto.setReportedCount(0);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long doctorId = practitioner.getId();
|
||||||
|
|
||||||
DoctorCardStatisticsDto dto = new DoctorCardStatisticsDto();
|
DoctorCardStatisticsDto dto = new DoctorCardStatisticsDto();
|
||||||
Integer totalCount = infectiousCardMapper.countByDoctorId(doctorId);
|
Integer totalCount = infectiousCardMapper.countByDoctorId(doctorId);
|
||||||
@@ -331,7 +346,18 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<?> getDoctorCardPage(DoctorCardQueryDto queryParams) {
|
public R<?> getDoctorCardPage(DoctorCardQueryDto queryParams) {
|
||||||
Long doctorId = SecurityUtils.getUserId();
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
|
||||||
|
// 通过 sys_user 表的 user_id 查询医生表 (adm_practitioner) 获取医生 ID
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null) {
|
||||||
|
Map<String, Object> emptyResult = new HashMap<>();
|
||||||
|
emptyResult.put("list", new ArrayList<>());
|
||||||
|
emptyResult.put("total", 0L);
|
||||||
|
return R.ok(emptyResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long doctorId = practitioner.getId();
|
||||||
|
|
||||||
Page<InfectiousCard> page = new Page<>(queryParams.getPageNo(), queryParams.getPageSize());
|
Page<InfectiousCard> page = new Page<>(queryParams.getPageNo(), queryParams.getPageSize());
|
||||||
LambdaQueryWrapper<InfectiousCard> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<InfectiousCard> wrapper = new LambdaQueryWrapper<>();
|
||||||
@@ -340,7 +366,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
wrapper.eq(InfectiousCard::getDoctorId, doctorId);
|
wrapper.eq(InfectiousCard::getDoctorId, doctorId);
|
||||||
|
|
||||||
// 状态筛选
|
// 状态筛选
|
||||||
if (StringUtils.hasText(queryParams.getStatus())) {
|
if (queryParams.getStatus() != null) {
|
||||||
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,13 +380,24 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
wrapper.le(InfectiousCard::getCreateTime, endDateTime);
|
wrapper.le(InfectiousCard::getCreateTime, endDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关键词搜索(患者姓名或报卡名称)
|
// 关键词搜索(患者姓名、疾病编码、报卡名称)
|
||||||
if (StringUtils.hasText(queryParams.getKeyword())) {
|
if (StringUtils.hasText(queryParams.getKeyword())) {
|
||||||
wrapper.and(w -> w
|
String kw = queryParams.getKeyword();
|
||||||
.like(InfectiousCard::getPatName, queryParams.getKeyword())
|
// 将关键词匹配报卡名称,找出对应的 cardNameCode 列表
|
||||||
.or()
|
List<Integer> matchedCodes = getMatchedCardNameCodes(kw);
|
||||||
.like(InfectiousCard::getDiseaseName, queryParams.getKeyword())
|
// cardNameCode为null的记录默认也属于"中华人民共和国传染病报告卡",匹配到code=1时需包含Null记录
|
||||||
);
|
boolean includeNull = matchedCodes.contains(1);
|
||||||
|
wrapper.and(w -> {
|
||||||
|
w.like(InfectiousCard::getPatName, kw)
|
||||||
|
.or()
|
||||||
|
.like(InfectiousCard::getDiseaseCode, kw);
|
||||||
|
if (!matchedCodes.isEmpty()) {
|
||||||
|
w.or().in(InfectiousCard::getCardNameCode, matchedCodes);
|
||||||
|
}
|
||||||
|
if (includeNull) {
|
||||||
|
w.or().isNull(InfectiousCard::getCardNameCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按创建时间倒序
|
// 按创建时间倒序
|
||||||
@@ -388,17 +425,19 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证权限:只能提交自己的报卡
|
// 验证权限:只能提交自己的报卡
|
||||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null || !practitioner.getId().equals(card.getDoctorId())) {
|
||||||
return R.fail("无权操作此报卡");
|
return R.fail("无权操作此报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证状态:只有暂存状态可以提交
|
// 狋证状态:只有暂存状态可以提交
|
||||||
if (!"0".equals(card.getStatus())) {
|
if (!Integer.valueOf(0).equals(card.getStatus())) {
|
||||||
return R.fail("只能提交暂存状态的报卡");
|
return R.fail("只能提交暂存状态的报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新状态为已提交
|
// 更新状态为已提交
|
||||||
card.setStatus("1");
|
card.setStatus(1);
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
|
|
||||||
@@ -414,17 +453,19 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证权限:只能撤回自己的报卡
|
// 验证权限:只能撤回自己的报卡
|
||||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null || !practitioner.getId().equals(card.getDoctorId())) {
|
||||||
return R.fail("无权操作此报卡");
|
return R.fail("无权操作此报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证状态:只有已提交状态可以撤回
|
// 狋证状态:只有已提交状态可以撤回
|
||||||
if (!"1".equals(card.getStatus())) {
|
if (!Integer.valueOf(1).equals(card.getStatus())) {
|
||||||
return R.fail("只能撤回已提交状态的报卡");
|
return R.fail("只能撤回已提交状态的报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新状态为暂存
|
// 更新状态为暂存
|
||||||
card.setStatus("0");
|
card.setStatus(0);
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
|
|
||||||
@@ -440,17 +481,19 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证权限:只能删除自己的报卡
|
// 验证权限:只能删除自己的报卡
|
||||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null || !practitioner.getId().equals(card.getDoctorId())) {
|
||||||
return R.fail("无权操作此报卡");
|
return R.fail("无权操作此报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证状态:只有暂存状态可以删除
|
// 狋证状态:只有暂存状态可以删除
|
||||||
if (!"0".equals(card.getStatus())) {
|
if (!Integer.valueOf(0).equals(card.getStatus())) {
|
||||||
return R.fail("只能删除暂存状态的报卡");
|
return R.fail("只能删除暂存状态的报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新状态为作废
|
// 更新状态为作废
|
||||||
card.setStatus("6");
|
card.setStatus(6);
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
|
|
||||||
@@ -464,7 +507,12 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
return R.fail("请选择要提交的报卡");
|
return R.fail("请选择要提交的报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
Long doctorId = SecurityUtils.getUserId();
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null) {
|
||||||
|
return R.fail("当前用户未关联医生信息");
|
||||||
|
}
|
||||||
|
Long doctorId = practitioner.getId();
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
|
|
||||||
for (String cardNo : cardNos) {
|
for (String cardNo : cardNos) {
|
||||||
@@ -472,13 +520,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
if (card == null) continue;
|
if (card == null) continue;
|
||||||
|
|
||||||
// 验证权限:只能提交自己的报卡
|
// 验证权限:只能提交自己的报卡
|
||||||
if (!card.getDoctorId().equals(doctorId)) continue;
|
if (!doctorId.equals(card.getDoctorId())) continue;
|
||||||
|
|
||||||
// 验证状态:只有暂存状态可以提交
|
// 狋证状态:只有暂存状态可以提交
|
||||||
if (!"0".equals(card.getStatus())) continue;
|
if (!Integer.valueOf(0).equals(card.getStatus())) continue;
|
||||||
|
|
||||||
// 更新状态为已提交
|
// 更新状态为已提交
|
||||||
card.setStatus("1");
|
card.setStatus(1);
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
successCount++;
|
successCount++;
|
||||||
@@ -498,7 +546,12 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
return R.fail("请选择要删除的报卡");
|
return R.fail("请选择要删除的报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
Long doctorId = SecurityUtils.getUserId();
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null) {
|
||||||
|
return R.fail("当前用户未关联医生信息");
|
||||||
|
}
|
||||||
|
Long doctorId = practitioner.getId();
|
||||||
int successCount = 0;
|
int successCount = 0;
|
||||||
|
|
||||||
for (String cardNo : cardNos) {
|
for (String cardNo : cardNos) {
|
||||||
@@ -506,13 +559,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
if (card == null) continue;
|
if (card == null) continue;
|
||||||
|
|
||||||
// 验证权限:只能删除自己的报卡
|
// 验证权限:只能删除自己的报卡
|
||||||
if (!card.getDoctorId().equals(doctorId)) continue;
|
if (!doctorId.equals(card.getDoctorId())) continue;
|
||||||
|
|
||||||
// 验证状态:只有暂存状态可以删除
|
// 狋证状态:只有暂存状态可以删除
|
||||||
if (!"0".equals(card.getStatus())) continue;
|
if (!Integer.valueOf(0).equals(card.getStatus())) continue;
|
||||||
|
|
||||||
// 更新状态为作废
|
// 更新状态为作废
|
||||||
card.setStatus("6");
|
card.setStatus(6);
|
||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
infectiousCardMapper.updateById(card);
|
infectiousCardMapper.updateById(card);
|
||||||
successCount++;
|
successCount++;
|
||||||
@@ -531,6 +584,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||||
Long currentUserId = loginUser.getUserId();
|
Long currentUserId = loginUser.getUserId();
|
||||||
|
|
||||||
|
// 通过 sys_user 表的 user_id 查询医生表 (adm_practitioner) 获取医生 ID
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(currentUserId);
|
||||||
|
if (practitioner == null) {
|
||||||
|
return R.fail("当前用户未关联医生信息");
|
||||||
|
}
|
||||||
|
Long doctorId = practitioner.getId();
|
||||||
|
|
||||||
// 查询报卡
|
// 查询报卡
|
||||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(updateDto.getCardNo());
|
InfectiousCard card = infectiousCardMapper.selectByCardNo(updateDto.getCardNo());
|
||||||
if (card == null) {
|
if (card == null) {
|
||||||
@@ -538,12 +598,12 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证是否当前医生的报卡 - 根据 doctorId 字段验证
|
// 验证是否当前医生的报卡 - 根据 doctorId 字段验证
|
||||||
if (!currentUserId.equals(card.getDoctorId())) {
|
if (!doctorId.equals(card.getDoctorId())) {
|
||||||
return R.fail("只能修改自己的报卡");
|
return R.fail("只能修改自己的报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证状态是否允许修改(只能修改暂存状态的报卡)
|
// 狋证状态是否允许修改(只能修改暂存状态的报卡)
|
||||||
if (!"0".equals(card.getStatus())) {
|
if (!Integer.valueOf(0).equals(card.getStatus())) {
|
||||||
return R.fail("只能修改暂存状态的报卡");
|
return R.fail("只能修改暂存状态的报卡");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,15 +619,6 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
card.setUpdateTime(new Date());
|
card.setUpdateTime(new Date());
|
||||||
card.setUpdateBy(loginUser.getUsername()); // 使用username作为更新者
|
card.setUpdateBy(loginUser.getUsername()); // 使用username作为更新者
|
||||||
|
|
||||||
card.setUpdateTime(new Date());
|
|
||||||
card.setUpdateBy(loginUser.getUsername()); // 使用 username 作为更新者
|
|
||||||
|
|
||||||
card.setUpdateTime(new Date());
|
|
||||||
card.setUpdateBy(loginUser.getUsername()); // 使用 username 作为更新者
|
|
||||||
|
|
||||||
card.setUpdateTime(new Date());
|
|
||||||
card.setUpdateBy(loginUser.getUsername()); // 使用 username 作为更新者
|
|
||||||
|
|
||||||
int rows = infectiousCardMapper.updateById(card);
|
int rows = infectiousCardMapper.updateById(card);
|
||||||
if (rows > 0) {
|
if (rows > 0) {
|
||||||
return R.ok("更新成功");
|
return R.ok("更新成功");
|
||||||
@@ -583,12 +634,14 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 验证权限:只能导出自己的报卡
|
// 验证权限:只能导出自己的报卡
|
||||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
Long userId = SecurityUtils.getUserId();
|
||||||
|
Practitioner practitioner = iPractitionerService.getPractitionerByUserId(userId);
|
||||||
|
if (practitioner == null || !practitioner.getId().equals(card.getDoctorId())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证状态:只有已上报状态可以导出
|
// 狋证状态:只有已上报状态可以导出
|
||||||
if (!"3".equals(card.getStatus())) {
|
if (!Integer.valueOf(3).equals(card.getStatus())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,6 +665,8 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
private DoctorCardListDto convertToDoctorCardListDto(InfectiousCard card) {
|
private DoctorCardListDto convertToDoctorCardListDto(InfectiousCard card) {
|
||||||
DoctorCardListDto dto = new DoctorCardListDto();
|
DoctorCardListDto dto = new DoctorCardListDto();
|
||||||
BeanUtils.copyProperties(card, dto);
|
BeanUtils.copyProperties(card, dto);
|
||||||
|
// 由于数据库中没有 disease_name 字段,使用 disease_code 作为疾病名称展示
|
||||||
|
dto.setDiseaseName(card.getDiseaseCode());
|
||||||
dto.setCardName(getCardName(card.getCardNameCode()));
|
dto.setCardName(getCardName(card.getCardNameCode()));
|
||||||
dto.setSubmitTime(card.getCreateTime() != null ?
|
dto.setSubmitTime(card.getCreateTime() != null ?
|
||||||
new SimpleDateFormat("yyyy-MM-dd HH:mm").format(card.getCreateTime()) : null);
|
new SimpleDateFormat("yyyy-MM-dd HH:mm").format(card.getCreateTime()) : null);
|
||||||
@@ -632,13 +687,35 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据关键词匹配报卡名称,返回匹配的 cardNameCode 列表
|
||||||
|
*/
|
||||||
|
private List<Integer> getMatchedCardNameCodes(String keyword) {
|
||||||
|
// 报卡名称映射表 code -> name
|
||||||
|
java.util.Map<Integer, String> cardNameMap = new java.util.LinkedHashMap<>();
|
||||||
|
cardNameMap.put(1, "中华人民共和国传染病报告卡");
|
||||||
|
cardNameMap.put(2, "甲类传染病报告卡");
|
||||||
|
cardNameMap.put(3, "乙类传染病报告卡");
|
||||||
|
cardNameMap.put(4, "丙类传染病报告卡");
|
||||||
|
|
||||||
|
List<Integer> matchedCodes = new ArrayList<>();
|
||||||
|
for (java.util.Map.Entry<Integer, String> entry : cardNameMap.entrySet()) {
|
||||||
|
if (entry.getValue().contains(keyword)) {
|
||||||
|
matchedCodes.add(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cardNameCode 为 null 的数据默认也是「中华人民共和国传染病报告卡」
|
||||||
|
// 如果关键词匹配 code=1,则同时要包含 null 的记录
|
||||||
|
return matchedCodes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换审核记录为 DTO
|
* 转换审核记录为 DTO
|
||||||
*/
|
*/
|
||||||
private AuditRecordDto convertAuditToDto(InfectiousAudit audit) {
|
private AuditRecordDto convertAuditToDto(InfectiousAudit audit) {
|
||||||
AuditRecordDto dto = new AuditRecordDto();
|
AuditRecordDto dto = new AuditRecordDto();
|
||||||
BeanUtils.copyProperties(audit, dto);
|
BeanUtils.copyProperties(audit, dto);
|
||||||
dto.setCardId(audit.getCardId() != null ? audit.getCardId().toString() : null);
|
dto.setCardId(audit.getCardId());
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,6 +725,8 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
private InfectiousCardDto convertToDto(InfectiousCard card) {
|
private InfectiousCardDto convertToDto(InfectiousCard card) {
|
||||||
InfectiousCardDto dto = new InfectiousCardDto();
|
InfectiousCardDto dto = new InfectiousCardDto();
|
||||||
BeanUtils.copyProperties(card, dto);
|
BeanUtils.copyProperties(card, dto);
|
||||||
|
// 由于数据库中没有 disease_name 字段,使用 disease_code 作为疾病名称展示
|
||||||
|
dto.setDiseaseName(card.getDiseaseCode());
|
||||||
dto.setStatusText(getStatusText(card.getStatus()));
|
dto.setStatusText(getStatusText(card.getStatus()));
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
@@ -655,15 +734,15 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
/**
|
/**
|
||||||
* 创建审核记录
|
* 创建审核记录
|
||||||
*/
|
*/
|
||||||
private void createAuditRecord(Long cardId, String statusFrom, String statusTo, String auditType,
|
private void createAuditRecord(String cardId, Integer statusFrom, Integer statusTo, Integer auditType,
|
||||||
String auditOpinion, String returnReason, String auditorId, String auditorName,
|
String auditOpinion, String returnReason, String auditorId, String auditorName,
|
||||||
Boolean isBatch, Integer batchSize) {
|
Boolean isBatch, Integer batchSize) {
|
||||||
InfectiousAudit audit = new InfectiousAudit();
|
InfectiousAudit audit = new InfectiousAudit();
|
||||||
audit.setCardId(cardId);
|
audit.setCardId(cardId);
|
||||||
audit.setAuditSeq(infectiousAuditMapper.getNextAuditSeq(cardId));
|
audit.setAuditSeq(infectiousAuditMapper.getNextAuditSeq(cardId));
|
||||||
audit.setAuditType(auditType);
|
audit.setAuditType(String.valueOf(auditType));
|
||||||
audit.setAuditStatusFrom(statusFrom);
|
audit.setAuditStatusFrom(statusFrom != null ? String.valueOf(statusFrom) : null);
|
||||||
audit.setAuditStatusTo(statusTo);
|
audit.setAuditStatusTo(statusTo != null ? String.valueOf(statusTo) : null);
|
||||||
audit.setAuditTime(LocalDateTime.now());
|
audit.setAuditTime(LocalDateTime.now());
|
||||||
audit.setAuditorId(auditorId);
|
audit.setAuditorId(auditorId);
|
||||||
audit.setAuditorName(auditorName);
|
audit.setAuditorName(auditorName);
|
||||||
@@ -677,15 +756,16 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
|||||||
/**
|
/**
|
||||||
* 获取状态文本
|
* 获取状态文本
|
||||||
*/
|
*/
|
||||||
private String getStatusText(String status) {
|
private String getStatusText(Integer status) {
|
||||||
|
if (status == null) return "未知";
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "0": return "暂存";
|
case 0: return "暂存";
|
||||||
case "1": return "已提交";
|
case 1: return "已提交";
|
||||||
case "2": return "审核通过";
|
case 2: return "审核通过";
|
||||||
case "3": return "已上报";
|
case 3: return "已上报";
|
||||||
case "4": return "失败";
|
case 4: return "失败";
|
||||||
case "5": return "审核失败";
|
case 5: return "审核失败";
|
||||||
case "6": return "作废";
|
case 6: return "作废";
|
||||||
default: return "未知";
|
default: return "未知";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ public class CardQueryDto {
|
|||||||
/** 患者姓名 */
|
/** 患者姓名 */
|
||||||
private String patientName;
|
private String patientName;
|
||||||
|
|
||||||
/** 审核状态 */
|
/** 审核状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||||
private String status;
|
private Integer status;
|
||||||
|
|
||||||
/** 科室ID */
|
/** 科室ID */
|
||||||
private Long deptId;
|
private Long deptId;
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 医生个人报卡列表DTO
|
* 医生个人报卡列表DTO
|
||||||
*
|
*
|
||||||
@@ -41,6 +44,51 @@ public class DoctorCardListDto {
|
|||||||
/** 提交时间 */
|
/** 提交时间 */
|
||||||
private String submitTime;
|
private String submitTime;
|
||||||
|
|
||||||
/** 状态 */
|
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||||
private String status;
|
private Integer status;
|
||||||
|
|
||||||
|
/** 疾病名称 */
|
||||||
|
private String diseaseName;
|
||||||
|
|
||||||
|
/** 发病日期 */
|
||||||
|
private LocalDate onsetDate;
|
||||||
|
|
||||||
|
/** 诊断日期 */
|
||||||
|
private LocalDateTime diagDate;
|
||||||
|
|
||||||
|
/** 报告单位 */
|
||||||
|
private String reportOrg;
|
||||||
|
|
||||||
|
/** 报告医生 */
|
||||||
|
private String reportDoc;
|
||||||
|
|
||||||
|
/** 传染病类别 */
|
||||||
|
private String diseaseType;
|
||||||
|
|
||||||
|
/** 性别 (1男/2女/0未知) */
|
||||||
|
private String sex;
|
||||||
|
|
||||||
|
/** 年龄 */
|
||||||
|
private Integer age;
|
||||||
|
|
||||||
|
/** 年龄单位 (1岁/2月/3天) */
|
||||||
|
private String ageUnit;
|
||||||
|
|
||||||
|
/** 现住址省 */
|
||||||
|
private String addressProv;
|
||||||
|
|
||||||
|
/** 现住址市 */
|
||||||
|
private String addressCity;
|
||||||
|
|
||||||
|
/** 现住址县 */
|
||||||
|
private String addressCounty;
|
||||||
|
|
||||||
|
/** 现住址街道 */
|
||||||
|
private String addressTown;
|
||||||
|
|
||||||
|
/** 现住址村/居委 */
|
||||||
|
private String addressVillage;
|
||||||
|
|
||||||
|
/** 现住址门牌号 */
|
||||||
|
private String addressHouse;
|
||||||
}
|
}
|
||||||
@@ -26,8 +26,8 @@ public class DoctorCardQueryDto {
|
|||||||
/** 结束日期 */
|
/** 结束日期 */
|
||||||
private String endDate;
|
private String endDate;
|
||||||
|
|
||||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回) */
|
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||||
private String status;
|
private Integer status;
|
||||||
|
|
||||||
/** 患者姓名或报卡名称 */
|
/** 患者姓名或报卡名称 */
|
||||||
private String keyword;
|
private String keyword;
|
||||||
|
|||||||
@@ -1,18 +1,44 @@
|
|||||||
package com.openhis.web.cardmanagement.dto;
|
package com.openhis.web.cardmanagement.dto;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class DoctorCardUpdateDto {
|
public class DoctorCardUpdateDto {
|
||||||
|
@NotBlank(message = "卡片编号不能为空")
|
||||||
private String cardNo;
|
private String cardNo;
|
||||||
|
|
||||||
private String phone;
|
private String phone;
|
||||||
|
private String contactPhone; // 紧急联系人电话
|
||||||
|
|
||||||
private LocalDate onsetDate;
|
private LocalDate onsetDate;
|
||||||
private LocalDateTime diagDate;
|
private LocalDateTime diagDate;
|
||||||
private String diseaseType; // 修改为diseaseType,对应InfectiousCard中的diseaseType字段
|
|
||||||
private String addressProv;
|
private String diseaseType; // 病例分类(对应InfectiousCard中的diseaseType字段)
|
||||||
private String addressCity;
|
private String diseaseCode; // 疾病编码
|
||||||
private String addressCounty;
|
|
||||||
private String addressHouse;
|
@NotNull(message = "病例类别不能为空")
|
||||||
|
private Integer caseClass; // 病例类别(1疑似病例/2临床诊断病例/3实验室确诊病例/4病原携带者/5阳性检测结果)
|
||||||
|
|
||||||
|
private String occupation; // 职业
|
||||||
|
|
||||||
|
@NotNull(message = "病人属于不能为空")
|
||||||
|
private Integer patientBelong; // 病人属于(1本县区/2本市其他县区/3本省其他地市/4外省/5港澳台/6外籍)
|
||||||
|
|
||||||
|
private String addressProv; // 现住址省
|
||||||
|
private String addressCity; // 现住址市
|
||||||
|
private String addressCounty; // 现住址县
|
||||||
|
private String addressTown; // 现住址街道
|
||||||
|
private String addressVillage; // 现住址村/居委
|
||||||
|
private String addressHouse; // 现住址门牌号
|
||||||
|
|
||||||
|
private String parentName; // 家长姓名
|
||||||
|
private String workplace; // 工作单位
|
||||||
|
private String correctName; // 订正病名
|
||||||
|
private LocalDate deathDate; // 死亡日期
|
||||||
|
private String withdrawReason; // 退卡原因
|
||||||
|
private String otherDisease; // 其他传染病名称
|
||||||
}
|
}
|
||||||
@@ -65,8 +65,8 @@ public class InfectiousCardDto {
|
|||||||
/** 现住址门牌号 */
|
/** 现住址门牌号 */
|
||||||
private String addressHouse;
|
private String addressHouse;
|
||||||
|
|
||||||
/** 病人属于 */
|
/** 病人属于(1本县区/2本市其他县区/3本省其他地市/4外省/5港澳台/6外籍) */
|
||||||
private String patientbelong;
|
private Integer patientBelong;
|
||||||
|
|
||||||
/** 职业 */
|
/** 职业 */
|
||||||
private String occupation;
|
private String occupation;
|
||||||
@@ -110,8 +110,8 @@ public class InfectiousCardDto {
|
|||||||
/** 填卡日期 */
|
/** 填卡日期 */
|
||||||
private LocalDate reportDate;
|
private LocalDate reportDate;
|
||||||
|
|
||||||
/** 状态 */
|
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||||
private String status;
|
private Integer status;
|
||||||
|
|
||||||
/** 状态文本 */
|
/** 状态文本 */
|
||||||
private String statusText;
|
private String statusText;
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ import java.util.List;
|
|||||||
public interface InfectiousAuditMapper extends BaseMapper<InfectiousAudit> {
|
public interface InfectiousAuditMapper extends BaseMapper<InfectiousAudit> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据报卡ID查询审核记录
|
* 根据报卡编号查询审核记录
|
||||||
*/
|
*/
|
||||||
@Select("SELECT * FROM infectious_audit WHERE card_id = #{cardId} ORDER BY audit_time DESC")
|
@Select("SELECT * FROM infectious_audit WHERE card_id = #{cardId} ORDER BY audit_time DESC")
|
||||||
List<InfectiousAudit> selectByCardId(@Param("cardId") Long cardId);
|
List<InfectiousAudit> selectByCardId(@Param("cardId") String cardId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取下一个审核序号
|
* 获取下一个审核序号
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COALESCE(MAX(audit_seq), 0) + 1 FROM infectious_audit WHERE card_id = #{cardId}")
|
@Select("SELECT COALESCE(MAX(audit_seq), 0) + 1 FROM infectious_audit WHERE card_id = #{cardId}")
|
||||||
Integer getNextAuditSeq(@Param("cardId") Long cardId);
|
Integer getNextAuditSeq(@Param("cardId") String cardId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,25 +21,25 @@ public interface InfectiousCardMapper extends BaseMapper<InfectiousCard> {
|
|||||||
/**
|
/**
|
||||||
* 统计今日待审核数量
|
* 统计今日待审核数量
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE(create_time) = CURRENT_DATE AND status = '1'")
|
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE(create_time) = CURRENT_DATE AND status = 1")
|
||||||
Integer countTodayPending();
|
Integer countTodayPending();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计本月审核失败数量
|
* 统计本月审核失败数量
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE_TRUNC('month', create_time) = DATE_TRUNC('month', CURRENT_DATE) AND status = '5'")
|
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE_TRUNC('month', create_time) = DATE_TRUNC('month', CURRENT_DATE) AND status = 5")
|
||||||
Integer countMonthFailed();
|
Integer countMonthFailed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计本月审核成功数量
|
* 统计本月审核成功数量
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE_TRUNC('month', create_time) = DATE_TRUNC('month', CURRENT_DATE) AND status = '2'")
|
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE_TRUNC('month', create_time) = DATE_TRUNC('month', CURRENT_DATE) AND status = 2")
|
||||||
Integer countMonthSuccess();
|
Integer countMonthSuccess();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计本月已上报数量
|
* 统计本月已上报数量
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE_TRUNC('month', create_time) = DATE_TRUNC('month', CURRENT_DATE) AND status = '3'")
|
@Select("SELECT COUNT(*) FROM infectious_card WHERE DATE_TRUNC('month', create_time) = DATE_TRUNC('month', CURRENT_DATE) AND status = 3")
|
||||||
Integer countMonthReported();
|
Integer countMonthReported();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,14 +55,14 @@ public interface InfectiousCardMapper extends BaseMapper<InfectiousCard> {
|
|||||||
Integer countByDoctorId(@Param("doctorId") Long doctorId);
|
Integer countByDoctorId(@Param("doctorId") Long doctorId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计医生待处理失败数(状态为0暂存或4失败)
|
* 统计医生待提交数(状态为0暂存待提交)
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE doctor_id = #{doctorId} AND status IN ('0', '4')")
|
@Select("SELECT COUNT(*) FROM infectious_card WHERE doctor_id = #{doctorId} AND status = 0")
|
||||||
Integer countPendingFailedByDoctorId(@Param("doctorId") Long doctorId);
|
Integer countPendingFailedByDoctorId(@Param("doctorId") Long doctorId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计医生已成功上报数(状态为3已上报)
|
* 统计医生已成功上报数(状态为3已上报)
|
||||||
*/
|
*/
|
||||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE doctor_id = #{doctorId} AND status = '3'")
|
@Select("SELECT COUNT(*) FROM infectious_card WHERE doctor_id = #{doctorId} AND status = 3")
|
||||||
Integer countReportedByDoctorId(@Param("doctorId") Long doctorId);
|
Integer countReportedByDoctorId(@Param("doctorId") Long doctorId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,14 +127,11 @@ public class InfectiousCardDto {
|
|||||||
/** 审核意见 */
|
/** 审核意见 */
|
||||||
private String auditOpinion;
|
private String auditOpinion;
|
||||||
|
|
||||||
/** 退回原因 */
|
/** 退卡原因 */
|
||||||
private String returnReason;
|
private String returnReason;
|
||||||
|
|
||||||
/** 订正病名 */
|
/** 订正病名 */
|
||||||
private String correctName;
|
private String revisedDiseaseName;
|
||||||
|
|
||||||
/** 退卡原因 */
|
|
||||||
private String withdrawReason;
|
|
||||||
|
|
||||||
/** 其他传染病 */
|
/** 其他传染病 */
|
||||||
private String otherDisease;
|
private String otherDisease;
|
||||||
|
|||||||
@@ -29,9 +29,8 @@ public class InfectiousAudit extends HisBaseEntity {
|
|||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long auditId;
|
private Long auditId;
|
||||||
|
|
||||||
/** 报卡ID */
|
/** 报卡编号(关联 infectious_card.card_no) */
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
private String cardId;
|
||||||
private Long cardId;
|
|
||||||
|
|
||||||
/** 审核序号 */
|
/** 审核序号 */
|
||||||
private Integer auditSeq;
|
private Integer auditSeq;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.openhis.infectious.domain;
|
package com.openhis.infectious.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.core.common.core.domain.HisBaseEntity;
|
import com.core.common.core.domain.HisBaseEntity;
|
||||||
@@ -26,12 +27,8 @@ import java.time.LocalDateTime;
|
|||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
public class InfectiousCard extends HisBaseEntity {
|
public class InfectiousCard extends HisBaseEntity {
|
||||||
|
|
||||||
/** 卡片编号 */
|
/** 卡片编号(业务编号,主键) */
|
||||||
@TableId(type = IdType.ASSIGN_ID)
|
@TableId(type = IdType.INPUT)
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/** 卡片编号(业务编号) */
|
|
||||||
private String cardNo;
|
private String cardNo;
|
||||||
|
|
||||||
/** 本次就诊ID */
|
/** 本次就诊ID */
|
||||||
@@ -97,8 +94,9 @@ public class InfectiousCard extends HisBaseEntity {
|
|||||||
/** 现住址门牌号 */
|
/** 现住址门牌号 */
|
||||||
private String addressHouse;
|
private String addressHouse;
|
||||||
|
|
||||||
/** 病人属于 */
|
/** 病人属于(1本县区/2本市其他县区/3本省其他地市/4外省/5港澳台/6外籍) */
|
||||||
private String patientbelong;
|
@TableField("patient_belong")
|
||||||
|
private Integer patientBelong;
|
||||||
|
|
||||||
/** 职业 */
|
/** 职业 */
|
||||||
private String occupation;
|
private String occupation;
|
||||||
@@ -106,18 +104,15 @@ public class InfectiousCard extends HisBaseEntity {
|
|||||||
/** 疾病编码 */
|
/** 疾病编码 */
|
||||||
private String diseaseCode;
|
private String diseaseCode;
|
||||||
|
|
||||||
/** 疾病名称 */
|
|
||||||
private String diseaseName;
|
|
||||||
|
|
||||||
/** 分型 */
|
|
||||||
private String diseaseSubtype;
|
|
||||||
|
|
||||||
/** 其他传染病 */
|
|
||||||
private String otherDisease;
|
|
||||||
|
|
||||||
/** 病例分类 */
|
/** 病例分类 */
|
||||||
private String diseaseType;
|
private String diseaseType;
|
||||||
|
|
||||||
|
/** 其他传染病名称 */
|
||||||
|
private String otherDisease;
|
||||||
|
|
||||||
|
/** 病例类别(1疑似病例/2临床诊断病例/3实验室确诊病例/4病原携带者/5阳性检测结果) */
|
||||||
|
private Integer caseClass;
|
||||||
|
|
||||||
/** 发病日期 */
|
/** 发病日期 */
|
||||||
private LocalDate onsetDate;
|
private LocalDate onsetDate;
|
||||||
|
|
||||||
@@ -146,7 +141,7 @@ public class InfectiousCard extends HisBaseEntity {
|
|||||||
private LocalDate reportDate;
|
private LocalDate reportDate;
|
||||||
|
|
||||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回) */
|
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回) */
|
||||||
private String status;
|
private Integer status;
|
||||||
|
|
||||||
/** 失败原因 */
|
/** 失败原因 */
|
||||||
private String failMsg;
|
private String failMsg;
|
||||||
@@ -165,6 +160,7 @@ public class InfectiousCard extends HisBaseEntity {
|
|||||||
private Long deptId;
|
private Long deptId;
|
||||||
|
|
||||||
/** 科室名称 */
|
/** 科室名称 */
|
||||||
|
@TableField(exist = false)
|
||||||
private String deptName;
|
private String deptName;
|
||||||
|
|
||||||
/** 医生ID */
|
/** 医生ID */
|
||||||
|
|||||||
@@ -334,12 +334,12 @@
|
|||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="病人属于">
|
<el-form-item label="病人属于">
|
||||||
<el-select v-model="currentCard.patientBelong" :disabled="drawerMode !== 'edit'" style="width: 100%">
|
<el-select v-model="currentCard.patientBelong" :disabled="drawerMode !== 'edit'" style="width: 100%">
|
||||||
<el-option label="本县区" value="1" />
|
<el-option label="本县区" :value="1" />
|
||||||
<el-option label="本市其他县区" value="2" />
|
<el-option label="本市其他县区" :value="2" />
|
||||||
<el-option label="本省其他地市" value="3" />
|
<el-option label="本省其他地市" :value="3" />
|
||||||
<el-option label="外省" value="4" />
|
<el-option label="外省" :value="4" />
|
||||||
<el-option label="港澳台" value="5" />
|
<el-option label="港澳台" :value="5" />
|
||||||
<el-option label="外籍" value="6" />
|
<el-option label="外籍" :value="6" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|||||||
@@ -130,12 +130,12 @@
|
|||||||
<el-col :span="24" class="form-item full-width">
|
<el-col :span="24" class="form-item full-width">
|
||||||
<span class="form-label required">病人属于</span>
|
<span class="form-label required">病人属于</span>
|
||||||
<el-radio-group v-model="form.patientBelong">
|
<el-radio-group v-model="form.patientBelong">
|
||||||
<el-radio label="1">本县区</el-radio>
|
<el-radio :label="1">本县区</el-radio>
|
||||||
<el-radio label="2">本市其他县区</el-radio>
|
<el-radio :label="2">本市其他县区</el-radio>
|
||||||
<el-radio label="3">本省其他地市</el-radio>
|
<el-radio :label="3">本省其他地市</el-radio>
|
||||||
<el-radio label="4">外省</el-radio>
|
<el-radio :label="4">外省</el-radio>
|
||||||
<el-radio label="5">港澳台</el-radio>
|
<el-radio :label="5">港澳台</el-radio>
|
||||||
<el-radio label="6">外籍</el-radio>
|
<el-radio :label="6">外籍</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -732,7 +732,7 @@ const form = ref({
|
|||||||
addressTown: '',
|
addressTown: '',
|
||||||
addressVillage: '',
|
addressVillage: '',
|
||||||
addressHouse: '',
|
addressHouse: '',
|
||||||
patientBelong: '1',
|
patientBelong: 1,
|
||||||
occupation: '',
|
occupation: '',
|
||||||
caseClass: '',
|
caseClass: '',
|
||||||
onsetDate: '',
|
onsetDate: '',
|
||||||
@@ -1186,7 +1186,7 @@ function show(diagnosisData) {
|
|||||||
addressHouse: diagnosisData?.addressHouse || '', // 门牌号
|
addressHouse: diagnosisData?.addressHouse || '', // 门牌号
|
||||||
|
|
||||||
// 患者类型和职业
|
// 患者类型和职业
|
||||||
patientBelong: '1', // 患者属于(本县区/本市其他县区/本省其他地市/外省/港澳台/外籍)
|
patientBelong: 1, // 患者属于(本县区/本市其他县区/本省其他地市/外省/港澳台/外籍)
|
||||||
occupation: '', // 职业
|
occupation: '', // 职业
|
||||||
caseClass: '', // 病例分类(疑似病例/临床诊断病例/确诊病例/病原携带者/阳性检测)
|
caseClass: '', // 病例分类(疑似病例/临床诊断病例/确诊病例/病原携带者/阳性检测)
|
||||||
|
|
||||||
@@ -1297,7 +1297,7 @@ async function buildSubmitData() {
|
|||||||
addressTown: formData.addressTown || '',
|
addressTown: formData.addressTown || '',
|
||||||
addressVillage: formData.addressVillage || '',
|
addressVillage: formData.addressVillage || '',
|
||||||
addressHouse: formData.addressHouse || '',
|
addressHouse: formData.addressHouse || '',
|
||||||
patientBelong: patientBelongMap[formData.patientBelong] || 1,
|
patientBelong: formData.patientBelong || 1,
|
||||||
occupation: formData.occupation || null,
|
occupation: formData.occupation || null,
|
||||||
diseaseCode: diseaseCode || null,
|
diseaseCode: diseaseCode || null,
|
||||||
diseaseType: diseaseType || null,
|
diseaseType: diseaseType || null,
|
||||||
|
|||||||
@@ -31,12 +31,12 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item :label="'家长姓名' + (isChildPatient ? '' : '')" :prop="isChildPatient ? 'parentName' : ''" :required="isChildPatient">
|
<el-form-item :label="'家长姓名' + (isChildPatient ? '' : '')" :prop="isChildPatient ? 'parentName' : ''" :required="isChildPatient">
|
||||||
<el-input v-model="form.parentName" placeholder="≤14岁必填" />
|
<el-input v-model="form.parentName" placeholder="≤14岁必填" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="身份证号" prop="idNo" required>
|
<el-form-item label="身份证号" prop="idNo" required>
|
||||||
<el-input v-model="form.idNo" placeholder="请输入身份证号" maxlength="18" @change="handleIdCardChange" />
|
<el-input v-model="form.idNo" placeholder="请输入身份证号" maxlength="18" :disabled="isReadOnly" @change="isReadOnly ? null : handleIdCardChange($event)" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="性别" prop="sex" required>
|
<el-form-item label="性别" prop="sex" required>
|
||||||
<el-radio-group v-model="form.sex">
|
<el-radio-group v-model="form.sex" :disabled="isReadOnly">
|
||||||
<el-radio label="男">男</el-radio>
|
<el-radio label="男">男</el-radio>
|
||||||
<el-radio label="女">女</el-radio>
|
<el-radio label="女">女</el-radio>
|
||||||
<el-radio label="未知">未知</el-radio>
|
<el-radio label="未知">未知</el-radio>
|
||||||
@@ -55,11 +55,11 @@
|
|||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<el-form-item label="出生日期" required>
|
<el-form-item label="出生日期" required>
|
||||||
<div class="date-inputs">
|
<div class="date-inputs">
|
||||||
<el-input v-model="form.birthYear" placeholder="年" maxlength="4" @change="calculateAge" style="width: 80px" />
|
<el-input v-model="form.birthYear" placeholder="年" maxlength="4" :disabled="isReadOnly" @change="isReadOnly ? null : calculateAge()" style="width: 80px" />
|
||||||
<span>年</span>
|
<span>年</span>
|
||||||
<el-input v-model="form.birthMonth" placeholder="月" maxlength="2" @change="calculateAge" style="width: 60px" />
|
<el-input v-model="form.birthMonth" placeholder="月" maxlength="2" :disabled="isReadOnly" @change="isReadOnly ? null : calculateAge()" style="width: 60px" />
|
||||||
<span>月</span>
|
<span>月</span>
|
||||||
<el-input v-model="form.birthDay" placeholder="日" maxlength="2" @change="calculateAge" style="width: 60px" />
|
<el-input v-model="form.birthDay" placeholder="日" maxlength="2" :disabled="isReadOnly" @change="isReadOnly ? null : calculateAge()" style="width: 60px" />
|
||||||
<span>日</span>
|
<span>日</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -67,8 +67,8 @@
|
|||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="或 实足年龄">
|
<el-form-item label="或 实足年龄">
|
||||||
<div class="age-inputs">
|
<div class="age-inputs">
|
||||||
<el-input v-model="form.age" placeholder="年龄" style="width: 100px" />
|
<el-input v-model="form.age" placeholder="年龄" style="width: 100px" :disabled="isReadOnly" />
|
||||||
<el-select v-model="form.ageUnit" style="width: 80px">
|
<el-select v-model="form.ageUnit" style="width: 80px" :disabled="isReadOnly">
|
||||||
<el-option label="岁" value="岁" />
|
<el-option label="岁" value="岁" />
|
||||||
<el-option label="月" value="月" />
|
<el-option label="月" value="月" />
|
||||||
<el-option label="天" value="天" />
|
<el-option label="天" value="天" />
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="工作单位(学校)">
|
<el-form-item label="工作单位(学校)">
|
||||||
<el-input v-model="form.workplace" placeholder="请输入工作单位" />
|
<el-input v-model="form.workplace" placeholder="请输入工作单位" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -91,12 +91,12 @@
|
|||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="联系电话" prop="phone" required>
|
<el-form-item label="联系电话" prop="phone" required>
|
||||||
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
|
<el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="紧急联系人电话" prop="contactPhone" required>
|
<el-form-item label="紧急联系人电话" prop="contactPhone" required>
|
||||||
<el-input v-model="form.contactPhone" placeholder="请输入紧急联系人电话" maxlength="11" />
|
<el-input v-model="form.contactPhone" placeholder="请输入紧急联系人电话" maxlength="11" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -112,6 +112,7 @@
|
|||||||
placeholder="请选择省/市/区县/街道"
|
placeholder="请选择省/市/区县/街道"
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
:disabled="isReadOnly"
|
||||||
@change="handleAddressChange"
|
@change="handleAddressChange"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -119,10 +120,10 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-input v-model="form.addressVillage" placeholder="村(居)" />
|
<el-input v-model="form.addressVillage" placeholder="村(居)" :disabled="isReadOnly" />
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-input v-model="form.addressHouse" placeholder="门牌号" />
|
<el-input v-model="form.addressHouse" placeholder="门牌号" :disabled="isReadOnly" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@@ -130,13 +131,13 @@
|
|||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="病人属于" prop="patientBelong" required>
|
<el-form-item label="病人属于" prop="patientBelong" required>
|
||||||
<el-radio-group v-model="form.patientBelong">
|
<el-radio-group v-model="form.patientBelong" :disabled="isReadOnly">
|
||||||
<el-radio label="1">本县区</el-radio>
|
<el-radio :label="1">本县区</el-radio>
|
||||||
<el-radio label="2">本市其他县区</el-radio>
|
<el-radio :label="2">本市其他县区</el-radio>
|
||||||
<el-radio label="3">本省其他地市</el-radio>
|
<el-radio :label="3">本省其他地市</el-radio>
|
||||||
<el-radio label="4">外省</el-radio>
|
<el-radio :label="4">外省</el-radio>
|
||||||
<el-radio label="5">港澳台</el-radio>
|
<el-radio :label="5">港澳台</el-radio>
|
||||||
<el-radio label="6">外籍</el-radio>
|
<el-radio :label="6">外籍</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -146,14 +147,14 @@
|
|||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="职业" prop="occupation" required>
|
<el-form-item label="职业" prop="occupation" required>
|
||||||
<el-select v-model="form.occupation" placeholder="请选择职业" style="width: 100%">
|
<el-select v-model="form.occupation" placeholder="请选择职业" style="width: 100%" :disabled="isReadOnly">
|
||||||
<el-option v-for="item in occupationList" :key="item.value" :label="item.label" :value="item.value" />
|
<el-option v-for="item in occupationList" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="病例分类" prop="caseClass" required>
|
<el-form-item label="病例分类" prop="caseClass" required>
|
||||||
<el-radio-group v-model="form.caseClass">
|
<el-radio-group v-model="form.caseClass" :disabled="isReadOnly">
|
||||||
<el-radio label="1">疑似病例</el-radio>
|
<el-radio label="1">疑似病例</el-radio>
|
||||||
<el-radio label="2">临床诊断病例</el-radio>
|
<el-radio label="2">临床诊断病例</el-radio>
|
||||||
<el-radio label="3">确诊病例</el-radio>
|
<el-radio label="3">确诊病例</el-radio>
|
||||||
@@ -175,6 +176,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
||||||
|
:disabled="isReadOnly"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -187,6 +189,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
||||||
|
:disabled="isReadOnly"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -199,6 +202,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
||||||
|
:disabled="isReadOnly"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -215,11 +219,13 @@
|
|||||||
<div class="disease-list">
|
<div class="disease-list">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
:model-value="form.selectedClassA === '0101'"
|
:model-value="form.selectedClassA === '0101'"
|
||||||
@update:model-value="(checked) => handleClassACheckbox('0101', checked)"
|
:disabled="isReadOnly"
|
||||||
|
@update:model-value="(checked) => isReadOnly ? null : handleClassACheckbox('0101', checked)"
|
||||||
>鼠疫</el-checkbox>
|
>鼠疫</el-checkbox>
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
:model-value="form.selectedClassA === '0102'"
|
:model-value="form.selectedClassA === '0102'"
|
||||||
@update:model-value="(checked) => handleClassACheckbox('0102', checked)"
|
:disabled="isReadOnly"
|
||||||
|
@update:model-value="(checked) => isReadOnly ? null : handleClassACheckbox('0102', checked)"
|
||||||
>霍乱</el-checkbox>
|
>霍乱</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -232,7 +238,8 @@
|
|||||||
v-for="disease in classBDiseases"
|
v-for="disease in classBDiseases"
|
||||||
:key="disease.code"
|
:key="disease.code"
|
||||||
:model-value="form.selectedClassB === disease.code"
|
:model-value="form.selectedClassB === disease.code"
|
||||||
@update:model-value="(checked) => handleClassBCheckbox(disease.code, checked)"
|
:disabled="isReadOnly"
|
||||||
|
@update:model-value="(checked) => isReadOnly ? null : handleClassBCheckbox(disease.code, checked)"
|
||||||
>{{ disease.name }}</el-checkbox>
|
>{{ disease.name }}</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -245,7 +252,8 @@
|
|||||||
v-for="disease in classCDiseases"
|
v-for="disease in classCDiseases"
|
||||||
:key="disease.code"
|
:key="disease.code"
|
||||||
:model-value="form.selectedClassC === disease.code"
|
:model-value="form.selectedClassC === disease.code"
|
||||||
@update:model-value="(checked) => handleClassCCheckbox(disease.code, checked)"
|
:disabled="isReadOnly"
|
||||||
|
@update:model-value="(checked) => isReadOnly ? null : handleClassCCheckbox(disease.code, checked)"
|
||||||
>{{ disease.name }}</el-checkbox>
|
>{{ disease.name }}</el-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -254,12 +262,12 @@
|
|||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="showSubtypeSelect ? 16 : 24">
|
<el-col :span="showSubtypeSelect ? 16 : 24">
|
||||||
<el-form-item label="其他法定管理以及重点监测传染病">
|
<el-form-item label="其他法定管理以及重点监测传染病">
|
||||||
<el-input v-model="form.otherDisease" placeholder="手动输入非列表疾病" />
|
<el-input v-model="form.otherDisease" placeholder="手动输入非列表疾病" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-if="showSubtypeSelect" :span="8">
|
<el-col v-if="showSubtypeSelect" :span="8">
|
||||||
<el-form-item label="分型" prop="diseaseType" :required="showSubtypeSelect">
|
<el-form-item label="分型" prop="diseaseType" :required="showSubtypeSelect">
|
||||||
<el-select v-model="form.diseaseType" placeholder="请选择分型" style="width: 100%">
|
<el-select v-model="form.diseaseType" placeholder="请选择分型" style="width: 100%" :disabled="isReadOnly">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="option in currentSubtypeOptions"
|
v-for="option in currentSubtypeOptions"
|
||||||
:key="option.value"
|
:key="option.value"
|
||||||
@@ -284,7 +292,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="联系电话">
|
<el-form-item label="联系电话">
|
||||||
<el-input v-model="form.reportOrgPhone" placeholder="请输入联系电话" />
|
<el-input v-model="form.reportOrgPhone" placeholder="请输入联系电话" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
@@ -304,17 +312,18 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
||||||
|
:disabled="isReadOnly"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="订正病名">
|
<el-form-item label="订正病名">
|
||||||
<el-input v-model="form.correctName" placeholder="请输入订正病名" />
|
<el-input v-model="form.correctName" placeholder="请输入订正病名" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="退卡原因">
|
<el-form-item label="退卡原因">
|
||||||
<el-input v-model="form.withdrawReason" placeholder="请输入退卡原因" />
|
<el-input v-model="form.withdrawReason" placeholder="请输入退卡原因" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -322,15 +331,15 @@
|
|||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" :disabled="isReadOnly" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 操作按钮区 -->
|
<!-- 操作按钮区(create/edit 模式下显示) -->
|
||||||
<div class="action-buttons">
|
<div v-if="mode !== 'view'" class="action-buttons">
|
||||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">保 存</el-button>
|
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">保 存</el-button>
|
||||||
<el-button @click="handleReset">重 置</el-button>
|
<el-button @click="handleReset">重 置</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -347,6 +356,9 @@ import { useDict } from '@/utils/dict';
|
|||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
// 是否只读模式
|
||||||
|
const isReadOnly = computed(() => props.mode === 'view');
|
||||||
|
|
||||||
// 获取职业字典数据
|
// 获取职业字典数据
|
||||||
const { prfs: occupationList } = useDict('prfs');
|
const { prfs: occupationList } = useDict('prfs');
|
||||||
|
|
||||||
@@ -418,9 +430,19 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
// 'create' | 'view' | 'edit'
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'create',
|
||||||
|
},
|
||||||
|
// 已有报卡数据(view/edit 模式下使用)
|
||||||
|
cardData: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['saved']);
|
const emit = defineEmits(['saved', 'submit-edit']);
|
||||||
|
|
||||||
// 地址级联选择器配置
|
// 地址级联选择器配置
|
||||||
const addressOptions = ref(pcas);
|
const addressOptions = ref(pcas);
|
||||||
@@ -453,7 +475,7 @@ const form = ref({
|
|||||||
addressTown: '',
|
addressTown: '',
|
||||||
addressVillage: '',
|
addressVillage: '',
|
||||||
addressHouse: '',
|
addressHouse: '',
|
||||||
patientBelong: '1',
|
patientBelong: 1,
|
||||||
occupation: '',
|
occupation: '',
|
||||||
caseClass: '',
|
caseClass: '',
|
||||||
onsetDate: '',
|
onsetDate: '',
|
||||||
@@ -567,19 +589,27 @@ const isChildPatient = computed(() => {
|
|||||||
|
|
||||||
// 监听疾病选择变化,自动清空分型选择
|
// 监听疾病选择变化,自动清空分型选择
|
||||||
watch(() => [form.value.selectedClassA, form.value.selectedClassB, form.value.selectedClassC], (newVal, oldVal) => {
|
watch(() => [form.value.selectedClassA, form.value.selectedClassB, form.value.selectedClassC], (newVal, oldVal) => {
|
||||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
// 在view/edit模式下初始化时不清空分型,避免数据加载时被错误清空
|
||||||
|
if (JSON.stringify(newVal) !== JSON.stringify(oldVal) && props.mode !== 'view' && props.mode !== 'edit') {
|
||||||
form.value.diseaseType = '';
|
form.value.diseaseType = '';
|
||||||
}
|
}
|
||||||
updateSelectedDiseases();
|
updateSelectedDiseases();
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
// 监听患者信息变化,自动填充表单
|
// 监听患者信息变化,自动填充表单(仅 create 模式)
|
||||||
watch(() => props.patientInfo, (newVal) => {
|
watch(() => props.patientInfo, (newVal) => {
|
||||||
if (newVal && Object.keys(newVal).length > 0) {
|
if (props.mode === 'create' && newVal && Object.keys(newVal).length > 0) {
|
||||||
initForm();
|
initForm();
|
||||||
}
|
}
|
||||||
}, { deep: true, immediate: true });
|
}, { deep: true, immediate: true });
|
||||||
|
|
||||||
|
// 监听 cardData 变化,在 view/edit 模式下初始化
|
||||||
|
watch(() => props.cardData, (newVal) => {
|
||||||
|
if ((props.mode === 'view' || props.mode === 'edit') && newVal) {
|
||||||
|
initFormFromCard(newVal);
|
||||||
|
}
|
||||||
|
}, { immediate: true });
|
||||||
|
|
||||||
// 监听Tab切换,重新初始化
|
// 监听Tab切换,重新初始化
|
||||||
watch(() => props.activeTab, (newVal) => {
|
watch(() => props.activeTab, (newVal) => {
|
||||||
if (newVal === 'infectiousReport' && props.patientInfo && Object.keys(props.patientInfo).length > 0) {
|
if (newVal === 'infectiousReport' && props.patientInfo && Object.keys(props.patientInfo).length > 0) {
|
||||||
@@ -808,7 +838,7 @@ async function initForm() {
|
|||||||
addressTown: patientInfo.addressStreet || '',
|
addressTown: patientInfo.addressStreet || '',
|
||||||
addressVillage: '',
|
addressVillage: '',
|
||||||
addressHouse: '',
|
addressHouse: '',
|
||||||
patientBelong: '1',
|
patientBelong: 1,
|
||||||
occupation: '',
|
occupation: '',
|
||||||
caseClass: '',
|
caseClass: '',
|
||||||
onsetDate: getCurrentDate(),
|
onsetDate: getCurrentDate(),
|
||||||
@@ -893,7 +923,7 @@ function buildSubmitData() {
|
|||||||
addressTown: formData.addressTown || '',
|
addressTown: formData.addressTown || '',
|
||||||
addressVillage: formData.addressVillage || '',
|
addressVillage: formData.addressVillage || '',
|
||||||
addressHouse: formData.addressHouse || '',
|
addressHouse: formData.addressHouse || '',
|
||||||
patientBelong: parseInt(formData.patientBelong) || 1,
|
patientBelong: formData.patientBelong || 1,
|
||||||
occupation: formData.occupation || null,
|
occupation: formData.occupation || null,
|
||||||
diseaseCode: diseaseCode || null,
|
diseaseCode: diseaseCode || null,
|
||||||
diseaseType: diseaseType || null,
|
diseaseType: diseaseType || null,
|
||||||
@@ -1015,15 +1045,20 @@ async function handleSubmit() {
|
|||||||
|
|
||||||
const submitData = buildSubmitData();
|
const submitData = buildSubmitData();
|
||||||
|
|
||||||
const res = await saveInfectiousDiseaseReport(submitData);
|
if (props.mode === 'edit') {
|
||||||
|
// 编辑模式:通过事件通知父组件处理保存
|
||||||
if (res.code === 200) {
|
emit('submit-edit', submitData);
|
||||||
proxy.$modal.msgSuccess('传染病报告卡保存成功');
|
|
||||||
emit('saved');
|
|
||||||
// 重新初始化表单,获取新的卡片编号
|
|
||||||
initForm();
|
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '保存失败');
|
// 新建模式
|
||||||
|
const res = await saveInfectiousDiseaseReport(submitData);
|
||||||
|
if (res.code === 200) {
|
||||||
|
proxy.$modal.msgSuccess('传染病报告卡保存成功');
|
||||||
|
emit('saved');
|
||||||
|
// 重新初始化表单,获取新的卡片编号
|
||||||
|
initForm();
|
||||||
|
} else {
|
||||||
|
proxy.$modal.msgError(res.msg || '保存失败');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('传染病报告卡保存失败:', err);
|
console.error('传染病报告卡保存失败:', err);
|
||||||
@@ -1065,7 +1100,7 @@ function handleReset() {
|
|||||||
form.value.contactPhone = '';
|
form.value.contactPhone = '';
|
||||||
form.value.occupation = '';
|
form.value.occupation = '';
|
||||||
form.value.caseClass = '';
|
form.value.caseClass = '';
|
||||||
form.value.patientBelong = '1';
|
form.value.patientBelong = 1;
|
||||||
form.value.otherDisease = '';
|
form.value.otherDisease = '';
|
||||||
form.value.correctName = '';
|
form.value.correctName = '';
|
||||||
form.value.withdrawReason = '';
|
form.value.withdrawReason = '';
|
||||||
@@ -1075,22 +1110,108 @@ function handleReset() {
|
|||||||
updateSelectedDiseases();
|
updateSelectedDiseases();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从已有报卡数据初始化表单(view/edit 模式)
|
||||||
|
function initFormFromCard(card) {
|
||||||
|
if (!card) return;
|
||||||
|
|
||||||
|
const ageUnitReverseMap = { '1': '岁', '2': '月', '3': '天' };
|
||||||
|
const sexMap = { '1': '男', '2': '女', '0': '未知' };
|
||||||
|
|
||||||
|
// 拆解出生日期
|
||||||
|
let birthYear = '', birthMonth = '', birthDay = '';
|
||||||
|
if (card.birthday) {
|
||||||
|
const parts = card.birthday.split('-');
|
||||||
|
birthYear = parts[0] || '';
|
||||||
|
birthMonth = parts[1] || '';
|
||||||
|
birthDay = parts[2] || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 还原疾病分类选中状态
|
||||||
|
let selectedClassA = '', selectedClassB = '', selectedClassC = '';
|
||||||
|
if (card.diseaseCode) {
|
||||||
|
if (card.diseaseCode.startsWith('01')) selectedClassA = card.diseaseCode;
|
||||||
|
else if (card.diseaseCode.startsWith('02')) selectedClassB = card.diseaseCode;
|
||||||
|
else if (card.diseaseCode.startsWith('03')) selectedClassC = card.diseaseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
form.value = {
|
||||||
|
cardNo: card.cardNo || '',
|
||||||
|
patName: card.patName || '',
|
||||||
|
parentName: card.parentName || '',
|
||||||
|
idNo: card.idNo || '',
|
||||||
|
sex: sexMap[card.sex] || card.sex || '男',
|
||||||
|
birthYear,
|
||||||
|
birthMonth,
|
||||||
|
birthDay,
|
||||||
|
age: card.age != null ? String(card.age) : '',
|
||||||
|
ageUnit: ageUnitReverseMap[card.ageUnit] || '岁',
|
||||||
|
workplace: card.workplace || '',
|
||||||
|
phone: card.phone || '',
|
||||||
|
contactPhone: card.contactPhone || '',
|
||||||
|
addressProv: card.addressProv || '',
|
||||||
|
addressCity: card.addressCity || '',
|
||||||
|
addressCounty: card.addressCounty || '',
|
||||||
|
addressTown: card.addressTown || '',
|
||||||
|
addressVillage: card.addressVillage || '',
|
||||||
|
addressHouse: card.addressHouse || '',
|
||||||
|
patientBelong: card.patientBelong || 1,
|
||||||
|
occupation: card.occupation || '',
|
||||||
|
caseClass: card.caseClass != null ? String(card.caseClass) : '',
|
||||||
|
onsetDate: card.onsetDate || '',
|
||||||
|
diagDate: card.diagDate ? card.diagDate.substring(0, 10) : '',
|
||||||
|
deathDate: card.deathDate || '',
|
||||||
|
selectedDiseases: card.diseaseCode && card.diseaseCode !== 'OTHER' ? [card.diseaseCode] : [],
|
||||||
|
selectedClassA,
|
||||||
|
selectedClassB,
|
||||||
|
selectedClassC,
|
||||||
|
otherDisease: card.diseaseCode === 'OTHER' ? (card.otherDisease || '') : (card.otherDisease || ''),
|
||||||
|
diseaseType: card.diseaseType || '',
|
||||||
|
reportOrg: card.reportOrg || '',
|
||||||
|
reportOrgPhone: card.reportOrgPhone || '',
|
||||||
|
reportDoc: card.reportDoc || '',
|
||||||
|
reportDate: card.reportDate || '',
|
||||||
|
correctName: card.correctName || '',
|
||||||
|
withdrawReason: card.withdrawReason || '',
|
||||||
|
remark: card.remark || '',
|
||||||
|
encounterId: card.visitId || '',
|
||||||
|
patientId: card.patId || '',
|
||||||
|
diagnosisId: card.diagId || '',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置地址级联选择器
|
||||||
|
const provName = card.addressProv || '';
|
||||||
|
const cityName = card.addressCity || '';
|
||||||
|
const countyName = card.addressCounty || '';
|
||||||
|
const townName = card.addressTown || '';
|
||||||
|
let names = [];
|
||||||
|
if (municipalities.includes(provName)) {
|
||||||
|
names = [provName, countyName, townName].filter(n => n);
|
||||||
|
} else {
|
||||||
|
names = [provName, cityName, countyName, townName].filter(n => n);
|
||||||
|
}
|
||||||
|
addressCodes.value = findCodesByNames(names);
|
||||||
|
}
|
||||||
|
|
||||||
// 组件挂载时初始化
|
// 组件挂载时初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.patientInfo && Object.keys(props.patientInfo).length > 0) {
|
if ((props.mode === 'view' || props.mode === 'edit') && props.cardData) {
|
||||||
|
initFormFromCard(props.cardData);
|
||||||
|
} else if (props.mode === 'create' && props.patientInfo && Object.keys(props.patientInfo).length > 0) {
|
||||||
initForm();
|
initForm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 暴露方法供父组件调用
|
// 暴露方法供父组件调用
|
||||||
defineExpose({
|
defineExpose({
|
||||||
initForm
|
initForm,
|
||||||
|
initFormFromCard
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.infectious-report-container {
|
.infectious-report-container {
|
||||||
height: 100%;
|
height: auto;
|
||||||
|
min-height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -1130,8 +1251,7 @@ defineExpose({
|
|||||||
|
|
||||||
/* 表单区域样式 */
|
/* 表单区域样式 */
|
||||||
.report-form {
|
.report-form {
|
||||||
flex: 1;
|
overflow-y: visible;
|
||||||
overflow-y: auto;
|
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="my-card-management-container">
|
<div class="my-card-management-container">
|
||||||
|
<!-- 顶部标题 -->
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>我的报卡</h2>
|
<h2 class="page-title">我的报卡</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 统计卡片区 -->
|
||||||
<div class="statistics-section">
|
<div class="statistics-section">
|
||||||
<div class="stat-card total">
|
<div class="stat-card">
|
||||||
<div class="stat-icon">
|
<div class="stat-icon-wrap stat-icon-purple">
|
||||||
<el-icon><Document /></el-icon>
|
<el-icon class="stat-icon-inner"><DataAnalysis /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
<div class="stat-value">{{ statistics.totalCount || 0 }}</div>
|
<div class="stat-value">{{ statistics.totalCount || 0 }}</div>
|
||||||
<div class="stat-label">总报卡数</div>
|
<div class="stat-label">总报卡数</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card pending">
|
<div class="stat-card">
|
||||||
<div class="stat-icon">
|
<div class="stat-icon-wrap stat-icon-red">
|
||||||
<el-icon><Clock /></el-icon>
|
<el-icon class="stat-icon-inner"><Warning /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
<div class="stat-value">{{ statistics.pendingFailedCount || 0 }}</div>
|
<div class="stat-value">{{ statistics.pendingFailedCount || 0 }}</div>
|
||||||
<div class="stat-label">待处理/失败</div>
|
<div class="stat-label">待提交</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card success">
|
<div class="stat-card">
|
||||||
<div class="stat-icon">
|
<div class="stat-icon-wrap stat-icon-green">
|
||||||
<el-icon><CircleCheck /></el-icon>
|
<el-icon class="stat-icon-inner"><CircleCheck /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-content">
|
<div class="stat-content">
|
||||||
<div class="stat-value">{{ statistics.reportedCount || 0 }}</div>
|
<div class="stat-value">{{ statistics.reportedCount || 0 }}</div>
|
||||||
@@ -34,21 +36,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 高级筛选区 -->
|
||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<el-form :model="queryParams" :inline="true">
|
<div class="filter-title">高级筛选</div>
|
||||||
<el-form-item label="日期范围">
|
<div class="filter-row">
|
||||||
|
<div class="filter-item">
|
||||||
|
<span class="filter-label">日期范围</span>
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="queryParams.dateRange"
|
v-model="queryParams.dateRange"
|
||||||
type="daterange"
|
type="daterange"
|
||||||
range-separator="至"
|
range-separator="至"
|
||||||
start-placeholder="开始日期"
|
start-placeholder="年/月/日"
|
||||||
end-placeholder="结束日期"
|
end-placeholder="年/月/日"
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
style="width: 240px"
|
class="filter-date-picker"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</div>
|
||||||
<el-form-item label="状态">
|
<div class="filter-item">
|
||||||
<el-select v-model="queryParams.status" placeholder="全部状态" clearable style="width: 140px">
|
<span class="filter-label">状态</span>
|
||||||
|
<el-select v-model="queryParams.status" placeholder="全部状态" clearable class="filter-select">
|
||||||
<el-option label="全部状态" value="" />
|
<el-option label="全部状态" value="" />
|
||||||
<el-option label="待提交" value="0" />
|
<el-option label="待提交" value="0" />
|
||||||
<el-option label="已提交" value="1" />
|
<el-option label="已提交" value="1" />
|
||||||
@@ -57,101 +63,65 @@
|
|||||||
<el-option label="失败" value="4" />
|
<el-option label="失败" value="4" />
|
||||||
<el-option label="作废" value="6" />
|
<el-option label="作废" value="6" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</div>
|
||||||
<el-form-item label="关键词">
|
<div class="filter-item">
|
||||||
|
<span class="filter-label">报卡名称</span>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.keyword"
|
v-model="queryParams.keyword"
|
||||||
placeholder="患者姓名/报卡名称"
|
placeholder="输入报卡名称..."
|
||||||
clearable
|
clearable
|
||||||
style="width: 180px"
|
class="filter-input"
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</div>
|
||||||
<el-form-item>
|
<div class="filter-actions">
|
||||||
<el-button type="primary" @click="handleQuery">
|
<el-button class="btn-apply" type="primary" @click="handleQuery">
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon><Check /></el-icon>
|
||||||
应用筛选
|
应用筛选
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="handleReset">
|
<el-button class="btn-reset" @click="handleReset">
|
||||||
<el-icon><Refresh /></el-icon>
|
<el-icon><RefreshRight /></el-icon>
|
||||||
重置条件
|
重置条件
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-form>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="action-section">
|
|
||||||
<el-checkbox v-model="isAllSelected" @change="handleSelectAll">全选</el-checkbox>
|
|
||||||
<el-button type="primary" :disabled="selectedRows.length === 0" @click="handleBatchSubmit">
|
|
||||||
批量提交
|
|
||||||
</el-button>
|
|
||||||
<el-button type="danger" :disabled="selectedRows.length === 0" @click="handleBatchDelete">
|
|
||||||
批量删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 数据表格区 -->
|
||||||
<div class="table-section">
|
<div class="table-section">
|
||||||
<el-table
|
<el-table
|
||||||
|
ref="tableRef"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="cardList"
|
:data="cardList"
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
border
|
border
|
||||||
stripe
|
stripe
|
||||||
|
:height="tableHeight"
|
||||||
|
virtualized
|
||||||
|
:virtualized-row-height="48"
|
||||||
>
|
>
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="50" align="center" />
|
||||||
<el-table-column label="卡片ID" prop="cardNo" min-width="150" />
|
<el-table-column label="卡片ID" prop="cardNo" min-width="155" />
|
||||||
<el-table-column label="患者姓名" prop="patName" width="100" />
|
<el-table-column label="患者姓名" prop="patName" width="90" />
|
||||||
<el-table-column label="身份证号" prop="idNo" min-width="180" />
|
<el-table-column label="身份证号" prop="idNo" min-width="170" />
|
||||||
<el-table-column label="联系电话" prop="phone" width="130" />
|
<el-table-column label="联系电话" prop="phone" width="120" />
|
||||||
<el-table-column label="就诊卡号" prop="visitCardNo" width="130" />
|
<el-table-column label="就诊卡号" prop="visitCardNo" width="110" />
|
||||||
<el-table-column label="报卡名称" prop="cardName" min-width="200" />
|
<el-table-column label="报卡名称" prop="cardName" min-width="120" />
|
||||||
<el-table-column label="提交时间" prop="submitTime" width="160" align="center" />
|
<el-table-column label="提交时间" prop="submitTime" width="110" align="center" />
|
||||||
<el-table-column label="状态" prop="status" width="100" align="center">
|
<el-table-column label="状态" prop="status" width="80" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag :type="getStatusType(row.status)" size="small">
|
<span :class="['status-tag', 'status-' + row.status]">
|
||||||
{{ getStatusName(row.status) }}
|
{{ getStatusName(row.status) }}
|
||||||
</el-tag>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
<el-table-column label="操作" width="160" align="center" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button type="primary" link size="small" @click="handleView(row)">查看</el-button>
|
<el-button type="primary" link size="small" @click="handleView(row)">查看</el-button>
|
||||||
<el-button
|
<el-button v-if="row.status == 0" type="primary" link size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
v-if="row.status === '0'"
|
<el-button v-if="row.status == 0" type="success" link size="small" @click="handleSubmit(row)">提交</el-button>
|
||||||
type="primary"
|
<el-button v-if="row.status == 1" type="warning" link size="small" @click="handleWithdraw(row)">撤回</el-button>
|
||||||
link
|
<el-button v-if="row.status == 3" type="primary" link size="small" @click="handleExport(row)">导出</el-button>
|
||||||
size="small"
|
|
||||||
@click="handleEdit(row)"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-if="row.status === '0'"
|
|
||||||
type="success"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleSubmit(row)"
|
|
||||||
>
|
|
||||||
提交
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-if="row.status === '1'"
|
|
||||||
type="warning"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleWithdraw(row)"
|
|
||||||
>
|
|
||||||
撤回
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
v-if="row.status === '3'"
|
|
||||||
type="info"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleExport(row)"
|
|
||||||
>
|
|
||||||
导出
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -169,149 +139,43 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部批量操作栏 -->
|
||||||
|
<div class="bottom-action-bar">
|
||||||
|
<div class="bottom-action-left">
|
||||||
|
<el-checkbox v-model="isAllSelected" @change="handleSelectAll">全选</el-checkbox>
|
||||||
|
<span class="selected-info">已选择 {{ selectedRows.length }} 个项目</span>
|
||||||
|
</div>
|
||||||
|
<div class="bottom-action-right">
|
||||||
|
<el-button class="btn-batch-delete" :disabled="selectedRows.length === 0" @click="handleBatchDelete">批量删除</el-button>
|
||||||
|
<el-button class="btn-batch-submit" type="primary" :disabled="selectedRows.length === 0" @click="handleBatchSubmit">批量提交</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="detailVisible"
|
v-model="detailVisible"
|
||||||
:title="detailMode === 'view' ? '报卡详情' : '编辑报卡'"
|
:title="detailMode === 'view' ? '报卡详情' : '编辑报卡'"
|
||||||
width="800px"
|
width="900px"
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
|
class="card-detail-dialog"
|
||||||
>
|
>
|
||||||
<el-descriptions v-if="detailMode === 'view'" :column="2" border>
|
<InfectiousReport
|
||||||
<el-descriptions-item label="卡片编号">{{ currentCard.cardNo }}</el-descriptions-item>
|
:mode=" detailMode"
|
||||||
<el-descriptions-item label="状态">
|
:card-data="currentCard"
|
||||||
<el-tag :type="getStatusType(currentCard.status)">{{ getStatusName(currentCard.status) }}</el-tag>
|
@submit-edit="handleSaveEdit"
|
||||||
</el-descriptions-item>
|
style="max-height: 70vh; overflow-y: auto;"
|
||||||
<el-descriptions-item label="患者姓名">{{ currentCard.patName }}</el-descriptions-item>
|
/>
|
||||||
<el-descriptions-item label="身份证号">{{ currentCard.idNo }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="联系电话">{{ currentCard.phone }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="性别">{{ currentCard.sex === '1' ? '男' : currentCard.sex === '2' ? '女' : '未知' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="年龄">{{ currentCard.age }}{{ getAgeUnit(currentCard.ageUnit) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="疾病名称">{{ currentCard.diseaseName }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="发病日期">{{ currentCard.onsetDate }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="诊断日期">{{ currentCard.diagDate }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="报告单位">{{ currentCard.reportOrg }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="报告医生">{{ currentCard.reportDoc }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="填卡日期">{{ currentCard.reportDate }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="现住址" :span="2">
|
|
||||||
{{ currentCard.addressProv }}{{ currentCard.addressCity }}{{ currentCard.addressCounty }}{{ currentCard.addressTown }}{{ currentCard.addressVillage }}{{ currentCard.addressHouse }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
<el-form v-else ref="editFormRef" :model="editForm" :rules="editFormRules" label-width="100px">
|
|
||||||
<!-- 患者基本信息 -->
|
|
||||||
<el-divider content-position="left">患者基本信息</el-divider>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="患者姓名" prop="patName">
|
|
||||||
<el-input v-model="editForm.patName" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="身份证号" prop="idNo">
|
|
||||||
<el-input v-model="editForm.idNo" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="性别" prop="sex">
|
|
||||||
<el-input :value="editForm.sex === '1' ? '男' : editForm.sex === '2' ? '女' : '未知'" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="年龄" prop="age">
|
|
||||||
<el-input :value="`${editForm.age}${getAgeUnit(editForm.ageUnit)}`" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="联系电话" prop="phone" required>
|
|
||||||
<el-input v-model="editForm.phone" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<!-- 临床信息 -->
|
|
||||||
<el-divider content-position="left">临床信息</el-divider>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="疾病名称" prop="diseaseName">
|
|
||||||
<el-input v-model="editForm.diseaseName" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="发病日期" prop="onsetDate">
|
|
||||||
<el-date-picker v-model="editForm.onsetDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="诊断日期" prop="diagDate" required>
|
|
||||||
<el-date-picker v-model="editForm.diagDate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="传染病类别" prop="diseaseType">
|
|
||||||
<el-select v-model="editForm.diseaseType" placeholder="请选择传染病类别" style="width: 100%">
|
|
||||||
<el-option label="甲类传染病" value="A" />
|
|
||||||
<el-option label="乙类传染病" value="B" />
|
|
||||||
<el-option label="丙类传染病" value="C" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<!-- 报告信息 -->
|
|
||||||
<el-divider content-position="left">报告信息</el-divider>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="报告单位" prop="reportOrg">
|
|
||||||
<el-input v-model="editForm.reportOrg" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="报告医生" prop="reportDoc">
|
|
||||||
<el-input v-model="editForm.reportDoc" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="填卡日期" prop="reportDate">
|
|
||||||
<el-input v-model="editForm.reportDate" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<!-- 现住址 -->
|
|
||||||
<el-divider content-position="left">现住址</el-divider>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="省" prop="addressProv">
|
|
||||||
<el-input v-model="editForm.addressProv" placeholder="请输入省份" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="市" prop="addressCity">
|
|
||||||
<el-input v-model="editForm.addressCity" placeholder="请输入城市" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-form-item label="区县" prop="addressCounty">
|
|
||||||
<el-input v-model="editForm.addressCounty" placeholder="请输入区县" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-form-item label="详细地址" prop="addressHouse">
|
|
||||||
<el-input v-model="editForm.addressHouse" type="textarea" placeholder="请输入详细地址" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="detailVisible = false">取消</el-button>
|
<el-button @click="detailVisible = false">关闭</el-button>
|
||||||
<el-button v-if="detailMode === 'edit'" type="primary" @click="handleSaveEdit">保存</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted, onActivated, onBeforeUnmount, nextTick, computed } from 'vue';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { Document, Clock, CircleCheck, Search, Refresh } from '@element-plus/icons-vue';
|
import { DataAnalysis, Warning, CircleCheck, Check, RefreshRight } from '@element-plus/icons-vue';
|
||||||
|
import InfectiousReport from '../components/infectiousReport/index.vue';
|
||||||
import {
|
import {
|
||||||
getDoctorCardStatistics,
|
getDoctorCardStatistics,
|
||||||
getDoctorCardList,
|
getDoctorCardList,
|
||||||
@@ -329,6 +193,7 @@ const cardList = ref([]);
|
|||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
const isAllSelected = ref(false);
|
const isAllSelected = ref(false);
|
||||||
|
const tableRef = ref(null);
|
||||||
|
|
||||||
const statistics = ref({
|
const statistics = ref({
|
||||||
totalCount: 0,
|
totalCount: 0,
|
||||||
@@ -347,28 +212,25 @@ const queryParams = reactive({
|
|||||||
const detailVisible = ref(false);
|
const detailVisible = ref(false);
|
||||||
const detailMode = ref('view');
|
const detailMode = ref('view');
|
||||||
const currentCard = ref({});
|
const currentCard = ref({});
|
||||||
const editForm = reactive({});
|
|
||||||
const editFormRef = ref(null);
|
|
||||||
|
|
||||||
// 编辑表单验证规则
|
// 计算表格高度:根据视口高度动态调整
|
||||||
const editFormRules = {
|
const tableHeight = computed(() => {
|
||||||
phone: [
|
// 视口高度 - 顶部导航(约60px) - 标题(40px) - 统计卡片(120px) - 筛选区(100px)
|
||||||
{ required: true, message: '请输入联系电话', trigger: 'blur' },
|
// - 分页(60px) - 底部操作栏(60px) - 上下边距(80px) - 额外缓冲(20px)
|
||||||
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
|
return window.innerHeight - 540;
|
||||||
],
|
});
|
||||||
diagDate: [
|
|
||||||
{ required: true, message: '请选择诊断日期', trigger: 'change' }
|
// 监听窗口大小变化,确保表格高度自适应
|
||||||
]
|
let resizeObserver = null;
|
||||||
};
|
|
||||||
|
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
'0': { name: '待提交', type: 'warning' },
|
0: { name: '待提交', type: 'warning' },
|
||||||
'1': { name: '已提交', type: 'primary' },
|
1: { name: '已提交', type: 'primary' },
|
||||||
'2': { name: '已审核', type: 'success' },
|
2: { name: '已审核', type: 'success' },
|
||||||
'3': { name: '已上报', type: 'success' },
|
3: { name: '已上报', type: 'success' },
|
||||||
'4': { name: '失败', type: 'danger' },
|
4: { name: '失败', type: 'danger' },
|
||||||
'5': { name: '退回', type: 'danger' },
|
5: { name: '退回', type: 'danger' },
|
||||||
'6': { name: '作废', type: 'info' },
|
6: { name: '作废', type: 'info' },
|
||||||
};
|
};
|
||||||
|
|
||||||
const ageUnitMap = {
|
const ageUnitMap = {
|
||||||
@@ -454,11 +316,11 @@ function handleSelectionChange(selection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleSelectAll(val) {
|
function handleSelectAll(val) {
|
||||||
if (val) {
|
nextTick(() => {
|
||||||
selectedRows.value = [...cardList.value];
|
if (tableRef.value) {
|
||||||
} else {
|
tableRef.value.toggleAllSelection();
|
||||||
selectedRows.value = [];
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleView(row) {
|
async function handleView(row) {
|
||||||
@@ -478,7 +340,7 @@ async function handleEdit(row) {
|
|||||||
try {
|
try {
|
||||||
const res = await getCardDetail(row.cardNo);
|
const res = await getCardDetail(row.cardNo);
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
Object.assign(editForm, res.data || {});
|
currentCard.value = res.data || {};
|
||||||
detailMode.value = 'edit';
|
detailMode.value = 'edit';
|
||||||
detailVisible.value = true;
|
detailVisible.value = true;
|
||||||
}
|
}
|
||||||
@@ -487,26 +349,33 @@ async function handleEdit(row) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSaveEdit() {
|
async function handleSaveEdit(submitData) {
|
||||||
// 验证表单
|
// submitData 来自 InfectiousReport 组件的 submit-edit 事件
|
||||||
try {
|
|
||||||
await editFormRef.value.validate();
|
|
||||||
} catch (error) {
|
|
||||||
ElMessage.error('表单验证失败,请检查输入');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const updateData = {
|
const updateData = {
|
||||||
cardNo: editForm.cardNo,
|
cardNo: submitData.cardNo,
|
||||||
phone: editForm.phone,
|
phone: submitData.phone,
|
||||||
onsetDate: editForm.onsetDate,
|
contactPhone: submitData.contactPhone,
|
||||||
diagDate: editForm.diagDate,
|
onsetDate: submitData.onsetDate,
|
||||||
diseaseType: editForm.diseaseType,
|
diagDate: submitData.diagDate,
|
||||||
addressProv: editForm.addressProv,
|
diseaseCode: submitData.diseaseCode,
|
||||||
addressCity: editForm.addressCity,
|
diseaseType: submitData.diseaseType,
|
||||||
addressCounty: editForm.addressCounty,
|
otherDisease: submitData.otherDisease,
|
||||||
addressHouse: editForm.addressHouse,
|
caseClass: submitData.caseClass,
|
||||||
|
occupation: submitData.occupation,
|
||||||
|
patientBelong: submitData.patientBelong,
|
||||||
|
addressProv: submitData.addressProv,
|
||||||
|
addressCity: submitData.addressCity,
|
||||||
|
addressCounty: submitData.addressCounty,
|
||||||
|
addressTown: submitData.addressTown,
|
||||||
|
addressVillage: submitData.addressVillage,
|
||||||
|
addressHouse: submitData.addressHouse,
|
||||||
|
workplace: submitData.workplace,
|
||||||
|
parentName: submitData.parentName,
|
||||||
|
deathDate: submitData.deathDate,
|
||||||
|
correctName: submitData.correctName,
|
||||||
|
withdrawReason: submitData.withdrawReason,
|
||||||
|
remark: submitData.remark,
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await updateDoctorCard(updateData);
|
const res = await updateDoctorCard(updateData);
|
||||||
@@ -567,7 +436,7 @@ async function handleWithdraw(row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleBatchSubmit() {
|
async function handleBatchSubmit() {
|
||||||
const validRows = selectedRows.value.filter(row => row.status === '0');
|
const validRows = selectedRows.value.filter(row => row.status == 0);
|
||||||
if (validRows.length === 0) {
|
if (validRows.length === 0) {
|
||||||
ElMessage.warning('只能提交待提交状态的报卡');
|
ElMessage.warning('只能提交待提交状态的报卡');
|
||||||
return;
|
return;
|
||||||
@@ -595,7 +464,7 @@ async function handleBatchSubmit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleBatchDelete() {
|
async function handleBatchDelete() {
|
||||||
const validRows = selectedRows.value.filter(row => row.status === '0');
|
const validRows = selectedRows.value.filter(row => row.status == 0);
|
||||||
if (validRows.length === 0) {
|
if (validRows.length === 0) {
|
||||||
ElMessage.warning('只能删除待提交状态的报卡');
|
ElMessage.warning('只能删除待提交状态的报卡');
|
||||||
return;
|
return;
|
||||||
@@ -638,9 +507,35 @@ async function handleExport(row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
console.log('页面首次加载 - onMounted');
|
||||||
|
getStatistics();
|
||||||
|
getList();
|
||||||
|
|
||||||
|
// 添加窗口大小变化监听
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理 keep-alive 缓存场景:从其他页面返回时重新加载数据
|
||||||
|
onActivated(() => {
|
||||||
|
console.log('页面被激活 - onActivated');
|
||||||
getStatistics();
|
getStatistics();
|
||||||
getList();
|
getList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 组件卸载时移除事件监听
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 窗口大小变化处理函数
|
||||||
|
function handleResize() {
|
||||||
|
// 触发计算属性重新计算
|
||||||
|
nextTick(() => {
|
||||||
|
if (tableRef.value) {
|
||||||
|
tableRef.value.doLayout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -648,109 +543,274 @@ onMounted(() => {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
background-color: #f5f7fa;
|
background-color: #f5f7fa;
|
||||||
min-height: calc(100vh - 84px);
|
min-height: calc(100vh - 84px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 页面标题 */
|
||||||
.page-header {
|
.page-header {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
.page-title {
|
||||||
.page-header h2 {
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #1e293b;
|
color: #1e293b;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 统计卡片区 */
|
||||||
.statistics-section {
|
.statistics-section {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 20px;
|
gap: 16px;
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card {
|
.stat-card {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: #fff;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 24px;
|
padding: 20px 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
color: #fff;
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
|
||||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
border: 1px solid #f0f0f0;
|
||||||
|
transition: box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
.stat-card:hover {
|
||||||
|
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card.pending {
|
/* 图标容器 */
|
||||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
.stat-icon-wrap {
|
||||||
box-shadow: 0 4px 12px rgba(245, 87, 108, 0.3);
|
width: 52px;
|
||||||
}
|
height: 52px;
|
||||||
|
border-radius: 50%;
|
||||||
.stat-card.success {
|
|
||||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
|
||||||
box-shadow: 0 4px 12px rgba(0, 242, 254, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-icon {
|
|
||||||
width: 56px;
|
|
||||||
height: 56px;
|
|
||||||
background: rgba(255, 255, 255, 0.2);
|
|
||||||
border-radius: 12px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 28px;
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.stat-icon-purple {
|
||||||
|
background: linear-gradient(135deg, #818cf8 0%, #6366f1 100%);
|
||||||
|
}
|
||||||
|
.stat-icon-red {
|
||||||
|
background: linear-gradient(135deg, #fca5a5 0%, #ef4444 100%);
|
||||||
|
}
|
||||||
|
.stat-icon-green {
|
||||||
|
background: linear-gradient(135deg, #6ee7b7 0%, #10b981 100%);
|
||||||
|
}
|
||||||
|
.stat-icon-inner {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-content {
|
.stat-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 32px;
|
font-size: 28px;
|
||||||
font-weight: bold;
|
font-weight: 700;
|
||||||
|
color: #1e293b;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-label {
|
.stat-label {
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
opacity: 0.9;
|
color: #64748b;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 高级筛选区 */
|
||||||
.filter-section {
|
.filter-section {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 16px 20px;
|
padding: 16px 20px;
|
||||||
margin-bottom: 16px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
|
.filter-title {
|
||||||
.action-section {
|
font-size: 14px;
|
||||||
background: #fff;
|
font-weight: 600;
|
||||||
border-radius: 8px;
|
color: #1e293b;
|
||||||
padding: 12px 20px;
|
margin-bottom: 14px;
|
||||||
margin-bottom: 16px;
|
}
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
.filter-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
flex-wrap: wrap;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.filter-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.filter-label {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #475569;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.filter-date-picker {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
.filter-select {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
.filter-input {
|
||||||
|
width: 180px;
|
||||||
|
}
|
||||||
|
.filter-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
.btn-apply {
|
||||||
|
background-color: #6366f1;
|
||||||
|
border-color: #6366f1;
|
||||||
|
}
|
||||||
|
.btn-apply:hover {
|
||||||
|
background-color: #4f46e5;
|
||||||
|
border-color: #4f46e5;
|
||||||
|
}
|
||||||
|
.btn-reset {
|
||||||
|
color: #475569;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 表格区 */
|
||||||
.table-section {
|
.table-section {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 状态标签 */
|
||||||
|
.status-tag {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
/* 已上报 - 绿 */
|
||||||
|
.status-3 {
|
||||||
|
color: #16a34a;
|
||||||
|
background: #dcfce7;
|
||||||
|
border: 1px solid #bbf7d0;
|
||||||
|
}
|
||||||
|
/* 已审核 - 蓝 */
|
||||||
|
.status-2 {
|
||||||
|
color: #2563eb;
|
||||||
|
background: #dbeafe;
|
||||||
|
border: 1px solid #bfdbfe;
|
||||||
|
}
|
||||||
|
/* 失败 - 红 */
|
||||||
|
.status-4 {
|
||||||
|
color: #dc2626;
|
||||||
|
background: #fee2e2;
|
||||||
|
border: 1px solid #fecaca;
|
||||||
|
}
|
||||||
|
/* 已提交 - 绿 */
|
||||||
|
.status-1 {
|
||||||
|
color: #16a34a;
|
||||||
|
background: #dcfce7;
|
||||||
|
border: 1px solid #bbf7d0;
|
||||||
|
}
|
||||||
|
/* 待提交 - 橙 */
|
||||||
|
.status-0 {
|
||||||
|
color: #d97706;
|
||||||
|
background: #fef3c7;
|
||||||
|
border: 1px solid #fde68a;
|
||||||
|
}
|
||||||
|
/* 作废 - 灰 */
|
||||||
|
.status-6 {
|
||||||
|
color: #64748b;
|
||||||
|
background: #f1f5f9;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
/* 退回 - 红 */
|
||||||
|
.status-5 {
|
||||||
|
color: #dc2626;
|
||||||
|
background: #fee2e2;
|
||||||
|
border: 1px solid #fecaca;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分页 */
|
||||||
.pagination-section {
|
.pagination-section {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 底部批量操作栏 */
|
||||||
|
.bottom-action-bar {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px 20px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.bottom-action-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.selected-info {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
.bottom-action-right {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.btn-batch-delete {
|
||||||
|
color: #dc2626;
|
||||||
|
border-color: #fecaca;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.btn-batch-delete:hover {
|
||||||
|
background: #fee2e2;
|
||||||
|
border-color: #fca5a5;
|
||||||
|
}
|
||||||
|
.btn-batch-submit {
|
||||||
|
background-color: #6366f1;
|
||||||
|
border-color: #6366f1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.btn-batch-submit:hover {
|
||||||
|
background-color: #4f46e5;
|
||||||
|
border-color: #4f46e5;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 992px) {
|
@media (max-width: 992px) {
|
||||||
.statistics-section {
|
.statistics-section {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
.filter-row {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.filter-actions {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 报卡详情弹窗 */
|
||||||
|
:deep(.card-detail-dialog .el-dialog__body) {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.card-detail-dialog .infectious-report-container) {
|
||||||
|
padding: 16px;
|
||||||
|
height: auto;
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user