Compare commits
4 Commits
5d02da03b4
...
f515b90c43
| Author | SHA1 | Date | |
|---|---|---|---|
| f515b90c43 | |||
| 6aff10e240 | |||
| d99188bfb9 | |||
| c3776c642b |
@@ -104,4 +104,8 @@ public class InstrumentManageDto {
|
||||
/** 备注 */
|
||||
private String remarks;
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public Integer getInstrumentTypeEnum() {
|
||||
return instrumentTypeEnum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,19 @@ public class InstrumentManageInitDto {
|
||||
private List<InstrumentType> InstrumentTypeList;
|
||||
private List<InstrumentStatusEnumOption> InstrumentStatusEnumList;
|
||||
|
||||
// 手动添加 setter 方法
|
||||
public void setStatusFlagOptions(List<statusEnumOption> statusFlagOptions) {
|
||||
this.statusFlagOptions = statusFlagOptions;
|
||||
}
|
||||
|
||||
public void setInstrumentTypeList(List<InstrumentType> InstrumentTypeList) {
|
||||
this.InstrumentTypeList = InstrumentTypeList;
|
||||
}
|
||||
|
||||
public void setInstrumentStatusEnumList(List<InstrumentStatusEnumOption> InstrumentStatusEnumList) {
|
||||
this.InstrumentStatusEnumList = InstrumentStatusEnumList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
|
||||
@@ -13,4 +13,13 @@ import java.util.List;
|
||||
public class InstrumentStatusRequest {
|
||||
private List<Long> ids;
|
||||
private String type;
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,4 +28,36 @@ public class LisConfigManageDto {
|
||||
|
||||
private List<ActivityDefSpecimenDef> activityDefSpecimenDefs;
|
||||
|
||||
// 手动添加 getter 和 setter 方法
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<ActivityDefDeviceDef> getActivityDefDeviceDefs() {
|
||||
return activityDefDeviceDefs;
|
||||
}
|
||||
|
||||
public void setActivityDefDeviceDefs(List<ActivityDefDeviceDef> activityDefDeviceDefs) {
|
||||
this.activityDefDeviceDefs = activityDefDeviceDefs;
|
||||
}
|
||||
|
||||
public List<ActivityDefObservationDef> getActivityDefObservationDefs() {
|
||||
return activityDefObservationDefs;
|
||||
}
|
||||
|
||||
public void setActivityDefObservationDefs(List<ActivityDefObservationDef> activityDefObservationDefs) {
|
||||
this.activityDefObservationDefs = activityDefObservationDefs;
|
||||
}
|
||||
|
||||
public List<ActivityDefSpecimenDef> getActivityDefSpecimenDefs() {
|
||||
return activityDefSpecimenDefs;
|
||||
}
|
||||
|
||||
public void setActivityDefSpecimenDefs(List<ActivityDefSpecimenDef> activityDefSpecimenDefs) {
|
||||
this.activityDefSpecimenDefs = activityDefSpecimenDefs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,4 +23,16 @@ public class LisConfigManageInitDto {
|
||||
|
||||
private List<SpecimenDefinition> specimenDefs;
|
||||
|
||||
// 手动添加 setter 方法
|
||||
public void setDeviceDefs(List<DeviceDefinition> deviceDefs) {
|
||||
this.deviceDefs = deviceDefs;
|
||||
}
|
||||
|
||||
public void setObservationDefs(List<ObservationDefinition> observationDefs) {
|
||||
this.observationDefs = observationDefs;
|
||||
}
|
||||
|
||||
public void setSpecimenDefs(List<SpecimenDefinition> specimenDefs) {
|
||||
this.specimenDefs = specimenDefs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,16 @@ public class ObservationDefManageDto {
|
||||
/** 删除状态) */
|
||||
private String deleteFlag;
|
||||
|
||||
|
||||
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public Long getInstrumentId() {
|
||||
return instrumentId;
|
||||
}
|
||||
|
||||
public Integer getStatusEnum() {
|
||||
return statusEnum;
|
||||
}
|
||||
|
||||
public Integer getObservationTypeEnum() {
|
||||
return observationTypeEnum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,19 @@ public class ObservationDefManageInitDto {
|
||||
private List<ObservationTypeEnumOption> ObservationTypeList;
|
||||
private List<InstrumentEnumOption> instrumentEnumOptionList;
|
||||
|
||||
// 手动添加 setter 方法
|
||||
public void setStatusFlagOptions(List<statusEnumOption> statusFlagOptions) {
|
||||
this.statusFlagOptions = statusFlagOptions;
|
||||
}
|
||||
|
||||
public void setObservationTypeList(List<ObservationTypeEnumOption> ObservationTypeList) {
|
||||
this.ObservationTypeList = ObservationTypeList;
|
||||
}
|
||||
|
||||
public void setInstrumentEnumOptionList(List<InstrumentEnumOption> instrumentEnumOptionList) {
|
||||
this.instrumentEnumOptionList = instrumentEnumOptionList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
|
||||
@@ -13,4 +13,13 @@ import java.util.List;
|
||||
public class ObservationDefStatusRequest {
|
||||
private List<Long> ids;
|
||||
private String type;
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,4 +32,8 @@ public class ReportResultManageDto {
|
||||
private String authoredTime; // 开单时间
|
||||
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public Integer getGenderEnum() {
|
||||
return genderEnum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +40,12 @@ public class SampleCollectManageDto {
|
||||
private String authoredTime; // 开单时间
|
||||
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public Integer getGenderEnum() {
|
||||
return genderEnum;
|
||||
}
|
||||
|
||||
public Integer getCollectionStatusEnum() {
|
||||
return collectionStatusEnum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,13 @@ import java.util.List;
|
||||
public class SampleCollectStatusRequest {
|
||||
private List<Long> ids;
|
||||
private String type;
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,12 @@ public class SpecimenDefManageDto {
|
||||
private Integer statusEnum;
|
||||
private String statusEnumText;
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public Integer getSpecimenTypeEnum() {
|
||||
return specimenTypeEnum;
|
||||
}
|
||||
|
||||
public Integer getStatusEnum() {
|
||||
return statusEnum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,15 @@ public class SpecimenDefManageInitDto {
|
||||
private List<statusEnumOption> statusFlagOptions;
|
||||
private List<SpecimenType> SpecimenTypeList;
|
||||
|
||||
// 手动添加 setter 方法
|
||||
public void setStatusFlagOptions(List<statusEnumOption> statusFlagOptions) {
|
||||
this.statusFlagOptions = statusFlagOptions;
|
||||
}
|
||||
|
||||
public void setSpecimenTypeList(List<SpecimenType> SpecimenTypeList) {
|
||||
this.SpecimenTypeList = SpecimenTypeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
|
||||
@@ -13,4 +13,13 @@ import java.util.List;
|
||||
public class SpecimenDefStatusRequest {
|
||||
private List<Long> ids;
|
||||
private String type;
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<Long> getIds() {
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,4 +69,13 @@ public class AdjustPriceDataVo {
|
||||
private Long locationId;
|
||||
|
||||
private BigDecimal finalTotalQuantity;
|
||||
|
||||
// 手动添加 getter 方法
|
||||
public Long getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public Integer getCategoryType() {
|
||||
return categoryType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +93,75 @@ public interface ICardManageAppService {
|
||||
* @return 科室树数据
|
||||
*/
|
||||
R<?> getDeptTree();
|
||||
|
||||
/**
|
||||
* 获取医生个人报卡统计数据
|
||||
*
|
||||
* @return 统计数据
|
||||
*/
|
||||
DoctorCardStatisticsDto getDoctorCardStatistics();
|
||||
|
||||
/**
|
||||
* 分页查询医生个人报卡列表
|
||||
*
|
||||
* @param queryParams 查询参数
|
||||
* @return 分页数据
|
||||
*/
|
||||
R<?> getDoctorCardPage(DoctorCardQueryDto queryParams);
|
||||
|
||||
/**
|
||||
* 提交报卡
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> submitCard(String cardNo);
|
||||
|
||||
/**
|
||||
* 撤回报卡
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> withdrawCard(String cardNo);
|
||||
|
||||
/**
|
||||
* 删除报卡(状态变为作废)
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> deleteCard(String cardNo);
|
||||
|
||||
/**
|
||||
* 批量提交报卡
|
||||
*
|
||||
* @param cardNos 卡片编号列表
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> batchSubmitCards(List<String> cardNos);
|
||||
|
||||
/**
|
||||
* 批量删除报卡
|
||||
*
|
||||
* @param cardNos 卡片编号列表
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> batchDeleteCards(List<String> cardNos);
|
||||
|
||||
/**
|
||||
* 导出报卡为Word文档
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @param response 响应
|
||||
*/
|
||||
void exportCardToWord(String cardNo, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 更新医生报卡
|
||||
*
|
||||
* @param updateDto 更新参数
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> updateDoctorCard(DoctorCardUpdateDto updateDto);
|
||||
}
|
||||
|
||||
@@ -308,15 +308,340 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为DTO
|
||||
*/
|
||||
private InfectiousCardDto convertToDto(InfectiousCard card) {
|
||||
InfectiousCardDto dto = new InfectiousCardDto();
|
||||
BeanUtils.copyProperties(card, dto);
|
||||
@Override
|
||||
public DoctorCardStatisticsDto getDoctorCardStatistics() {
|
||||
Long doctorId = SecurityUtils.getUserId();
|
||||
|
||||
DoctorCardStatisticsDto dto = new DoctorCardStatisticsDto();
|
||||
dto.setTotalCount(infectiousCardMapper.countByDoctorId(doctorId));
|
||||
dto.setPendingFailedCount(infectiousCardMapper.countPendingFailedByDoctorId(doctorId));
|
||||
dto.setReportedCount(infectiousCardMapper.countReportedByDoctorId(doctorId));
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> getDoctorCardPage(DoctorCardQueryDto queryParams) {
|
||||
Long doctorId = SecurityUtils.getUserId();
|
||||
|
||||
Page<InfectiousCard> page = new Page<>(queryParams.getPageNo(), queryParams.getPageSize());
|
||||
LambdaQueryWrapper<InfectiousCard> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 只查询当前医生的报卡
|
||||
wrapper.eq(InfectiousCard::getDoctorId, doctorId);
|
||||
|
||||
// 状态筛选
|
||||
if (StringUtils.hasText(queryParams.getStatus())) {
|
||||
wrapper.eq(InfectiousCard::getStatus, queryParams.getStatus());
|
||||
}
|
||||
|
||||
// 时间范围筛选
|
||||
if (StringUtils.hasText(queryParams.getStartDate())) {
|
||||
LocalDateTime startDateTime = LocalDateTime.parse(queryParams.getStartDate() + "T00:00:00");
|
||||
wrapper.ge(InfectiousCard::getCreateTime, startDateTime);
|
||||
}
|
||||
if (StringUtils.hasText(queryParams.getEndDate())) {
|
||||
LocalDateTime endDateTime = LocalDateTime.parse(queryParams.getEndDate() + "T23:59:59");
|
||||
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())
|
||||
);
|
||||
}
|
||||
|
||||
// 按创建时间倒序
|
||||
wrapper.orderByDesc(InfectiousCard::getCreateTime);
|
||||
|
||||
IPage<InfectiousCard> result = infectiousCardMapper.selectPage(page, wrapper);
|
||||
|
||||
// 转换为DTO
|
||||
List<DoctorCardListDto> list = result.getRecords().stream()
|
||||
.map(this::convertToDoctorCardListDto)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String, Object> resultMap = new HashMap<>();
|
||||
resultMap.put("list", list);
|
||||
resultMap.put("total", result.getTotal());
|
||||
return R.ok(resultMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> submitCard(String cardNo) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
if (card == null) {
|
||||
return R.fail("报卡不存在");
|
||||
}
|
||||
|
||||
// 验证权限:只能提交自己的报卡
|
||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
||||
return R.fail("无权操作此报卡");
|
||||
}
|
||||
|
||||
// 验证状态:只有暂存状态可以提交
|
||||
if (!"0".equals(card.getStatus())) {
|
||||
return R.fail("只能提交暂存状态的报卡");
|
||||
}
|
||||
|
||||
// 更新状态为已提交
|
||||
card.setStatus("1");
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
|
||||
return R.ok("提交成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> withdrawCard(String cardNo) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
if (card == null) {
|
||||
return R.fail("报卡不存在");
|
||||
}
|
||||
|
||||
// 验证权限:只能撤回自己的报卡
|
||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
||||
return R.fail("无权操作此报卡");
|
||||
}
|
||||
|
||||
// 验证状态:只有已提交状态可以撤回
|
||||
if (!"1".equals(card.getStatus())) {
|
||||
return R.fail("只能撤回已提交状态的报卡");
|
||||
}
|
||||
|
||||
// 更新状态为暂存
|
||||
card.setStatus("0");
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
|
||||
return R.ok("撤回成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> deleteCard(String cardNo) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
if (card == null) {
|
||||
return R.fail("报卡不存在");
|
||||
}
|
||||
|
||||
// 验证权限:只能删除自己的报卡
|
||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
||||
return R.fail("无权操作此报卡");
|
||||
}
|
||||
|
||||
// 验证状态:只有暂存状态可以删除
|
||||
if (!"0".equals(card.getStatus())) {
|
||||
return R.fail("只能删除暂存状态的报卡");
|
||||
}
|
||||
|
||||
// 更新状态为作废
|
||||
card.setStatus("6");
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
|
||||
return R.ok("删除成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> batchSubmitCards(List<String> cardNos) {
|
||||
if (cardNos == null || cardNos.isEmpty()) {
|
||||
return R.fail("请选择要提交的报卡");
|
||||
}
|
||||
|
||||
Long doctorId = SecurityUtils.getUserId();
|
||||
int successCount = 0;
|
||||
|
||||
for (String cardNo : cardNos) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
if (card == null) continue;
|
||||
|
||||
// 验证权限:只能提交自己的报卡
|
||||
if (!card.getDoctorId().equals(doctorId)) continue;
|
||||
|
||||
// 验证状态:只有暂存状态可以提交
|
||||
if (!"0".equals(card.getStatus())) continue;
|
||||
|
||||
// 更新状态为已提交
|
||||
card.setStatus("1");
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
successCount++;
|
||||
}
|
||||
|
||||
if (successCount == 0) {
|
||||
return R.fail("没有可提交的报卡,只能提交暂存状态的报卡");
|
||||
}
|
||||
|
||||
return R.ok("批量提交成功,共提交" + successCount + "条");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> batchDeleteCards(List<String> cardNos) {
|
||||
if (cardNos == null || cardNos.isEmpty()) {
|
||||
return R.fail("请选择要删除的报卡");
|
||||
}
|
||||
|
||||
Long doctorId = SecurityUtils.getUserId();
|
||||
int successCount = 0;
|
||||
|
||||
for (String cardNo : cardNos) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
if (card == null) continue;
|
||||
|
||||
// 验证权限:只能删除自己的报卡
|
||||
if (!card.getDoctorId().equals(doctorId)) continue;
|
||||
|
||||
// 验证状态:只有暂存状态可以删除
|
||||
if (!"0".equals(card.getStatus())) continue;
|
||||
|
||||
// 更新状态为作废
|
||||
card.setStatus("6");
|
||||
card.setUpdateTime(new Date());
|
||||
infectiousCardMapper.updateById(card);
|
||||
successCount++;
|
||||
}
|
||||
|
||||
if (successCount == 0) {
|
||||
return R.fail("没有可删除的报卡,只能删除暂存状态的报卡");
|
||||
}
|
||||
|
||||
return R.ok("批量删除成功,共删除" + successCount + "条");
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> updateDoctorCard(DoctorCardUpdateDto updateDto) {
|
||||
// 获取当前登录用户信息
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
Long currentUserId = loginUser.getUserId();
|
||||
|
||||
// 查询报卡
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(updateDto.getCardNo());
|
||||
if (card == null) {
|
||||
return R.fail("报卡不存在");
|
||||
}
|
||||
|
||||
// 验证是否当前医生的报卡 - 根据doctorId字段验证
|
||||
if (!currentUserId.equals(card.getDoctorId())) {
|
||||
return R.fail("只能修改自己的报卡");
|
||||
}
|
||||
|
||||
// 验证状态是否允许修改(只能修改暂存状态的报卡)
|
||||
if (!"0".equals(card.getStatus())) {
|
||||
return R.fail("只能修改暂存状态的报卡");
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
card.setPhone(updateDto.getPhone());
|
||||
card.setOnsetDate(updateDto.getOnsetDate());
|
||||
card.setDiagDate(updateDto.getDiagDate());
|
||||
card.setDiseaseType(updateDto.getDiseaseType()); // 使用diseaseType字段
|
||||
card.setAddressProv(updateDto.getAddressProv());
|
||||
card.setAddressCity(updateDto.getAddressCity());
|
||||
card.setAddressCounty(updateDto.getAddressCounty());
|
||||
card.setAddressHouse(updateDto.getAddressHouse());
|
||||
card.setUpdateTime(LocalDateTime.now());
|
||||
card.setUpdateBy(loginUser.getUsername()); // 使用username作为更新者
|
||||
|
||||
int rows = infectiousCardMapper.updateById(card);
|
||||
if (rows > 0) {
|
||||
return R.ok("更新成功");
|
||||
}
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
// 验证是否当前医生的报卡
|
||||
// 使用createBy字段验证(通常是创建人),如果使用了其他字段则需调整
|
||||
if (!currentUserId.equals(card.getCreateBy())) {
|
||||
return R.fail("只能修改自己的报卡");
|
||||
}
|
||||
|
||||
// 验证状态是否允许修改(只能修改暂存状态的报卡)
|
||||
if (!"0".equals(card.getStatus())) {
|
||||
return R.fail("只能修改暂存状态的报卡");
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
card.setPhone(updateDto.getPhone());
|
||||
card.setOnsetDate(updateDto.getOnsetDate());
|
||||
card.setDiagDate(updateDto.getDiagDate());
|
||||
card.setAddressProv(updateDto.getAddressProv());
|
||||
card.setAddressCity(updateDto.getAddressCity());
|
||||
card.setAddressCounty(updateDto.getAddressCounty());
|
||||
card.setAddressHouse(updateDto.getAddressHouse());
|
||||
card.setUpdateTime(LocalDateTime.now());
|
||||
card.setUpdateBy(currentUserId);
|
||||
|
||||
int rows = infectiousCardMapper.updateById(card);
|
||||
if (rows > 0) {
|
||||
return R.ok("更新成功");
|
||||
}
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportCardToWord(String cardNo, HttpServletResponse response) {
|
||||
InfectiousCard card = infectiousCardMapper.selectByCardNo(cardNo);
|
||||
if (card == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证权限:只能导出自己的报卡
|
||||
if (!card.getDoctorId().equals(SecurityUtils.getUserId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证状态:只有已上报状态可以导出
|
||||
if (!"3".equals(card.getStatus())) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO: 实现Word导出逻辑,使用Apache POI或其他库
|
||||
// 这里简化为返回文本内容
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" +
|
||||
URLEncoder.encode("传染病报告卡-" + cardNo + ".docx", StandardCharsets.UTF_8));
|
||||
|
||||
// 实际应生成Word文档内容
|
||||
response.getWriter().write("报卡编号:" + cardNo);
|
||||
} catch (IOException e) {
|
||||
log.error("导出报卡失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为医生报卡列表DTO
|
||||
*/
|
||||
private DoctorCardListDto convertToDoctorCardListDto(InfectiousCard card) {
|
||||
DoctorCardListDto dto = new DoctorCardListDto();
|
||||
BeanUtils.copyProperties(card, dto);
|
||||
dto.setCardName(getCardName(card.getCardNameCode()));
|
||||
dto.setSubmitTime(card.getCreateTime() != null ?
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm").format(card.getCreateTime()) : null);
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取报卡名称
|
||||
*/
|
||||
private String getCardName(Integer cardNameCode) {
|
||||
if (cardNameCode == null) return "中华人民共和国传染病报告卡";
|
||||
switch (cardNameCode) {
|
||||
case 1: return "中华人民共和国传染病报告卡";
|
||||
case 2: return "甲类传染病报告卡";
|
||||
case 3: return "乙类传染病报告卡";
|
||||
case 4: return "丙类传染病报告卡";
|
||||
default: return "中华人民共和国传染病报告卡";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换审核记录为DTO
|
||||
*/
|
||||
@@ -327,6 +652,16 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为报卡DTO
|
||||
*/
|
||||
private InfectiousCardDto convertToDto(InfectiousCard card) {
|
||||
InfectiousCardDto dto = new InfectiousCardDto();
|
||||
BeanUtils.copyProperties(card, dto);
|
||||
dto.setStatusText(getStatusText(card.getStatus()));
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建审核记录
|
||||
*/
|
||||
@@ -355,11 +690,12 @@ public class CardManageAppServiceImpl implements ICardManageAppService {
|
||||
private String getStatusText(String status) {
|
||||
switch (status) {
|
||||
case "0": return "暂存";
|
||||
case "1": return "待审核";
|
||||
case "1": return "已提交";
|
||||
case "2": return "审核通过";
|
||||
case "3": return "已上报";
|
||||
case "4": return "失败";
|
||||
case "5": return "审核失败";
|
||||
case "6": return "作废";
|
||||
default: return "未知";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,4 +134,104 @@ public class CardManageController {
|
||||
public R<?> getDeptTree() {
|
||||
return cardManageAppService.getDeptTree();
|
||||
}
|
||||
|
||||
// ==================== 医生个人报卡管理 ====================
|
||||
|
||||
/**
|
||||
* 获取医生个人报卡统计数据
|
||||
*
|
||||
* @return 统计数据
|
||||
*/
|
||||
@GetMapping("/doctor/statistics")
|
||||
public R<DoctorCardStatisticsDto> getDoctorCardStatistics() {
|
||||
return R.ok(cardManageAppService.getDoctorCardStatistics());
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询医生个人报卡列表
|
||||
*
|
||||
* @param queryParams 查询参数
|
||||
* @return 分页数据
|
||||
*/
|
||||
@GetMapping("/doctor/page")
|
||||
public R<?> getDoctorCardPage(DoctorCardQueryDto queryParams) {
|
||||
return cardManageAppService.getDoctorCardPage(queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交报卡
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/doctor/submit/{cardNo}")
|
||||
public R<?> submitCard(@PathVariable String cardNo) {
|
||||
return cardManageAppService.submitCard(cardNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回报卡
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/doctor/withdraw/{cardNo}")
|
||||
public R<?> withdrawCard(@PathVariable String cardNo) {
|
||||
return cardManageAppService.withdrawCard(cardNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除报卡(状态变为作废)
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @return 结果
|
||||
*/
|
||||
@DeleteMapping("/doctor/{cardNo}")
|
||||
public R<?> deleteCard(@PathVariable String cardNo) {
|
||||
return cardManageAppService.deleteCard(cardNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量提交报卡
|
||||
*
|
||||
* @param cardNos 卡片编号列表
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/doctor/batch-submit")
|
||||
public R<?> batchSubmitCards(@RequestBody List<String> cardNos) {
|
||||
return cardManageAppService.batchSubmitCards(cardNos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除报卡
|
||||
*
|
||||
* @param cardNos 卡片编号列表
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/doctor/batch-delete")
|
||||
public R<?> batchDeleteCards(@RequestBody List<String> cardNos) {
|
||||
return cardManageAppService.batchDeleteCards(cardNos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新医生报卡
|
||||
*
|
||||
* @param updateDto 更新参数
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping("/doctor/update")
|
||||
public R<?> updateDoctorCard(@RequestBody DoctorCardUpdateDto updateDto) {
|
||||
return cardManageAppService.updateDoctorCard(updateDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出报卡为Word文档
|
||||
*
|
||||
* @param cardNo 卡片编号
|
||||
* @param response 响应
|
||||
*/
|
||||
@GetMapping("/doctor/export-word/{cardNo}")
|
||||
public void exportCardToWord(@PathVariable String cardNo, HttpServletResponse response) {
|
||||
cardManageAppService.exportCardToWord(cardNo, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright ©2026 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.cardmanagement.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 医生个人报卡列表DTO
|
||||
*
|
||||
* @author system
|
||||
* @date 2026-03-08
|
||||
*/
|
||||
@Data
|
||||
public class DoctorCardListDto {
|
||||
|
||||
/** 卡片ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/** 卡片编号 */
|
||||
private String cardNo;
|
||||
|
||||
/** 患者姓名 */
|
||||
private String patName;
|
||||
|
||||
/** 身份证号 */
|
||||
private String idNo;
|
||||
|
||||
/** 联系电话 */
|
||||
private String phone;
|
||||
|
||||
/** 就诊卡号(暂时不展示,字段保留) */
|
||||
private String visitCardNo;
|
||||
|
||||
/** 报卡名称 */
|
||||
private String cardName;
|
||||
|
||||
/** 提交时间 */
|
||||
private String submitTime;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright ©2026 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.cardmanagement.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 医生个人报卡查询参数
|
||||
*
|
||||
* @author system
|
||||
* @date 2026-03-08
|
||||
*/
|
||||
@Data
|
||||
public class DoctorCardQueryDto {
|
||||
|
||||
/** 页码 */
|
||||
private Integer pageNo = 1;
|
||||
|
||||
/** 每页数量 */
|
||||
private Integer pageSize = 10;
|
||||
|
||||
/** 开始日期 */
|
||||
private String startDate;
|
||||
|
||||
/** 结束日期 */
|
||||
private String endDate;
|
||||
|
||||
/** 状态(0暂存/1已提交/2已审核/3已上报/4失败/5退回) */
|
||||
private String status;
|
||||
|
||||
/** 患者姓名或报卡名称 */
|
||||
private String keyword;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright ©2026 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.cardmanagement.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 医生个人报卡统计数据
|
||||
*
|
||||
* @author system
|
||||
* @date 2026-03-08
|
||||
*/
|
||||
@Data
|
||||
public class DoctorCardStatisticsDto {
|
||||
|
||||
/** 总报卡数 */
|
||||
private Integer totalCount;
|
||||
|
||||
/** 待处理失败数 */
|
||||
private Integer pendingFailedCount;
|
||||
|
||||
/** 已成功上报数 */
|
||||
private Integer reportedCount;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.openhis.web.cardmanagement.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class DoctorCardUpdateDto {
|
||||
private String cardNo;
|
||||
private String phone;
|
||||
private LocalDate onsetDate;
|
||||
private LocalDateTime diagDate;
|
||||
private String diseaseType; // 修改为diseaseType,对应InfectiousCard中的diseaseType字段
|
||||
private String addressProv;
|
||||
private String addressCity;
|
||||
private String addressCounty;
|
||||
private String addressHouse;
|
||||
}
|
||||
@@ -113,6 +113,9 @@ public class InfectiousCardDto {
|
||||
/** 状态 */
|
||||
private String status;
|
||||
|
||||
/** 状态文本 */
|
||||
private String statusText;
|
||||
|
||||
/** 报卡名称代码 */
|
||||
private Integer cardNameCode;
|
||||
|
||||
|
||||
@@ -47,4 +47,22 @@ public interface InfectiousCardMapper extends BaseMapper<InfectiousCard> {
|
||||
*/
|
||||
@Select("SELECT * FROM infectious_card WHERE card_no = #{cardNo}")
|
||||
InfectiousCard selectByCardNo(@Param("cardNo") String cardNo);
|
||||
|
||||
/**
|
||||
* 统计医生个人总报卡数
|
||||
*/
|
||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE doctor_id = #{doctorId}")
|
||||
Integer countByDoctorId(@Param("doctorId") Long doctorId);
|
||||
|
||||
/**
|
||||
* 统计医生待处理失败数(状态为0暂存或4失败)
|
||||
*/
|
||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE doctor_id = #{doctorId} AND status IN ('0', '4')")
|
||||
Integer countPendingFailedByDoctorId(@Param("doctorId") Long doctorId);
|
||||
|
||||
/**
|
||||
* 统计医生已成功上报数(状态为3已上报)
|
||||
*/
|
||||
@Select("SELECT COUNT(*) FROM infectious_card WHERE doctor_id = #{doctorId} AND status = '3'")
|
||||
Integer countReportedByDoctorId(@Param("doctorId") Long doctorId);
|
||||
}
|
||||
|
||||
@@ -288,4 +288,286 @@ public class ProductDetailPageDto {
|
||||
this.salePriceStatistics = BigDecimal.ZERO;
|
||||
this.purchasePriceStatistics = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
// 手动添加 getter 和 setter 方法(Lombok 注解处理器未正常工作)
|
||||
|
||||
public Integer getInventoryStatusEnum() {
|
||||
return inventoryStatusEnum;
|
||||
}
|
||||
|
||||
public void setInventoryStatusEnum(Integer inventoryStatusEnum) {
|
||||
this.inventoryStatusEnum = inventoryStatusEnum;
|
||||
}
|
||||
|
||||
public Long getInventoryId() {
|
||||
return inventoryId;
|
||||
}
|
||||
|
||||
public void setInventoryId(Long inventoryId) {
|
||||
this.inventoryId = inventoryId;
|
||||
}
|
||||
|
||||
public Integer getChrgitmLv() {
|
||||
return chrgitmLv;
|
||||
}
|
||||
|
||||
public void setChrgitmLv(Integer chrgitmLv) {
|
||||
this.chrgitmLv = chrgitmLv;
|
||||
}
|
||||
|
||||
public String getDevCategoryCode() {
|
||||
return devCategoryCode;
|
||||
}
|
||||
|
||||
public void setDevCategoryCode(String devCategoryCode) {
|
||||
this.devCategoryCode = devCategoryCode;
|
||||
}
|
||||
|
||||
public Long getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public void setItemId(Long itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
public String getItemName() {
|
||||
return itemName;
|
||||
}
|
||||
|
||||
public void setItemName(String itemName) {
|
||||
this.itemName = itemName;
|
||||
}
|
||||
|
||||
public String getBusNo() {
|
||||
return busNo;
|
||||
}
|
||||
|
||||
public void setBusNo(String busNo) {
|
||||
this.busNo = busNo;
|
||||
}
|
||||
|
||||
public String getMedCategoryCode() {
|
||||
return medCategoryCode;
|
||||
}
|
||||
|
||||
public void setMedCategoryCode(String medCategoryCode) {
|
||||
this.medCategoryCode = medCategoryCode;
|
||||
}
|
||||
|
||||
public String getItemTable() {
|
||||
return itemTable;
|
||||
}
|
||||
|
||||
public void setItemTable(String itemTable) {
|
||||
this.itemTable = itemTable;
|
||||
}
|
||||
|
||||
public Long getLocationId() {
|
||||
return locationId;
|
||||
}
|
||||
|
||||
public void setLocationId(Long locationId) {
|
||||
this.locationId = locationId;
|
||||
}
|
||||
|
||||
public String getLocationName() {
|
||||
return locationName;
|
||||
}
|
||||
|
||||
public void setLocationName(String locationName) {
|
||||
this.locationName = locationName;
|
||||
}
|
||||
|
||||
public Long getLocationStoreId() {
|
||||
return locationStoreId;
|
||||
}
|
||||
|
||||
public void setLocationStoreId(Long locationStoreId) {
|
||||
this.locationStoreId = locationStoreId;
|
||||
}
|
||||
|
||||
public String getLocationStoreName() {
|
||||
return locationStoreName;
|
||||
}
|
||||
|
||||
public void setLocationStoreName(String locationStoreName) {
|
||||
this.locationStoreName = locationStoreName;
|
||||
}
|
||||
|
||||
public String getManufacturerText() {
|
||||
return manufacturerText;
|
||||
}
|
||||
|
||||
public void setManufacturerText(String manufacturerText) {
|
||||
this.manufacturerText = manufacturerText;
|
||||
}
|
||||
|
||||
public String getMinUnitCode() {
|
||||
return minUnitCode;
|
||||
}
|
||||
|
||||
public void setMinUnitCode(String minUnitCode) {
|
||||
this.minUnitCode = minUnitCode;
|
||||
}
|
||||
|
||||
public BigDecimal getPartPercent() {
|
||||
return partPercent;
|
||||
}
|
||||
|
||||
public void setPartPercent(BigDecimal partPercent) {
|
||||
this.partPercent = partPercent;
|
||||
}
|
||||
|
||||
public BigDecimal getPurchasePrice() {
|
||||
return purchasePrice;
|
||||
}
|
||||
|
||||
public void setPurchasePrice(BigDecimal purchasePrice) {
|
||||
this.purchasePrice = purchasePrice;
|
||||
}
|
||||
|
||||
public Date getProductionDate() {
|
||||
return productionDate;
|
||||
}
|
||||
|
||||
public void setProductionDate(Date productionDate) {
|
||||
this.productionDate = productionDate;
|
||||
}
|
||||
|
||||
public Date getExpirationDate() {
|
||||
return expirationDate;
|
||||
}
|
||||
|
||||
public void setExpirationDate(Date expirationDate) {
|
||||
this.expirationDate = expirationDate;
|
||||
}
|
||||
|
||||
public BigDecimal getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(BigDecimal quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public BigDecimal getSalePrice() {
|
||||
return salePrice;
|
||||
}
|
||||
|
||||
public void setSalePrice(BigDecimal salePrice) {
|
||||
this.salePrice = salePrice;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalPurchasePrice() {
|
||||
return totalPurchasePrice;
|
||||
}
|
||||
|
||||
public void setTotalPurchasePrice(BigDecimal totalPurchasePrice) {
|
||||
this.totalPurchasePrice = totalPurchasePrice;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalSalePrice() {
|
||||
return totalSalePrice;
|
||||
}
|
||||
|
||||
public void setTotalSalePrice(BigDecimal totalSalePrice) {
|
||||
this.totalSalePrice = totalSalePrice;
|
||||
}
|
||||
|
||||
public String getTotalVolume() {
|
||||
return totalVolume;
|
||||
}
|
||||
|
||||
public void setTotalVolume(String totalVolume) {
|
||||
this.totalVolume = totalVolume;
|
||||
}
|
||||
|
||||
public String getUnitCode() {
|
||||
return unitCode;
|
||||
}
|
||||
|
||||
public void setUnitCode(String unitCode) {
|
||||
this.unitCode = unitCode;
|
||||
}
|
||||
|
||||
public String getWbStr() {
|
||||
return wbStr;
|
||||
}
|
||||
|
||||
public void setWbStr(String wbStr) {
|
||||
this.wbStr = wbStr;
|
||||
}
|
||||
|
||||
public String getPyStr() {
|
||||
return pyStr;
|
||||
}
|
||||
|
||||
public void setPyStr(String pyStr) {
|
||||
this.pyStr = pyStr;
|
||||
}
|
||||
|
||||
public Long getSupplierId() {
|
||||
return supplierId;
|
||||
}
|
||||
|
||||
public void setSupplierId(Long supplierId) {
|
||||
this.supplierId = supplierId;
|
||||
}
|
||||
|
||||
public String getSupplierName() {
|
||||
return supplierName;
|
||||
}
|
||||
|
||||
public void setSupplierName(String supplierName) {
|
||||
this.supplierName = supplierName;
|
||||
}
|
||||
|
||||
public Integer getRemainingDays() {
|
||||
return remainingDays;
|
||||
}
|
||||
|
||||
public void setRemainingDays(Integer remainingDays) {
|
||||
this.remainingDays = remainingDays;
|
||||
}
|
||||
|
||||
public BigDecimal getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(BigDecimal number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public BigDecimal getRemainder() {
|
||||
return remainder;
|
||||
}
|
||||
|
||||
public void setRemainder(BigDecimal remainder) {
|
||||
this.remainder = remainder;
|
||||
}
|
||||
|
||||
public String getYbNo() {
|
||||
return ybNo;
|
||||
}
|
||||
|
||||
public void setYbNo(String ybNo) {
|
||||
this.ybNo = ybNo;
|
||||
}
|
||||
|
||||
public String getApprovalNumber() {
|
||||
return approvalNumber;
|
||||
}
|
||||
|
||||
public void setApprovalNumber(String approvalNumber) {
|
||||
this.approvalNumber = approvalNumber;
|
||||
}
|
||||
|
||||
public String getLotNumber() {
|
||||
return lotNumber;
|
||||
}
|
||||
|
||||
public void setLotNumber(String lotNumber) {
|
||||
this.lotNumber = lotNumber;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +249,12 @@ export const dynamicRoutes = [
|
||||
component: () => import('@/views/doctorstation/pendingEmr.vue'),
|
||||
name: 'PendingEmr',
|
||||
meta: { title: '待写病历', icon: 'document', permissions: ['doctorstation:pending-emr:view'] }
|
||||
},
|
||||
{
|
||||
path: 'my-card-management',
|
||||
component: () => import('@/views/doctorstation/mycardmanagement/index.vue'),
|
||||
name: 'MyCardManagement',
|
||||
meta: { title: '医生个人报卡管理', icon: 'document', permissions: ['doctorstation:my-card-management:view'] }
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -347,6 +353,71 @@ export const dynamicRoutes = [
|
||||
meta: { title: '日结结算单管理', icon: 'document' }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/inspection',
|
||||
component: Layout,
|
||||
redirect: '/inspection/report',
|
||||
name: 'Inspection',
|
||||
meta: { title: '检查管理', icon: 'inspection' },
|
||||
children: [
|
||||
{
|
||||
path: 'report',
|
||||
component: () => import('@/views/inspection/report/index.vue'),
|
||||
name: 'Report',
|
||||
meta: { title: '检查报告', icon: 'document' }
|
||||
},
|
||||
{
|
||||
path: 'sampleType',
|
||||
component: () => import('@/views/inspection/sampleType/index.vue'),
|
||||
name: 'SampleType',
|
||||
meta: { title: '样本类型', icon: 'sample' }
|
||||
},
|
||||
{
|
||||
path: 'observation',
|
||||
component: () => import('@/views/inspection/observation/index.vue'),
|
||||
name: 'Observation',
|
||||
meta: { title: '观测记录', icon: 'observation' }
|
||||
},
|
||||
{
|
||||
path: 'lisconfig',
|
||||
component: () => import('@/views/inspection/lisconfig/index.vue'),
|
||||
name: 'LisConfig',
|
||||
meta: { title: 'LIS 配置', icon: 'setting' }
|
||||
},
|
||||
{
|
||||
path: 'instrument',
|
||||
component: () => import('@/views/inspection/instrument/index.vue'),
|
||||
name: 'Instrument',
|
||||
meta: { title: '仪器管理', icon: 'instrument' }
|
||||
},
|
||||
{
|
||||
path: 'groupRec',
|
||||
component: () => import('@/views/inspection/groupRec/index.vue'),
|
||||
name: 'GroupRec',
|
||||
meta: { title: '组合记录', icon: 'group' }
|
||||
},
|
||||
{
|
||||
path: 'sampleCollection',
|
||||
component: () => import('@/views/inspection/sampleCollection/index.vue'),
|
||||
name: 'SampleCollection',
|
||||
meta: { title: '样本采集', icon: 'collection' }
|
||||
}
|
||||
]
|
||||
},
|
||||
// 医生报告页面 - 快捷访问路径
|
||||
{
|
||||
path: '/doctorreport',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/inspection/report/index.vue'),
|
||||
name: 'DoctorReport',
|
||||
meta: { title: '医生报告', activeMenu: '/inspection/report' }
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
export function getDoctorCardStatistics() {
|
||||
return request({
|
||||
url: '/card-management/doctor/statistics',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export function getDoctorCardList(params) {
|
||||
return request({
|
||||
url: '/card-management/doctor/page',
|
||||
method: 'get',
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
export function getCardDetail(cardNo) {
|
||||
return request({
|
||||
url: `/card-management/detail/${cardNo}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export function submitCard(cardNo) {
|
||||
return request({
|
||||
url: `/card-management/doctor/submit/${cardNo}`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
export function withdrawCard(cardNo) {
|
||||
return request({
|
||||
url: `/card-management/doctor/withdraw/${cardNo}`,
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteCard(cardNo) {
|
||||
return request({
|
||||
url: `/card-management/doctor/${cardNo}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
export function batchSubmitCards(cardNos) {
|
||||
return request({
|
||||
url: '/card-management/doctor/batch-submit',
|
||||
method: 'post',
|
||||
data: cardNos,
|
||||
});
|
||||
}
|
||||
|
||||
export function batchDeleteCards(cardNos) {
|
||||
return request({
|
||||
url: '/card-management/doctor/batch-delete',
|
||||
method: 'post',
|
||||
data: cardNos,
|
||||
});
|
||||
}
|
||||
|
||||
export function exportCardToWord(cardNo) {
|
||||
return request({
|
||||
url: `/card-management/doctor/export-word/${cardNo}`,
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
});
|
||||
}
|
||||
|
||||
export function updateDoctorCard(data) {
|
||||
return request({
|
||||
url: '/card-management/doctor/update',
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,745 @@
|
||||
<template>
|
||||
<div class="my-card-management-container">
|
||||
<div class="page-header">
|
||||
<h2>我的报卡</h2>
|
||||
</div>
|
||||
|
||||
<div class="statistics-section">
|
||||
<div class="stat-card total">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Document /></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>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ statistics.pendingFailedCount || 0 }}</div>
|
||||
<div class="stat-label">待处理/失败</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card success">
|
||||
<div class="stat-icon">
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-value">{{ statistics.reportedCount || 0 }}</div>
|
||||
<div class="stat-label">已成功上报</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-section">
|
||||
<el-form :model="queryParams" :inline="true">
|
||||
<el-form-item label="日期范围">
|
||||
<el-date-picker
|
||||
v-model="queryParams.dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="queryParams.status" placeholder="全部状态" clearable style="width: 140px">
|
||||
<el-option label="全部状态" value="" />
|
||||
<el-option label="待提交" value="0" />
|
||||
<el-option label="已提交" value="1" />
|
||||
<el-option label="已审核" value="2" />
|
||||
<el-option label="已上报" value="3" />
|
||||
<el-option label="失败" value="4" />
|
||||
<el-option label="作废" value="6" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关键词">
|
||||
<el-input
|
||||
v-model="queryParams.keyword"
|
||||
placeholder="患者姓名/报卡名称"
|
||||
clearable
|
||||
style="width: 180px"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">
|
||||
<el-icon><Search /></el-icon>
|
||||
应用筛选
|
||||
</el-button>
|
||||
<el-button @click="handleReset">
|
||||
<el-icon><Refresh /></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 class="table-section">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="cardList"
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
stripe
|
||||
>
|
||||
<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">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusType(row.status)" size="small">
|
||||
{{ getStatusName(row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" 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>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-section">
|
||||
<el-pagination
|
||||
v-model:current-page="queryParams.pageNo"
|
||||
v-model:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="getList"
|
||||
@current-change="getList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-model="detailVisible"
|
||||
:title="detailMode === 'view' ? '报卡详情' : '编辑报卡'"
|
||||
width="800px"
|
||||
destroy-on-close
|
||||
>
|
||||
<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="diseaseCategory">
|
||||
<el-select v-model="editForm.diseaseCategory" 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>
|
||||
<el-button @click="detailVisible = false">取消</el-button>
|
||||
<el-button v-if="detailMode === 'edit'" type="primary" @click="handleSaveEdit">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { Document, Clock, CircleCheck, Search, Refresh } from '@element-plus/icons-vue';
|
||||
import {
|
||||
getDoctorCardStatistics,
|
||||
getDoctorCardList,
|
||||
submitCard,
|
||||
withdrawCard,
|
||||
batchSubmitCards,
|
||||
batchDeleteCards,
|
||||
exportCardToWord,
|
||||
getCardDetail,
|
||||
updateDoctorCard,
|
||||
} from './api';
|
||||
|
||||
const loading = ref(false);
|
||||
const cardList = ref([]);
|
||||
const total = ref(0);
|
||||
const selectedRows = ref([]);
|
||||
const isAllSelected = ref(false);
|
||||
|
||||
const statistics = ref({
|
||||
totalCount: 0,
|
||||
pendingFailedCount: 0,
|
||||
reportedCount: 0,
|
||||
});
|
||||
|
||||
const queryParams = reactive({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
dateRange: [],
|
||||
status: '',
|
||||
keyword: '',
|
||||
});
|
||||
|
||||
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 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' },
|
||||
};
|
||||
|
||||
const ageUnitMap = {
|
||||
'1': '岁',
|
||||
'2': '月',
|
||||
'3': '天',
|
||||
};
|
||||
|
||||
function getStatusName(status) {
|
||||
return statusMap[status]?.name || '未知';
|
||||
}
|
||||
|
||||
function getStatusType(status) {
|
||||
return statusMap[status]?.type || 'info';
|
||||
}
|
||||
|
||||
function getAgeUnit(unit) {
|
||||
return ageUnitMap[unit] || '岁';
|
||||
}
|
||||
|
||||
async function getStatistics() {
|
||||
try {
|
||||
const res = await getDoctorCardStatistics();
|
||||
if (res.code === 200) {
|
||||
statistics.value = res.data || {};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = { ...queryParams };
|
||||
if (params.dateRange && params.dateRange.length === 2) {
|
||||
params.startDate = params.dateRange[0];
|
||||
params.endDate = params.dateRange[1];
|
||||
}
|
||||
delete params.dateRange;
|
||||
|
||||
const res = await getDoctorCardList(params);
|
||||
if (res.code === 200) {
|
||||
cardList.value = res.data?.list || [];
|
||||
total.value = res.data?.total || 0;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取列表失败:', error);
|
||||
ElMessage.error('获取数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleQuery() {
|
||||
queryParams.pageNo = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
queryParams.pageNo = 1;
|
||||
queryParams.pageSize = 10;
|
||||
queryParams.dateRange = [];
|
||||
queryParams.status = '';
|
||||
queryParams.keyword = '';
|
||||
getList();
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection) {
|
||||
selectedRows.value = selection;
|
||||
isAllSelected.value = selection.length === cardList.value.length && cardList.value.length > 0;
|
||||
}
|
||||
|
||||
function handleSelectAll(val) {
|
||||
if (val) {
|
||||
selectedRows.value = [...cardList.value];
|
||||
} else {
|
||||
selectedRows.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
async function handleView(row) {
|
||||
try {
|
||||
const res = await getCardDetail(row.cardNo);
|
||||
if (res.code === 200) {
|
||||
currentCard.value = res.data || {};
|
||||
detailMode.value = 'view';
|
||||
detailVisible.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取详情失败');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleEdit(row) {
|
||||
try {
|
||||
const res = await getCardDetail(row.cardNo);
|
||||
if (res.code === 200) {
|
||||
Object.assign(editForm, res.data || {});
|
||||
detailMode.value = 'edit';
|
||||
detailVisible.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('获取详情失败');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSaveEdit() {
|
||||
// 验证表单
|
||||
try {
|
||||
await editFormRef.value.validate();
|
||||
} catch (error) {
|
||||
ElMessage.error('表单验证失败,请检查输入');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const updateData = {
|
||||
cardNo: editForm.cardNo,
|
||||
phone: editForm.phone,
|
||||
onsetDate: editForm.onsetDate,
|
||||
diagDate: editForm.diagDate,
|
||||
diseaseCategory: editForm.diseaseCategory,
|
||||
addressProv: editForm.addressProv,
|
||||
addressCity: editForm.addressCity,
|
||||
addressCounty: editForm.addressCounty,
|
||||
addressHouse: editForm.addressHouse,
|
||||
};
|
||||
|
||||
const res = await updateDoctorCard(updateData);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('保存成功');
|
||||
detailVisible.value = false;
|
||||
getList();
|
||||
} else {
|
||||
ElMessage.error(res.msg || '保存失败');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('保存失败:' + (error.message || '网络错误'));
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit(row) {
|
||||
try {
|
||||
await ElMessageBox.confirm('确认提交该报卡?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
const res = await submitCard(row.cardNo);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('提交成功');
|
||||
getStatistics();
|
||||
getList();
|
||||
} else {
|
||||
ElMessage.error(res.msg || '提交失败');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('提交失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleWithdraw(row) {
|
||||
try {
|
||||
await ElMessageBox.confirm('确认撤回该报卡?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
const res = await withdrawCard(row.cardNo);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('撤回成功');
|
||||
getStatistics();
|
||||
getList();
|
||||
} else {
|
||||
ElMessage.error(res.msg || '撤回失败');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('撤回失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleBatchSubmit() {
|
||||
const validRows = selectedRows.value.filter(row => row.status === '0');
|
||||
if (validRows.length === 0) {
|
||||
ElMessage.warning('只能提交待提交状态的报卡');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认提交选中的 ${validRows.length} 条报卡?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
const cardNos = validRows.map(row => row.cardNo);
|
||||
const res = await batchSubmitCards(cardNos);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success(res.msg || '批量提交成功');
|
||||
getStatistics();
|
||||
getList();
|
||||
} else {
|
||||
ElMessage.error(res.msg || '批量提交失败');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('批量提交失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const validRows = selectedRows.value.filter(row => row.status === '0');
|
||||
if (validRows.length === 0) {
|
||||
ElMessage.warning('只能删除待提交状态的报卡');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认删除选中的 ${validRows.length} 条报卡?删除后状态将变为作废。`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
});
|
||||
const cardNos = validRows.map(row => row.cardNo);
|
||||
const res = await batchDeleteCards(cardNos);
|
||||
if (res.code === 200) {
|
||||
ElMessage.success(res.msg || '批量删除成功');
|
||||
getStatistics();
|
||||
getList();
|
||||
} else {
|
||||
ElMessage.error(res.msg || '批量删除失败');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('批量删除失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleExport(row) {
|
||||
try {
|
||||
const res = await exportCardToWord(row.cardNo);
|
||||
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = `传染病报告卡-${row.cardNo}.docx`;
|
||||
link.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
} catch (error) {
|
||||
ElMessage.error('导出失败');
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getStatistics();
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-card-management-container {
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
min-height: calc(100vh - 84px);
|
||||
}
|
||||
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.page-header h2 {
|
||||
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;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.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;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
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);
|
||||
}
|
||||
|
||||
.action-section {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 12px 20px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.table-section {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.pagination-section {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.statistics-section {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -146,6 +146,7 @@
|
||||
<script setup name="Config">
|
||||
import {reportList, reports} from "./components/report.js";
|
||||
import {formatDateStr} from "@/utils/index.js";
|
||||
import { getCurrentInstance, toRefs } from 'vue';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
@@ -187,30 +188,27 @@ function getList() {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
/** 取消按钮 */
|
||||
function cancel() {
|
||||
open.value = false;
|
||||
reset();
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
authoredTime.value = [
|
||||
formatDateStr(new Date(new Date().setDate(new Date().getDate() - 3)), 'YYYY-MM-DD'),
|
||||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||||
];
|
||||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
/** 表单重置 */
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNo = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
dateRange.value = [];
|
||||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function printReport(row) {
|
||||
reports(row.id).then( response => {
|
||||
|
||||
// TODO: 处理报告打印逻辑
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
getList();
|
||||
</script>
|
||||
|
||||
BIN
scripts/screenshots/consultationApplication_1772771232211.png
Normal file
BIN
scripts/screenshots/consultationApplication_1772771232211.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 314 KiB |
Reference in New Issue
Block a user