Merge branch 'develop' of http://192.168.110.253:3000/wangyizhe/his into develop
This commit is contained in:
@@ -1 +1,2 @@
|
||||
陈琳Git提交测试 - 2026-04-14 16:57:08
|
||||
陈琳二次测试 - 2026-04-14 21:35:12
|
||||
|
||||
1
git_test3.md
Normal file
1
git_test3.md
Normal file
@@ -0,0 +1 @@
|
||||
# Git 代理禁用后测试 - 关羽 2026-04-14 17:11:41
|
||||
1
git_test4.md
Normal file
1
git_test4.md
Normal file
@@ -0,0 +1 @@
|
||||
# Git 晚间测试 - 关羽 2026-04-14 21:35:44
|
||||
@@ -12,6 +12,8 @@ import com.core.common.utils.SecurityUtils;
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
import com.openhis.infectious.domain.InfectiousAudit;
|
||||
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.dto.*;
|
||||
import com.openhis.web.cardmanagement.mapper.InfectiousAuditMapper;
|
||||
@@ -52,6 +54,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
|
||||
private final InfectiousCardMapper infectiousCardMapper;
|
||||
private final InfectiousAuditMapper infectiousAuditMapper;
|
||||
private final IPractitionerService iPractitionerService;
|
||||
|
||||
@Override
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -127,7 +130,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
if (card == null) {
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -145,16 +148,16 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
for (String cardNo : batchAuditDto.getCardNos()) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
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();
|
||||
card.setStatus("2");
|
||||
Integer oldStatus = card.getStatus();
|
||||
card.setStatus(2);
|
||||
card.setUpdateTime(new Date());
|
||||
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());
|
||||
successCount++;
|
||||
}
|
||||
@@ -176,17 +179,17 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
for (String cardNo : batchReturnDto.getCardNos()) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
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();
|
||||
card.setStatus("5");
|
||||
Integer oldStatus = card.getStatus();
|
||||
card.setStatus(5);
|
||||
card.setReturnReason(batchReturnDto.getReturnReason());
|
||||
card.setUpdateTime(new Date());
|
||||
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());
|
||||
successCount++;
|
||||
}
|
||||
@@ -206,13 +209,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
String auditorName = SecurityUtils.getUsername();
|
||||
|
||||
// 更新状态
|
||||
String oldStatus = card.getStatus();
|
||||
card.setStatus("2");
|
||||
Integer oldStatus = card.getStatus();
|
||||
card.setStatus(2);
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
|
||||
// 创建审核记录
|
||||
createAuditRecord(card.getId(), oldStatus, "2", "2", auditDto.getAuditOpinion(),
|
||||
createAuditRecord(card.getCardNo(), oldStatus, 2, 2, auditDto.getAuditOpinion(),
|
||||
null, auditorId, auditorName, false, 1);
|
||||
|
||||
return R.ok("审核通过");
|
||||
@@ -230,14 +233,14 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
String auditorName = SecurityUtils.getUsername();
|
||||
|
||||
// 更新状态
|
||||
String oldStatus = card.getStatus();
|
||||
card.setStatus("5");
|
||||
Integer oldStatus = card.getStatus();
|
||||
card.setStatus(5);
|
||||
card.setReturnReason(returnDto.getReturnReason());
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
|
||||
// 创建审核记录
|
||||
createAuditRecord(card.getId(), oldStatus, "5", "4", null,
|
||||
createAuditRecord(card.getCardNo(), oldStatus, 5, 4, null,
|
||||
returnDto.getReturnReason(), auditorId, auditorName, false, 1);
|
||||
|
||||
return R.ok("已退回");
|
||||
@@ -251,7 +254,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
if (queryParams.getRegistrationSource() != null) {
|
||||
wrapper.eq(InfectiousCard::getRegistrationSource, queryParams.getRegistrationSource());
|
||||
}
|
||||
if (StringUtils.hasText(queryParams.getStatus())) {
|
||||
if (queryParams.getStatus() != null) {
|
||||
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
||||
}
|
||||
if (StringUtils.hasText(queryParams.getPatientName())) {
|
||||
@@ -292,7 +295,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
row.createCell(1).setCellValue(card.getPatName());
|
||||
row.createCell(2).setCellValue("1".equals(card.getSex()) ? "男" : "2".equals(card.getSex()) ? "女" : "未知");
|
||||
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(6).setCellValue(card.getCreateTime() != null ? dateFormat.format(card.getCreateTime()) : "");
|
||||
row.createCell(7).setCellValue(getStatusText(card.getStatus()));
|
||||
@@ -316,7 +319,19 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
|
||||
@Override
|
||||
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();
|
||||
Integer totalCount = infectiousCardMapper.countByDoctorId(doctorId);
|
||||
@@ -331,7 +346,18 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
|
||||
@Override
|
||||
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());
|
||||
LambdaQueryWrapper<InfectiousCard> wrapper = new LambdaQueryWrapper<>();
|
||||
@@ -340,7 +366,7 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
wrapper.eq(InfectiousCard::getDoctorId, doctorId);
|
||||
|
||||
// 状态筛选
|
||||
if (StringUtils.hasText(queryParams.getStatus())) {
|
||||
if (queryParams.getStatus() != null) {
|
||||
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
||||
}
|
||||
|
||||
@@ -354,13 +380,24 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
wrapper.le(InfectiousCard::getCreateTime, endDateTime);
|
||||
}
|
||||
|
||||
// 关键词搜索(患者姓名或报卡名称)
|
||||
// 关键词搜索(患者姓名、疾病编码、报卡名称)
|
||||
if (StringUtils.hasText(queryParams.getKeyword())) {
|
||||
wrapper.and(w -> w
|
||||
.like(InfectiousCard::getPatName, queryParams.getKeyword())
|
||||
.or()
|
||||
.like(InfectiousCard::getDiseaseName, queryParams.getKeyword())
|
||||
);
|
||||
String kw = queryParams.getKeyword();
|
||||
// 将关键词匹配报卡名称,找出对应的 cardNameCode 列表
|
||||
List<Integer> matchedCodes = getMatchedCardNameCodes(kw);
|
||||
// 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("无权操作此报卡");
|
||||
}
|
||||
|
||||
// 验证状态:只有暂存状态可以提交
|
||||
if (!"0".equals(card.getStatus())) {
|
||||
// 狋证状态:只有暂存状态可以提交
|
||||
if (!Integer.valueOf(0).equals(card.getStatus())) {
|
||||
return R.fail("只能提交暂存状态的报卡");
|
||||
}
|
||||
|
||||
|
||||
// 更新状态为已提交
|
||||
card.setStatus("1");
|
||||
card.setStatus(1);
|
||||
card.setUpdateTime(new Date());
|
||||
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("无权操作此报卡");
|
||||
}
|
||||
|
||||
// 验证状态:只有已提交状态可以撤回
|
||||
if (!"1".equals(card.getStatus())) {
|
||||
// 狋证状态:只有已提交状态可以撤回
|
||||
if (!Integer.valueOf(1).equals(card.getStatus())) {
|
||||
return R.fail("只能撤回已提交状态的报卡");
|
||||
}
|
||||
|
||||
|
||||
// 更新状态为暂存
|
||||
card.setStatus("0");
|
||||
card.setStatus(0);
|
||||
card.setUpdateTime(new Date());
|
||||
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("无权操作此报卡");
|
||||
}
|
||||
|
||||
// 验证状态:只有暂存状态可以删除
|
||||
if (!"0".equals(card.getStatus())) {
|
||||
// 狋证状态:只有暂存状态可以删除
|
||||
if (!Integer.valueOf(0).equals(card.getStatus())) {
|
||||
return R.fail("只能删除暂存状态的报卡");
|
||||
}
|
||||
|
||||
|
||||
// 更新状态为作废
|
||||
card.setStatus("6");
|
||||
card.setStatus(6);
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
|
||||
@@ -464,7 +507,12 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
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;
|
||||
|
||||
for (String cardNo : cardNos) {
|
||||
@@ -472,13 +520,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
if (card == null) continue;
|
||||
|
||||
// 验证权限:只能提交自己的报卡
|
||||
if (!card.getDoctorId().equals(doctorId)) continue;
|
||||
|
||||
// 验证状态:只有暂存状态可以提交
|
||||
if (!"0".equals(card.getStatus())) continue;
|
||||
if (!doctorId.equals(card.getDoctorId())) continue;
|
||||
|
||||
// 狋证状态:只有暂存状态可以提交
|
||||
if (!Integer.valueOf(0).equals(card.getStatus())) continue;
|
||||
|
||||
// 更新状态为已提交
|
||||
card.setStatus("1");
|
||||
card.setStatus(1);
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
successCount++;
|
||||
@@ -498,7 +546,12 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
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;
|
||||
|
||||
for (String cardNo : cardNos) {
|
||||
@@ -506,13 +559,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
if (card == null) continue;
|
||||
|
||||
// 验证权限:只能删除自己的报卡
|
||||
if (!card.getDoctorId().equals(doctorId)) continue;
|
||||
|
||||
// 验证状态:只有暂存状态可以删除
|
||||
if (!"0".equals(card.getStatus())) continue;
|
||||
if (!doctorId.equals(card.getDoctorId())) continue;
|
||||
|
||||
// 狋证状态:只有暂存状态可以删除
|
||||
if (!Integer.valueOf(0).equals(card.getStatus())) continue;
|
||||
|
||||
// 更新状态为作废
|
||||
card.setStatus("6");
|
||||
card.setStatus(6);
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
successCount++;
|
||||
@@ -530,6 +583,13 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
// 获取当前登录用户信息
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
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());
|
||||
@@ -538,12 +598,12 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
}
|
||||
|
||||
// 验证是否当前医生的报卡 - 根据 doctorId 字段验证
|
||||
if (!currentUserId.equals(card.getDoctorId())) {
|
||||
if (!doctorId.equals(card.getDoctorId())) {
|
||||
return R.fail("只能修改自己的报卡");
|
||||
}
|
||||
|
||||
// 验证状态是否允许修改(只能修改暂存状态的报卡)
|
||||
if (!"0".equals(card.getStatus())) {
|
||||
// 狋证状态是否允许修改(只能修改暂存状态的报卡)
|
||||
if (!Integer.valueOf(0).equals(card.getStatus())) {
|
||||
return R.fail("只能修改暂存状态的报卡");
|
||||
}
|
||||
|
||||
@@ -559,15 +619,6 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
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 作为更新者
|
||||
|
||||
card.setUpdateTime(new Date());
|
||||
card.setUpdateBy(loginUser.getUsername()); // 使用 username 作为更新者
|
||||
|
||||
int rows = infectiousCardMapper.updateById(card);
|
||||
if (rows > 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 验证状态:只有已上报状态可以导出
|
||||
if (!"3".equals(card.getStatus())) {
|
||||
// 狋证状态:只有已上报状态可以导出
|
||||
if (!Integer.valueOf(3).equals(card.getStatus())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -612,6 +665,8 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
private DoctorCardListDto convertToDoctorCardListDto(InfectiousCard card) {
|
||||
DoctorCardListDto dto = new DoctorCardListDto();
|
||||
BeanUtils.copyProperties(card, dto);
|
||||
// 由于数据库中没有 disease_name 字段,使用 disease_code 作为疾病名称展示
|
||||
dto.setDiseaseName(card.getDiseaseCode());
|
||||
dto.setCardName(getCardName(card.getCardNameCode()));
|
||||
dto.setSubmitTime(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
|
||||
*/
|
||||
private AuditRecordDto convertAuditToDto(InfectiousAudit audit) {
|
||||
AuditRecordDto dto = new AuditRecordDto();
|
||||
BeanUtils.copyProperties(audit, dto);
|
||||
dto.setCardId(audit.getCardId() != null ? audit.getCardId().toString() : null);
|
||||
dto.setCardId(audit.getCardId());
|
||||
return dto;
|
||||
}
|
||||
|
||||
@@ -648,6 +725,8 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
private InfectiousCardDto convertToDto(InfectiousCard card) {
|
||||
InfectiousCardDto dto = new InfectiousCardDto();
|
||||
BeanUtils.copyProperties(card, dto);
|
||||
// 由于数据库中没有 disease_name 字段,使用 disease_code 作为疾病名称展示
|
||||
dto.setDiseaseName(card.getDiseaseCode());
|
||||
dto.setStatusText(getStatusText(card.getStatus()));
|
||||
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,
|
||||
Boolean isBatch, Integer batchSize) {
|
||||
InfectiousAudit audit = new InfectiousAudit();
|
||||
audit.setCardId(cardId);
|
||||
audit.setAuditSeq(infectiousAuditMapper.getNextAuditSeq(cardId));
|
||||
audit.setAuditType(auditType);
|
||||
audit.setAuditStatusFrom(statusFrom);
|
||||
audit.setAuditStatusTo(statusTo);
|
||||
audit.setAuditType(String.valueOf(auditType));
|
||||
audit.setAuditStatusFrom(statusFrom != null ? String.valueOf(statusFrom) : null);
|
||||
audit.setAuditStatusTo(statusTo != null ? String.valueOf(statusTo) : null);
|
||||
audit.setAuditTime(LocalDateTime.now());
|
||||
audit.setAuditorId(auditorId);
|
||||
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) {
|
||||
case "0": return "暂存";
|
||||
case "1": return "已提交";
|
||||
case "2": return "审核通过";
|
||||
case "3": return "已上报";
|
||||
case "4": return "失败";
|
||||
case "5": return "审核失败";
|
||||
case "6": return "作废";
|
||||
case 0: return "暂存";
|
||||
case 1: return "已提交";
|
||||
case 2: return "审核通过";
|
||||
case 3: return "已上报";
|
||||
case 4: return "失败";
|
||||
case 5: return "审核失败";
|
||||
case 6: return "作废";
|
||||
default: return "未知";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ public class CardQueryDto {
|
||||
/** 患者姓名 */
|
||||
private String patientName;
|
||||
|
||||
/** 审核状态 */
|
||||
private String status;
|
||||
/** 审核状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||
private Integer status;
|
||||
|
||||
/** 科室ID */
|
||||
private Long deptId;
|
||||
|
||||
@@ -7,6 +7,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 医生个人报卡列表DTO
|
||||
*
|
||||
@@ -41,6 +44,51 @@ public class DoctorCardListDto {
|
||||
/** 提交时间 */
|
||||
private String submitTime;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||
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;
|
||||
|
||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回) */
|
||||
private String status;
|
||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||
private Integer status;
|
||||
|
||||
/** 患者姓名或报卡名称 */
|
||||
private String keyword;
|
||||
|
||||
@@ -1,18 +1,44 @@
|
||||
package com.openhis.web.cardmanagement.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class DoctorCardUpdateDto {
|
||||
@NotBlank(message = "卡片编号不能为空")
|
||||
private String cardNo;
|
||||
|
||||
private String phone;
|
||||
private String contactPhone; // 紧急联系人电话
|
||||
|
||||
private LocalDate onsetDate;
|
||||
private LocalDateTime diagDate;
|
||||
private String diseaseType; // 修改为diseaseType,对应InfectiousCard中的diseaseType字段
|
||||
private String addressProv;
|
||||
private String addressCity;
|
||||
private String addressCounty;
|
||||
private String addressHouse;
|
||||
|
||||
private String diseaseType; // 病例分类(对应InfectiousCard中的diseaseType字段)
|
||||
private String diseaseCode; // 疾病编码
|
||||
|
||||
@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 patientbelong;
|
||||
/** 病人属于(1本县区/2本市其他县区/3本省其他地市/4外省/5港澳台/6外籍) */
|
||||
private Integer patientBelong;
|
||||
|
||||
/** 职业 */
|
||||
private String occupation;
|
||||
@@ -110,8 +110,8 @@ public class InfectiousCardDto {
|
||||
/** 填卡日期 */
|
||||
private LocalDate reportDate;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回/6作废) */
|
||||
private Integer status;
|
||||
|
||||
/** 状态文本 */
|
||||
private String statusText;
|
||||
|
||||
@@ -18,14 +18,14 @@ import java.util.List;
|
||||
public interface InfectiousAuditMapper extends BaseMapper<InfectiousAudit> {
|
||||
|
||||
/**
|
||||
* 根据报卡ID查询审核记录
|
||||
* 根据报卡编号查询审核记录
|
||||
*/
|
||||
@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}")
|
||||
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();
|
||||
|
||||
/**
|
||||
* 统计本月审核失败数量
|
||||
*/
|
||||
@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();
|
||||
|
||||
/**
|
||||
* 统计本月审核成功数量
|
||||
*/
|
||||
@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();
|
||||
|
||||
/**
|
||||
* 统计本月已上报数量
|
||||
*/
|
||||
@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();
|
||||
|
||||
/**
|
||||
@@ -55,14 +55,14 @@ public interface InfectiousCardMapper extends BaseMapper<InfectiousCard> {
|
||||
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);
|
||||
|
||||
/**
|
||||
* 统计医生已成功上报数(状态为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);
|
||||
}
|
||||
|
||||
@@ -127,14 +127,11 @@ public class InfectiousCardDto {
|
||||
/** 审核意见 */
|
||||
private String auditOpinion;
|
||||
|
||||
/** 退回原因 */
|
||||
/** 退卡原因 */
|
||||
private String returnReason;
|
||||
|
||||
/** 订正病名 */
|
||||
private String correctName;
|
||||
|
||||
/** 退卡原因 */
|
||||
private String withdrawReason;
|
||||
private String revisedDiseaseName;
|
||||
|
||||
/** 其他传染病 */
|
||||
private String otherDisease;
|
||||
|
||||
@@ -29,9 +29,8 @@ public class InfectiousAudit extends HisBaseEntity {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long auditId;
|
||||
|
||||
/** 报卡ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long cardId;
|
||||
/** 报卡编号(关联 infectious_card.card_no) */
|
||||
private String cardId;
|
||||
|
||||
/** 审核序号 */
|
||||
private Integer auditSeq;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.infectious.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
@@ -26,12 +27,8 @@ import java.time.LocalDateTime;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class InfectiousCard extends HisBaseEntity {
|
||||
|
||||
/** 卡片编号 */
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/** 卡片编号(业务编号) */
|
||||
/** 卡片编号(业务编号,主键) */
|
||||
@TableId(type = IdType.INPUT)
|
||||
private String cardNo;
|
||||
|
||||
/** 本次就诊ID */
|
||||
@@ -97,8 +94,9 @@ public class InfectiousCard extends HisBaseEntity {
|
||||
/** 现住址门牌号 */
|
||||
private String addressHouse;
|
||||
|
||||
/** 病人属于 */
|
||||
private String patientbelong;
|
||||
/** 病人属于(1本县区/2本市其他县区/3本省其他地市/4外省/5港澳台/6外籍) */
|
||||
@TableField("patient_belong")
|
||||
private Integer patientBelong;
|
||||
|
||||
/** 职业 */
|
||||
private String occupation;
|
||||
@@ -106,18 +104,15 @@ public class InfectiousCard extends HisBaseEntity {
|
||||
/** 疾病编码 */
|
||||
private String diseaseCode;
|
||||
|
||||
/** 疾病名称 */
|
||||
private String diseaseName;
|
||||
|
||||
/** 分型 */
|
||||
private String diseaseSubtype;
|
||||
|
||||
/** 其他传染病 */
|
||||
private String otherDisease;
|
||||
|
||||
/** 病例分类 */
|
||||
private String diseaseType;
|
||||
|
||||
/** 其他传染病名称 */
|
||||
private String otherDisease;
|
||||
|
||||
/** 病例类别(1疑似病例/2临床诊断病例/3实验室确诊病例/4病原携带者/5阳性检测结果) */
|
||||
private Integer caseClass;
|
||||
|
||||
/** 发病日期 */
|
||||
private LocalDate onsetDate;
|
||||
|
||||
@@ -146,7 +141,7 @@ public class InfectiousCard extends HisBaseEntity {
|
||||
private LocalDate reportDate;
|
||||
|
||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回) */
|
||||
private String status;
|
||||
private Integer status;
|
||||
|
||||
/** 失败原因 */
|
||||
private String failMsg;
|
||||
@@ -165,6 +160,7 @@ public class InfectiousCard extends HisBaseEntity {
|
||||
private Long deptId;
|
||||
|
||||
/** 科室名称 */
|
||||
@TableField(exist = false)
|
||||
private String deptName;
|
||||
|
||||
/** 医生ID */
|
||||
|
||||
@@ -334,12 +334,12 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="病人属于">
|
||||
<el-select v-model="currentCard.patientBelong" :disabled="drawerMode !== 'edit'" style="width: 100%">
|
||||
<el-option label="本县区" value="1" />
|
||||
<el-option label="本市其他县区" value="2" />
|
||||
<el-option label="本省其他地市" value="3" />
|
||||
<el-option label="外省" value="4" />
|
||||
<el-option label="港澳台" value="5" />
|
||||
<el-option label="外籍" value="6" />
|
||||
<el-option label="本县区" :value="1" />
|
||||
<el-option label="本市其他县区" :value="2" />
|
||||
<el-option label="本省其他地市" :value="3" />
|
||||
<el-option label="外省" :value="4" />
|
||||
<el-option label="港澳台" :value="5" />
|
||||
<el-option label="外籍" :value="6" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
@@ -130,12 +130,12 @@
|
||||
<el-col :span="24" class="form-item full-width">
|
||||
<span class="form-label required">病人属于</span>
|
||||
<el-radio-group v-model="form.patientBelong">
|
||||
<el-radio label="1">本县区</el-radio>
|
||||
<el-radio label="2">本市其他县区</el-radio>
|
||||
<el-radio label="3">本省其他地市</el-radio>
|
||||
<el-radio label="4">外省</el-radio>
|
||||
<el-radio label="5">港澳台</el-radio>
|
||||
<el-radio label="6">外籍</el-radio>
|
||||
<el-radio :label="1">本县区</el-radio>
|
||||
<el-radio :label="2">本市其他县区</el-radio>
|
||||
<el-radio :label="3">本省其他地市</el-radio>
|
||||
<el-radio :label="4">外省</el-radio>
|
||||
<el-radio :label="5">港澳台</el-radio>
|
||||
<el-radio :label="6">外籍</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -732,7 +732,7 @@ const form = ref({
|
||||
addressTown: '',
|
||||
addressVillage: '',
|
||||
addressHouse: '',
|
||||
patientBelong: '1',
|
||||
patientBelong: 1,
|
||||
occupation: '',
|
||||
caseClass: '',
|
||||
onsetDate: '',
|
||||
@@ -1186,7 +1186,7 @@ function show(diagnosisData) {
|
||||
addressHouse: diagnosisData?.addressHouse || '', // 门牌号
|
||||
|
||||
// 患者类型和职业
|
||||
patientBelong: '1', // 患者属于(本县区/本市其他县区/本省其他地市/外省/港澳台/外籍)
|
||||
patientBelong: 1, // 患者属于(本县区/本市其他县区/本省其他地市/外省/港澳台/外籍)
|
||||
occupation: '', // 职业
|
||||
caseClass: '', // 病例分类(疑似病例/临床诊断病例/确诊病例/病原携带者/阳性检测)
|
||||
|
||||
@@ -1297,7 +1297,7 @@ async function buildSubmitData() {
|
||||
addressTown: formData.addressTown || '',
|
||||
addressVillage: formData.addressVillage || '',
|
||||
addressHouse: formData.addressHouse || '',
|
||||
patientBelong: patientBelongMap[formData.patientBelong] || 1,
|
||||
patientBelong: formData.patientBelong || 1,
|
||||
occupation: formData.occupation || null,
|
||||
diseaseCode: diseaseCode || null,
|
||||
diseaseType: diseaseType || null,
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<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-col>
|
||||
<el-col :span="8">
|
||||
<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-col>
|
||||
</el-row>
|
||||
@@ -45,7 +45,7 @@
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="6">
|
||||
<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>
|
||||
@@ -55,11 +55,11 @@
|
||||
<el-col :span="10">
|
||||
<el-form-item label="出生日期" required>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
</el-form-item>
|
||||
@@ -67,8 +67,8 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item label="或 实足年龄">
|
||||
<div class="age-inputs">
|
||||
<el-input v-model="form.age" placeholder="年龄" style="width: 100px" />
|
||||
<el-select v-model="form.ageUnit" style="width: 80px">
|
||||
<el-input v-model="form.age" placeholder="年龄" style="width: 100px" :disabled="isReadOnly" />
|
||||
<el-select v-model="form.ageUnit" style="width: 80px" :disabled="isReadOnly">
|
||||
<el-option label="岁" value="岁" />
|
||||
<el-option label="月" value="月" />
|
||||
<el-option label="天" value="天" />
|
||||
@@ -82,7 +82,7 @@
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="工作单位(学校)">
|
||||
<el-input v-model="form.workplace" placeholder="请输入工作单位" />
|
||||
<el-input v-model="form.workplace" placeholder="请输入工作单位" :disabled="isReadOnly" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -91,12 +91,12 @@
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="12">
|
||||
<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-col>
|
||||
<el-col :span="12">
|
||||
<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-col>
|
||||
</el-row>
|
||||
@@ -112,6 +112,7 @@
|
||||
placeholder="请选择省/市/区县/街道"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
:disabled="isReadOnly"
|
||||
@change="handleAddressChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
@@ -119,10 +120,10 @@
|
||||
</el-row>
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="12">
|
||||
<el-input v-model="form.addressVillage" placeholder="村(居)" />
|
||||
<el-input v-model="form.addressVillage" placeholder="村(居)" :disabled="isReadOnly" />
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-input v-model="form.addressHouse" placeholder="门牌号" />
|
||||
<el-input v-model="form.addressHouse" placeholder="门牌号" :disabled="isReadOnly" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -130,13 +131,13 @@
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="病人属于" prop="patientBelong" required>
|
||||
<el-radio-group v-model="form.patientBelong">
|
||||
<el-radio label="1">本县区</el-radio>
|
||||
<el-radio label="2">本市其他县区</el-radio>
|
||||
<el-radio label="3">本省其他地市</el-radio>
|
||||
<el-radio label="4">外省</el-radio>
|
||||
<el-radio label="5">港澳台</el-radio>
|
||||
<el-radio label="6">外籍</el-radio>
|
||||
<el-radio-group v-model="form.patientBelong" :disabled="isReadOnly">
|
||||
<el-radio :label="1">本县区</el-radio>
|
||||
<el-radio :label="2">本市其他县区</el-radio>
|
||||
<el-radio :label="3">本省其他地市</el-radio>
|
||||
<el-radio :label="4">外省</el-radio>
|
||||
<el-radio :label="5">港澳台</el-radio>
|
||||
<el-radio :label="6">外籍</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -146,14 +147,14 @@
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="12">
|
||||
<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-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<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="2">临床诊断病例</el-radio>
|
||||
<el-radio label="3">确诊病例</el-radio>
|
||||
@@ -175,6 +176,7 @@
|
||||
style="width: 100%"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
:disabled="isReadOnly"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -187,6 +189,7 @@
|
||||
style="width: 100%"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
:disabled="isReadOnly"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -199,6 +202,7 @@
|
||||
style="width: 100%"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
:disabled="isReadOnly"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -215,11 +219,13 @@
|
||||
<div class="disease-list">
|
||||
<el-checkbox
|
||||
: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
|
||||
: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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -232,7 +238,8 @@
|
||||
v-for="disease in classBDiseases"
|
||||
:key="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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -245,7 +252,8 @@
|
||||
v-for="disease in classCDiseases"
|
||||
:key="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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -254,12 +262,12 @@
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="showSubtypeSelect ? 16 : 24">
|
||||
<el-form-item label="其他法定管理以及重点监测传染病">
|
||||
<el-input v-model="form.otherDisease" placeholder="手动输入非列表疾病" />
|
||||
<el-input v-model="form.otherDisease" placeholder="手动输入非列表疾病" :disabled="isReadOnly" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="showSubtypeSelect" :span="8">
|
||||
<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
|
||||
v-for="option in currentSubtypeOptions"
|
||||
:key="option.value"
|
||||
@@ -284,7 +292,7 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="联系电话">
|
||||
<el-input v-model="form.reportOrgPhone" placeholder="请输入联系电话" />
|
||||
<el-input v-model="form.reportOrgPhone" placeholder="请输入联系电话" :disabled="isReadOnly" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -304,17 +312,18 @@
|
||||
style="width: 100%"
|
||||
value-format="YYYY-MM-DD"
|
||||
format="YYYY-MM-DD"
|
||||
:disabled="isReadOnly"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="订正病名">
|
||||
<el-input v-model="form.correctName" placeholder="请输入订正病名" />
|
||||
<el-input v-model="form.correctName" placeholder="请输入订正病名" :disabled="isReadOnly" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="退卡原因">
|
||||
<el-input v-model="form.withdrawReason" placeholder="请输入退卡原因" />
|
||||
<el-input v-model="form.withdrawReason" placeholder="请输入退卡原因" :disabled="isReadOnly" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -322,15 +331,15 @@
|
||||
<el-row :gutter="16" class="form-row">
|
||||
<el-col :span="24">
|
||||
<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-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮区 -->
|
||||
<div class="action-buttons">
|
||||
<!-- 操作按钮区(create/edit 模式下显示) -->
|
||||
<div v-if="mode !== 'view'" class="action-buttons">
|
||||
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">保 存</el-button>
|
||||
<el-button @click="handleReset">重 置</el-button>
|
||||
</div>
|
||||
@@ -347,6 +356,9 @@ import { useDict } from '@/utils/dict';
|
||||
const { proxy } = getCurrentInstance();
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 是否只读模式
|
||||
const isReadOnly = computed(() => props.mode === 'view');
|
||||
|
||||
// 获取职业字典数据
|
||||
const { prfs: occupationList } = useDict('prfs');
|
||||
|
||||
@@ -418,9 +430,19 @@ const props = defineProps({
|
||||
type: String,
|
||||
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);
|
||||
@@ -453,7 +475,7 @@ const form = ref({
|
||||
addressTown: '',
|
||||
addressVillage: '',
|
||||
addressHouse: '',
|
||||
patientBelong: '1',
|
||||
patientBelong: 1,
|
||||
occupation: '',
|
||||
caseClass: '',
|
||||
onsetDate: '',
|
||||
@@ -567,19 +589,27 @@ const isChildPatient = computed(() => {
|
||||
|
||||
// 监听疾病选择变化,自动清空分型选择
|
||||
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 = '';
|
||||
}
|
||||
updateSelectedDiseases();
|
||||
}, { deep: true });
|
||||
|
||||
// 监听患者信息变化,自动填充表单
|
||||
// 监听患者信息变化,自动填充表单(仅 create 模式)
|
||||
watch(() => props.patientInfo, (newVal) => {
|
||||
if (newVal && Object.keys(newVal).length > 0) {
|
||||
if (props.mode === 'create' && newVal && Object.keys(newVal).length > 0) {
|
||||
initForm();
|
||||
}
|
||||
}, { deep: true, immediate: true });
|
||||
|
||||
// 监听 cardData 变化,在 view/edit 模式下初始化
|
||||
watch(() => props.cardData, (newVal) => {
|
||||
if ((props.mode === 'view' || props.mode === 'edit') && newVal) {
|
||||
initFormFromCard(newVal);
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
// 监听Tab切换,重新初始化
|
||||
watch(() => props.activeTab, (newVal) => {
|
||||
if (newVal === 'infectiousReport' && props.patientInfo && Object.keys(props.patientInfo).length > 0) {
|
||||
@@ -808,7 +838,7 @@ async function initForm() {
|
||||
addressTown: patientInfo.addressStreet || '',
|
||||
addressVillage: '',
|
||||
addressHouse: '',
|
||||
patientBelong: '1',
|
||||
patientBelong: 1,
|
||||
occupation: '',
|
||||
caseClass: '',
|
||||
onsetDate: getCurrentDate(),
|
||||
@@ -893,7 +923,7 @@ function buildSubmitData() {
|
||||
addressTown: formData.addressTown || '',
|
||||
addressVillage: formData.addressVillage || '',
|
||||
addressHouse: formData.addressHouse || '',
|
||||
patientBelong: parseInt(formData.patientBelong) || 1,
|
||||
patientBelong: formData.patientBelong || 1,
|
||||
occupation: formData.occupation || null,
|
||||
diseaseCode: diseaseCode || null,
|
||||
diseaseType: diseaseType || null,
|
||||
@@ -1015,15 +1045,20 @@ async function handleSubmit() {
|
||||
|
||||
const submitData = buildSubmitData();
|
||||
|
||||
const res = await saveInfectiousDiseaseReport(submitData);
|
||||
|
||||
if (res.code === 200) {
|
||||
proxy.$modal.msgSuccess('传染病报告卡保存成功');
|
||||
emit('saved');
|
||||
// 重新初始化表单,获取新的卡片编号
|
||||
initForm();
|
||||
if (props.mode === 'edit') {
|
||||
// 编辑模式:通过事件通知父组件处理保存
|
||||
emit('submit-edit', submitData);
|
||||
} 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) {
|
||||
console.error('传染病报告卡保存失败:', err);
|
||||
@@ -1065,7 +1100,7 @@ function handleReset() {
|
||||
form.value.contactPhone = '';
|
||||
form.value.occupation = '';
|
||||
form.value.caseClass = '';
|
||||
form.value.patientBelong = '1';
|
||||
form.value.patientBelong = 1;
|
||||
form.value.otherDisease = '';
|
||||
form.value.correctName = '';
|
||||
form.value.withdrawReason = '';
|
||||
@@ -1075,22 +1110,108 @@ function handleReset() {
|
||||
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(() => {
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
// 暴露方法供父组件调用
|
||||
defineExpose({
|
||||
initForm
|
||||
initForm,
|
||||
initFormFromCard
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.infectious-report-container {
|
||||
height: 100%;
|
||||
height: auto;
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
@@ -1130,8 +1251,7 @@ defineExpose({
|
||||
|
||||
/* 表单区域样式 */
|
||||
.report-form {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-y: visible;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,33 @@
|
||||
<template>
|
||||
<div class="my-card-management-container">
|
||||
<!-- 顶部标题 -->
|
||||
<div class="page-header">
|
||||
<h2>我的报卡</h2>
|
||||
<h2 class="page-title">我的报卡</h2>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片区 -->
|
||||
<div class="statistics-section">
|
||||
<div class="stat-card total">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Document /></el-icon>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon-wrap stat-icon-purple">
|
||||
<el-icon class="stat-icon-inner"><DataAnalysis /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ statistics.totalCount || 0 }}</div>
|
||||
<div class="stat-label">总报卡数</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card pending">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Clock /></el-icon>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon-wrap stat-icon-red">
|
||||
<el-icon class="stat-icon-inner"><Warning /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ statistics.pendingFailedCount || 0 }}</div>
|
||||
<div class="stat-label">待处理/失败</div>
|
||||
<div class="stat-label">待提交</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card success">
|
||||
<div class="stat-icon">
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon-wrap stat-icon-green">
|
||||
<el-icon class="stat-icon-inner"><CircleCheck /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ statistics.reportedCount || 0 }}</div>
|
||||
@@ -34,21 +36,25 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 高级筛选区 -->
|
||||
<div class="filter-section">
|
||||
<el-form :model="queryParams" :inline="true">
|
||||
<el-form-item label="日期范围">
|
||||
<div class="filter-title">高级筛选</div>
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">日期范围</span>
|
||||
<el-date-picker
|
||||
v-model="queryParams.dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
start-placeholder="年/月/日"
|
||||
end-placeholder="年/月/日"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 240px"
|
||||
class="filter-date-picker"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="queryParams.status" placeholder="全部状态" clearable style="width: 140px">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">状态</span>
|
||||
<el-select v-model="queryParams.status" placeholder="全部状态" clearable class="filter-select">
|
||||
<el-option label="全部状态" value="" />
|
||||
<el-option label="待提交" value="0" />
|
||||
<el-option label="已提交" value="1" />
|
||||
@@ -57,101 +63,65 @@
|
||||
<el-option label="失败" value="4" />
|
||||
<el-option label="作废" value="6" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关键词">
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">报卡名称</span>
|
||||
<el-input
|
||||
v-model="queryParams.keyword"
|
||||
placeholder="患者姓名/报卡名称"
|
||||
placeholder="输入报卡名称..."
|
||||
clearable
|
||||
style="width: 180px"
|
||||
class="filter-input"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">
|
||||
<el-icon><Search /></el-icon>
|
||||
</div>
|
||||
<div class="filter-actions">
|
||||
<el-button class="btn-apply" type="primary" @click="handleQuery">
|
||||
<el-icon><Check /></el-icon>
|
||||
应用筛选
|
||||
</el-button>
|
||||
<el-button @click="handleReset">
|
||||
<el-icon><Refresh /></el-icon>
|
||||
<el-button class="btn-reset" @click="handleReset">
|
||||
<el-icon><RefreshRight /></el-icon>
|
||||
重置条件
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</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>
|
||||
|
||||
<!-- 数据表格区 -->
|
||||
<div class="table-section">
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
v-loading="loading"
|
||||
:data="cardList"
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
stripe
|
||||
:height="tableHeight"
|
||||
virtualized
|
||||
:virtualized-row-height="48"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="卡片ID" prop="cardNo" min-width="150" />
|
||||
<el-table-column label="患者姓名" prop="patName" width="100" />
|
||||
<el-table-column label="身份证号" prop="idNo" min-width="180" />
|
||||
<el-table-column label="联系电话" prop="phone" width="130" />
|
||||
<el-table-column label="就诊卡号" prop="visitCardNo" width="130" />
|
||||
<el-table-column label="报卡名称" prop="cardName" min-width="200" />
|
||||
<el-table-column label="提交时间" prop="submitTime" width="160" align="center" />
|
||||
<el-table-column label="状态" prop="status" width="100" align="center">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column label="卡片ID" prop="cardNo" min-width="155" />
|
||||
<el-table-column label="患者姓名" prop="patName" width="90" />
|
||||
<el-table-column label="身份证号" prop="idNo" min-width="170" />
|
||||
<el-table-column label="联系电话" prop="phone" width="120" />
|
||||
<el-table-column label="就诊卡号" prop="visitCardNo" width="110" />
|
||||
<el-table-column label="报卡名称" prop="cardName" min-width="120" />
|
||||
<el-table-column label="提交时间" prop="submitTime" width="110" align="center" />
|
||||
<el-table-column label="状态" prop="status" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusType(row.status)" size="small">
|
||||
<span :class="['status-tag', 'status-' + row.status]">
|
||||
{{ getStatusName(row.status) }}
|
||||
</el-tag>
|
||||
</span>
|
||||
</template>
|
||||
</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 }">
|
||||
<el-button type="primary" link size="small" @click="handleView(row)">查看</el-button>
|
||||
<el-button
|
||||
v-if="row.status === '0'"
|
||||
type="primary"
|
||||
link
|
||||
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>
|
||||
<el-button v-if="row.status == 0" type="primary" link 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="primary" link size="small" @click="handleExport(row)">导出</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -169,149 +139,43 @@
|
||||
</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
|
||||
v-model="detailVisible"
|
||||
:title="detailMode === 'view' ? '报卡详情' : '编辑报卡'"
|
||||
width="800px"
|
||||
width="900px"
|
||||
destroy-on-close
|
||||
class="card-detail-dialog"
|
||||
>
|
||||
<el-descriptions v-if="detailMode === 'view'" :column="2" border>
|
||||
<el-descriptions-item label="卡片编号">{{ currentCard.cardNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag :type="getStatusType(currentCard.status)">{{ getStatusName(currentCard.status) }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<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>
|
||||
<InfectiousReport
|
||||
:mode=" detailMode"
|
||||
:card-data="currentCard"
|
||||
@submit-edit="handleSaveEdit"
|
||||
style="max-height: 70vh; overflow-y: auto;"
|
||||
/>
|
||||
<template #footer>
|
||||
<el-button @click="detailVisible = false">取消</el-button>
|
||||
<el-button v-if="detailMode === 'edit'" type="primary" @click="handleSaveEdit">保存</el-button>
|
||||
<el-button @click="detailVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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 { 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 {
|
||||
getDoctorCardStatistics,
|
||||
getDoctorCardList,
|
||||
@@ -329,6 +193,7 @@ const cardList = ref([]);
|
||||
const total = ref(0);
|
||||
const selectedRows = ref([]);
|
||||
const isAllSelected = ref(false);
|
||||
const tableRef = ref(null);
|
||||
|
||||
const statistics = ref({
|
||||
totalCount: 0,
|
||||
@@ -347,28 +212,25 @@ const queryParams = reactive({
|
||||
const detailVisible = ref(false);
|
||||
const detailMode = ref('view');
|
||||
const currentCard = ref({});
|
||||
const editForm = reactive({});
|
||||
const editFormRef = ref(null);
|
||||
|
||||
// 编辑表单验证规则
|
||||
const editFormRules = {
|
||||
phone: [
|
||||
{ required: true, message: '请输入联系电话', trigger: 'blur' },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
|
||||
],
|
||||
diagDate: [
|
||||
{ required: true, message: '请选择诊断日期', trigger: 'change' }
|
||||
]
|
||||
};
|
||||
// 计算表格高度:根据视口高度动态调整
|
||||
const tableHeight = computed(() => {
|
||||
// 视口高度 - 顶部导航(约60px) - 标题(40px) - 统计卡片(120px) - 筛选区(100px)
|
||||
// - 分页(60px) - 底部操作栏(60px) - 上下边距(80px) - 额外缓冲(20px)
|
||||
return window.innerHeight - 540;
|
||||
});
|
||||
|
||||
// 监听窗口大小变化,确保表格高度自适应
|
||||
let resizeObserver = null;
|
||||
|
||||
const statusMap = {
|
||||
'0': { name: '待提交', type: 'warning' },
|
||||
'1': { name: '已提交', type: 'primary' },
|
||||
'2': { name: '已审核', type: 'success' },
|
||||
'3': { name: '已上报', type: 'success' },
|
||||
'4': { name: '失败', type: 'danger' },
|
||||
'5': { name: '退回', type: 'danger' },
|
||||
'6': { name: '作废', type: 'info' },
|
||||
0: { name: '待提交', type: 'warning' },
|
||||
1: { name: '已提交', type: 'primary' },
|
||||
2: { name: '已审核', type: 'success' },
|
||||
3: { name: '已上报', type: 'success' },
|
||||
4: { name: '失败', type: 'danger' },
|
||||
5: { name: '退回', type: 'danger' },
|
||||
6: { name: '作废', type: 'info' },
|
||||
};
|
||||
|
||||
const ageUnitMap = {
|
||||
@@ -454,11 +316,11 @@ function handleSelectionChange(selection) {
|
||||
}
|
||||
|
||||
function handleSelectAll(val) {
|
||||
if (val) {
|
||||
selectedRows.value = [...cardList.value];
|
||||
} else {
|
||||
selectedRows.value = [];
|
||||
}
|
||||
nextTick(() => {
|
||||
if (tableRef.value) {
|
||||
tableRef.value.toggleAllSelection();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function handleView(row) {
|
||||
@@ -478,7 +340,7 @@ async function handleEdit(row) {
|
||||
try {
|
||||
const res = await getCardDetail(row.cardNo);
|
||||
if (res.code === 200) {
|
||||
Object.assign(editForm, res.data || {});
|
||||
currentCard.value = res.data || {};
|
||||
detailMode.value = 'edit';
|
||||
detailVisible.value = true;
|
||||
}
|
||||
@@ -487,26 +349,33 @@ async function handleEdit(row) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSaveEdit() {
|
||||
// 验证表单
|
||||
try {
|
||||
await editFormRef.value.validate();
|
||||
} catch (error) {
|
||||
ElMessage.error('表单验证失败,请检查输入');
|
||||
return;
|
||||
}
|
||||
|
||||
async function handleSaveEdit(submitData) {
|
||||
// submitData 来自 InfectiousReport 组件的 submit-edit 事件
|
||||
try {
|
||||
const updateData = {
|
||||
cardNo: editForm.cardNo,
|
||||
phone: editForm.phone,
|
||||
onsetDate: editForm.onsetDate,
|
||||
diagDate: editForm.diagDate,
|
||||
diseaseType: editForm.diseaseType,
|
||||
addressProv: editForm.addressProv,
|
||||
addressCity: editForm.addressCity,
|
||||
addressCounty: editForm.addressCounty,
|
||||
addressHouse: editForm.addressHouse,
|
||||
cardNo: submitData.cardNo,
|
||||
phone: submitData.phone,
|
||||
contactPhone: submitData.contactPhone,
|
||||
onsetDate: submitData.onsetDate,
|
||||
diagDate: submitData.diagDate,
|
||||
diseaseCode: submitData.diseaseCode,
|
||||
diseaseType: submitData.diseaseType,
|
||||
otherDisease: submitData.otherDisease,
|
||||
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);
|
||||
@@ -567,7 +436,7 @@ async function handleWithdraw(row) {
|
||||
}
|
||||
|
||||
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) {
|
||||
ElMessage.warning('只能提交待提交状态的报卡');
|
||||
return;
|
||||
@@ -595,7 +464,7 @@ async function handleBatchSubmit() {
|
||||
}
|
||||
|
||||
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) {
|
||||
ElMessage.warning('只能删除待提交状态的报卡');
|
||||
return;
|
||||
@@ -638,9 +507,35 @@ async function handleExport(row) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log('页面首次加载 - onMounted');
|
||||
getStatistics();
|
||||
getList();
|
||||
|
||||
// 添加窗口大小变化监听
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
// 处理 keep-alive 缓存场景:从其他页面返回时重新加载数据
|
||||
onActivated(() => {
|
||||
console.log('页面被激活 - onActivated');
|
||||
getStatistics();
|
||||
getList();
|
||||
});
|
||||
|
||||
// 组件卸载时移除事件监听
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
// 窗口大小变化处理函数
|
||||
function handleResize() {
|
||||
// 触发计算属性重新计算
|
||||
nextTick(() => {
|
||||
if (tableRef.value) {
|
||||
tableRef.value.doLayout();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -648,109 +543,274 @@ onMounted(() => {
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
min-height: calc(100vh - 84px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* 页面标题 */
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.page-header h2 {
|
||||
.page-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 统计卡片区 */
|
||||
.statistics-section {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
padding: 20px 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
|
||||
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%);
|
||||
box-shadow: 0 4px 12px rgba(245, 87, 108, 0.3);
|
||||
}
|
||||
|
||||
.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;
|
||||
/* 图标容器 */
|
||||
.stat-icon-wrap {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: 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 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
font-size: 13px;
|
||||
color: #64748b;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* 高级筛选区 */
|
||||
.filter-section {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.action-section {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 12px 20px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
.filter-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.filter-row {
|
||||
display: flex;
|
||||
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 {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
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 {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
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) {
|
||||
.statistics-section {
|
||||
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>
|
||||
1
test-acp.txt
Normal file
1
test-acp.txt
Normal file
@@ -0,0 +1 @@
|
||||
test Tue Apr 14 05:12:39 PM CST 2026
|
||||
Reference in New Issue
Block a user