Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 920752d36b | |||
| 6dc2a715c8 | |||
| bd50c58dd4 | |||
| e23ac2fd09 | |||
| 4e3ee1f49d | |||
| 2135682332 | |||
| 4ac9254496 | |||
| d4bbc58e4e | |||
| aa193f60a2 | |||
| b74f6bf3f9 | |||
| 9f789cd3a3 | |||
| 4c1222f0f4 | |||
| cfa073bdba | |||
| 021f7180c0 | |||
|
|
ee59fd5ea0 | ||
| 20a372268b | |||
| 31f288c0dd | |||
| 5c97380a78 | |||
| 30e5c92f0b | |||
| 7c6e35dcc3 | |||
| 74b67401f3 | |||
| 81d954fceb | |||
| 7adb3b3ea4 | |||
| 1e6704928a | |||
| 75e49f0237 | |||
| 2b6b00b6c2 | |||
| 1ddf8a2ccd | |||
| 0a37b05aab | |||
| 20817d6dc4 |
44
bug444_analysis.md
Normal file
44
bug444_analysis.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Bug #444 分析报告
|
||||
|
||||
## Bug 描述
|
||||
【手术管理-门诊手术安排】生成临时医嘱界面,"已引用计费药品"列表未正常显示药品详细名称信息,且错误地带出了非药品类的计费信息(如手术诊疗项目"小腿烧伤扩创交腿皮瓣修复术"、检查项目"心脏彩色多普勒超声")。
|
||||
|
||||
## 根因分析
|
||||
|
||||
### 数据流
|
||||
1. 用户点击"医嘱"按钮 → `handleMedicalAdvice()` → 调用 `getPrescriptionList()` 获取计费数据
|
||||
2. 用户对数据进行过滤后展示在"已引用计费药品"列表
|
||||
3. 用户点击"引用计费"按钮 → `handleQuoteBilling()` → 再次调用 `getPrescriptionList()` 获取最新计费数据
|
||||
|
||||
### 根因定位
|
||||
**`handleQuoteBilling()` 方法(index.vue:1866-1877)缺少非药品关键词过滤逻辑。**
|
||||
|
||||
`handleMedicalAdvice()` 中有两层过滤:
|
||||
1. `adviceType !== 1` 过滤(只保留药品类型)
|
||||
2. **关键词排除过滤**(排除名称中包含"术"、"超声"、"检查"等非药品关键词的项目)
|
||||
|
||||
但 `handleQuoteBilling()` 中只有第一层过滤(`adviceType !== 1`),**缺少关键词排除过滤**。
|
||||
|
||||
当后端返回的计费数据中某些非药品项目被错误标注为 `adviceType=1` 时:
|
||||
- `handleMedicalAdvice()` 能通过关键词过滤排除这些项目
|
||||
- `handleQuoteBilling()` 无法排除,导致非药品项目出现在"已引用计费药品"列表中
|
||||
|
||||
### 代码对比
|
||||
|
||||
| 过滤条件 | handleMedicalAdvice (L1576-1597) | handleQuoteBilling (L1866-1877) |
|
||||
|---------|:---:|:---:|
|
||||
| encounterId 匹配 | ✓ | ✓ |
|
||||
| adviceType === 1 | ✓ | ✓ |
|
||||
| 名称非空 | ✓ | ✓ |
|
||||
| **关键词排除** | ✓ **有** | ✗ **缺失** |
|
||||
| requestId 过滤 | ✓ | ✓ |
|
||||
|
||||
## 修复方案
|
||||
|
||||
在 `handleQuoteBilling()` 方法的过滤逻辑中,添加与 `handleMedicalAdvice()` 一致的关键词排除逻辑:
|
||||
|
||||
```javascript
|
||||
// 🔧 修复 Bug #444: 排除名称中包含手术/检查/诊疗关键词的非药品项目
|
||||
const excludedKeywords = ['术', '超声', '多普勒', '检查', '检验', '彩超', 'X线', 'CT', 'MRI', '扫描', '造影'];
|
||||
if (excludedKeywords.some(kw => medicineName.includes(kw))) return false;
|
||||
```
|
||||
@@ -5,37 +5,39 @@
|
||||
|
||||
## 根因定位
|
||||
|
||||
**核心问题在 `OrganizationLocationAppServiceImpl.java:161-174`**
|
||||
**核心问题在 `OrganizationLocationAppServiceImpl.java:161-162`**
|
||||
|
||||
时间冲突检测的查询逻辑存在两个缺陷:
|
||||
时间冲突检测使用了 `getOrgLocListByActivityDefinitionId()` 跨科室查询同一诊疗定义下的**所有**科室配置记录。
|
||||
|
||||
### 缺陷:跨科室误报冲突
|
||||
|
||||
### 缺陷1:查询范围过窄
|
||||
```java
|
||||
// 只查同一科室 + 同一诊疗的记录
|
||||
getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getOrganizationId(), orgLoc.getActivityDefinitionId());
|
||||
// 修复前:查询同一诊疗的所有科室配置(跨科室)
|
||||
organizationLocationService.getOrgLocListByActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
||||
```
|
||||
只查询**同一科室**的记录。如果同一诊疗项目在其他科室已有配置且时间重叠,不会被当前查询检测到。但系统本应阻止同一诊疗在多个科室同时段执行。
|
||||
|
||||
### 缺陷2:"未知科室"错误提示
|
||||
该查询返回**所有科室**中同一诊疗项目的配置记录。当其他科室(非当前操作科室)已配置了相同诊疗且时间重叠时,会被误判为冲突。
|
||||
|
||||
"执行科室配置"的业务语义是:为某个科室配置它可执行的诊疗项目及时段。不同科室配置同一诊疗的不同时段是完全合理的(如检验科 08:00-12:00,放射科 14:00-18:00)。跨科室时间重叠不应视为冲突。
|
||||
|
||||
### 附带缺陷:"未知科室"错误提示
|
||||
当冲突记录关联的科室被软删除(`delete_flag='1'`)时,`organizationService.getById()` 受 `@TableLogic` 注解影响查不到该科室,返回 null,错误提示变成"与未知科室时间冲突"。
|
||||
|
||||
数据库验证发现确实存在软删除科室的组织位置记录(内科门诊、上海学校医院、信息科等,共9条)。
|
||||
|
||||
### 数据流
|
||||
|
||||
1. 前端选择科室 → 点击"添加新项目" → 填写诊疗和时间 → 点击"保存"
|
||||
2. 后端 `addOrEditOrgLoc()` 接收请求
|
||||
3. 查询现有冲突记录(**当前只查同科室**)
|
||||
4. 对冲突记录检查时间重叠
|
||||
5. 查找冲突科室名称 → 若科室被软删除则返回 null → "未知科室"
|
||||
|
||||
## 修复方案
|
||||
|
||||
1. **修改冲突检测范围**:查询同一 `activityDefinitionId` 的所有记录(跨科室检测),而非仅限当前科室
|
||||
2. **优雅处理"未知科室"**:当 `getById` 返回 null 时,使用 "已删除科室( ID )" 替代 "未知科室",提供更有用的信息
|
||||
3. **新增 Service 方法**:`getOrgLocListByActivityDefinitionId(Long activityDefinitionId)` 用于按诊疗定义查询所有记录
|
||||
**修改冲突检测范围**:将 `getOrgLocListByActivityDefinitionId` 改为 `getOrgLocListByOrgIdAndActivityDefinitionId`,仅检测**同一科室内**的时间冲突。
|
||||
|
||||
## 涉及文件
|
||||
- `openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationLocationAppServiceImpl.java`
|
||||
- `openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/service/IOrganizationLocationService.java`
|
||||
- `openhis-server-new/openhis-domain/src/main/java/com/openhis/administration/service/impl/OrganizationLocationServiceImpl.java`
|
||||
## 修复结果
|
||||
|
||||
**修复状态**: ✅ 成功
|
||||
|
||||
**改动行数**: +3/-1(`OrganizationLocationAppServiceImpl.java`)
|
||||
|
||||
**变更内容**:
|
||||
```diff
|
||||
-organizationLocationService.getOrgLocListByActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
||||
+organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getOrganizationId(),
|
||||
+ orgLoc.getActivityDefinitionId());
|
||||
```
|
||||
|
||||
编译验证通过。
|
||||
|
||||
2
his-repo
2
his-repo
Submodule his-repo updated: 515ed84118...5de8a22418
@@ -1,7 +1,9 @@
|
||||
package com.core.framework.config;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
@@ -9,6 +11,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.TimeZone;
|
||||
@@ -24,6 +27,36 @@ import java.util.TimeZone;
|
||||
// 指定要扫描的Mapper类的包的路径
|
||||
@MapperScan({"com.core.**.mapper", "com.openhis.**.mapper"})
|
||||
public class ApplicationConfig {
|
||||
|
||||
/** 支持多种日期格式的反序列化器 */
|
||||
private static final JsonDeserializer<LocalDateTime> LOCAL_DATE_TIME_DESERIALIZER = new JsonDeserializer<LocalDateTime>() {
|
||||
private static final DateTimeFormatter ISO_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
private static final DateTimeFormatter SIMPLE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
private static final DateTimeFormatter SLASH_FORMATTER = DateTimeFormatter.ofPattern("yyyy/M/d HH:mm:ss");
|
||||
|
||||
@Override
|
||||
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
String text = p.getText();
|
||||
if (text == null || text.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// 去除时区后缀 Z/z 和偏移量 +HH:MM/+HHMM(LocalDateTime 不含时区信息)
|
||||
String cleaned = text.replaceAll("[Zz]$", "").replaceAll("[+-]\\d{2}:?\\d{2}$", "");
|
||||
// 尝试 ISO 8601 格式(yyyy-MM-ddTHH:mm:ss.SSS)
|
||||
try {
|
||||
return LocalDateTime.parse(cleaned, ISO_FORMATTER);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// 尝试简单格式(yyyy-MM-dd HH:mm:ss)
|
||||
try {
|
||||
return LocalDateTime.parse(cleaned, SIMPLE_FORMATTER);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// 尝试斜杠格式(yyyy/M/d HH:mm:ss)
|
||||
return LocalDateTime.parse(cleaned, SLASH_FORMATTER);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 时区配置
|
||||
*/
|
||||
@@ -36,7 +69,7 @@ public class ApplicationConfig {
|
||||
builder.simpleDateFormat("yyyy/M/d HH:mm:ss");
|
||||
// 添加JavaTimeModule支持,用于LocalDateTime
|
||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
javaTimeModule.addDeserializer(LocalDateTime.class, LOCAL_DATE_TIME_DESERIALIZER);
|
||||
builder.modules(javaTimeModule);
|
||||
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy/M/d HH:mm:ss")));
|
||||
};
|
||||
|
||||
@@ -199,7 +199,7 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
|
||||
dto.setStatus("已退号");
|
||||
} else {
|
||||
dto.setStatus("已预约");
|
||||
dto.setStatus("已锁定");
|
||||
}
|
||||
} else if (status == SlotStatus.BOOKED) {
|
||||
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
|
||||
@@ -380,7 +380,7 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
||||
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
|
||||
dto.setStatus("已退号");
|
||||
} else {
|
||||
dto.setStatus("已预约");
|
||||
dto.setStatus("已锁定");
|
||||
}
|
||||
} else if (status == SlotStatus.BOOKED) {
|
||||
if (OrderStatus.PATIENT_CANCELLED.getValue().equals(raw.getOrderStatus())) {
|
||||
|
||||
@@ -158,8 +158,10 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
|
||||
? activityDefinitionMapper.selectById(activityDefinitionId) : null;
|
||||
String activityName = activityDef != null ? activityDef.getName() : "";
|
||||
|
||||
// Only check for time conflicts within the same department
|
||||
List<OrganizationLocation> organizationLocationList =
|
||||
organizationLocationService.getOrgLocListByActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
||||
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getOrganizationId(),
|
||||
orgLoc.getActivityDefinitionId());
|
||||
organizationLocationList = (orgLoc.getId() != null)
|
||||
? organizationLocationList.stream().filter(item -> !orgLoc.getId().equals(item.getId())).toList()
|
||||
: organizationLocationList;
|
||||
|
||||
@@ -31,9 +31,4 @@ public class OrgLocQueryParam implements Serializable {
|
||||
/** 发放类别 */
|
||||
private String distributionCategoryCode;
|
||||
|
||||
/**
|
||||
* 项目编码 | 药品:1 耗材:2
|
||||
*/
|
||||
private String itemCode;
|
||||
|
||||
}
|
||||
|
||||
@@ -63,21 +63,17 @@ public interface IDoctorStationEmrAppService {
|
||||
* 获取待写病历列表
|
||||
*
|
||||
* @param doctorId 医生ID
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 每页条数
|
||||
* @param patientName 患者姓名(可选)
|
||||
* @return 待写病历分页数据
|
||||
* @return 待写病历列表
|
||||
*/
|
||||
R<?> getPendingEmrList(Long doctorId, Integer pageNo, Integer pageSize, String patientName);
|
||||
R<?> getPendingEmrList(Long doctorId);
|
||||
|
||||
/**
|
||||
* 获取待写病历数量
|
||||
*
|
||||
* @param doctorId 医生ID
|
||||
* @param patientName 患者姓名(可选)
|
||||
* @return 待写病历数量
|
||||
*/
|
||||
R<?> getPendingEmrCount(Long doctorId, String patientName);
|
||||
R<?> getPendingEmrCount(Long doctorId);
|
||||
|
||||
/**
|
||||
* 检查患者是否需要写病历
|
||||
|
||||
@@ -2205,10 +2205,6 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
||||
// 收费状态
|
||||
requestBaseDto.setChargeStatus_enumText(
|
||||
EnumUtils.getInfoByValue(ChargeItemStatus.class, requestBaseDto.getChargeStatus()));
|
||||
// 单位字典翻译失败时回退使用原始值(如手术申请硬编码了中文单位名)
|
||||
if (StringUtils.isNotBlank(requestBaseDto.getUnitCode()) && StringUtils.isBlank(requestBaseDto.getUnitCode_dictText())) {
|
||||
requestBaseDto.setUnitCode_dictText(requestBaseDto.getUnitCode());
|
||||
}
|
||||
}
|
||||
return R.ok(requestBaseInfo);
|
||||
}
|
||||
@@ -2290,7 +2286,7 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
||||
log.info("BugFix: signOffAdvice - 签退所有请求,状态改为待签发, requestIdList={}", requestIdList);
|
||||
|
||||
// 尝试签退药品请求(只有存在的才会更新)
|
||||
iMedicationRequestService.updateDraftStatusBatch(requestIdList, null, null);
|
||||
iMedicationRequestService.updateDraftStatusBatch(requestIdList, null, null, null);
|
||||
// 尝试签退耗材请求(只有存在的才会更新)
|
||||
iDeviceRequestService.updateDraftStatusBatch(requestIdList);
|
||||
// 尝试签退诊疗请求(只有存在的才会更新)
|
||||
@@ -2347,21 +2343,52 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
||||
.map(UpdateGroupDto::getRequestId).collect(Collectors.toList());
|
||||
|
||||
if (!idsToSetNull.isEmpty()) {
|
||||
// 创建更新条件
|
||||
UpdateWrapper<MedicationRequest> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.set("group_id", null).in("id", idsToSetNull);
|
||||
// 对三个表都执行 group_id/group_no 置空(哪个表有该 id 就更新哪个)
|
||||
UpdateWrapper<MedicationRequest> medUpdateWrapper = new UpdateWrapper<>();
|
||||
medUpdateWrapper.set("group_id", null).in("id", idsToSetNull);
|
||||
iMedicationRequestService.update(medUpdateWrapper);
|
||||
|
||||
// 执行更新
|
||||
iMedicationRequestService.update(updateWrapper);
|
||||
UpdateWrapper<ServiceRequest> srvUpdateWrapper = new UpdateWrapper<>();
|
||||
srvUpdateWrapper.set("group_id", null).in("id", idsToSetNull);
|
||||
iServiceRequestService.update(srvUpdateWrapper);
|
||||
|
||||
// DeviceRequest 使用 group_no(String 类型)
|
||||
UpdateWrapper<DeviceRequest> devUpdateWrapper = new UpdateWrapper<>();
|
||||
devUpdateWrapper.set("group_no", null).in("id", idsToSetNull);
|
||||
iDeviceRequestService.update(devUpdateWrapper);
|
||||
}
|
||||
|
||||
// 处理非null的情况
|
||||
List<MedicationRequest> medicationRequestList = groupList.stream().filter(dto -> dto.getGroupId() != null)
|
||||
.map(dto -> new MedicationRequest().setId(dto.getRequestId()).setGroupId(dto.getGroupId()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!medicationRequestList.isEmpty()) {
|
||||
iMedicationRequestService.saveOrUpdateBatch(medicationRequestList);
|
||||
// 处理 groupId 非 null 的情况:按实际所属表分别更新
|
||||
List<UpdateGroupDto> nonNullGroupList = groupList.stream()
|
||||
.filter(dto -> dto.getGroupId() != null).collect(Collectors.toList());
|
||||
if (!nonNullGroupList.isEmpty()) {
|
||||
for (UpdateGroupDto dto : nonNullGroupList) {
|
||||
Long reqId = dto.getRequestId();
|
||||
Long grpId = dto.getGroupId();
|
||||
// 先尝试药品表(med_medication_request → group_id)
|
||||
MedicationRequest medReq = iMedicationRequestService.getById(reqId);
|
||||
if (medReq != null) {
|
||||
UpdateWrapper<MedicationRequest> uw = new UpdateWrapper<>();
|
||||
uw.set("group_id", grpId).eq("id", reqId);
|
||||
iMedicationRequestService.update(uw);
|
||||
continue;
|
||||
}
|
||||
// 再尝试诊疗表(wor_service_request → group_id)
|
||||
ServiceRequest srvReq = iServiceRequestService.getById(reqId);
|
||||
if (srvReq != null) {
|
||||
UpdateWrapper<ServiceRequest> uw = new UpdateWrapper<>();
|
||||
uw.set("group_id", grpId).eq("id", reqId);
|
||||
iServiceRequestService.update(uw);
|
||||
continue;
|
||||
}
|
||||
// 最后尝试耗材表(wor_device_request → group_no, String 类型)
|
||||
DeviceRequest devReq = iDeviceRequestService.getById(reqId);
|
||||
if (devReq != null) {
|
||||
UpdateWrapper<DeviceRequest> uw = new UpdateWrapper<>();
|
||||
uw.set("group_no", grpId != null ? grpId.toString() : null).eq("id", reqId);
|
||||
iDeviceRequestService.update(uw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.openhis.document.service.IEmrTemplateService;
|
||||
import com.openhis.web.doctorstation.appservice.IDoctorStationEmrAppService;
|
||||
import com.openhis.web.doctorstation.dto.EmrTemplateDto;
|
||||
import com.openhis.web.doctorstation.dto.PatientEmrDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -42,7 +41,6 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 医生站-电子病历 应用实现类
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppService {
|
||||
|
||||
@@ -62,7 +60,13 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
IDocRecordService docRecordService;
|
||||
|
||||
@Resource
|
||||
private com.openhis.web.doctorstation.mapper.DoctorStationEmrAppMapper doctorStationEmrAppMapper;
|
||||
private EncounterMapper encounterMapper;
|
||||
|
||||
@Resource
|
||||
private PatientMapper patientMapper;
|
||||
|
||||
@Resource
|
||||
private com.openhis.administration.mapper.EncounterParticipantMapper encounterParticipantMapper;
|
||||
|
||||
/**
|
||||
* 添加病人病历信息
|
||||
@@ -75,7 +79,7 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
Emr emr = new Emr();
|
||||
BeanUtils.copyProperties(patientEmrDto, emr);
|
||||
String contextStr = patientEmrDto.getContextJson().toString();
|
||||
Emr patientEmr = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, emr.getEncounterId()));
|
||||
Emr patientEmr = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, emr.getEncounterId()).orderByDesc(Emr::getCreateTime).last("LIMIT 1"), false);
|
||||
boolean saveSuccess;
|
||||
// 如果已经保存病历,再次保存走更新
|
||||
if (patientEmr != null) {
|
||||
@@ -122,6 +126,10 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
*/
|
||||
@Override
|
||||
public R<?> getPatientEmrHistory(PatientEmrDto patientEmrDto, Integer pageNo, Integer pageSize) {
|
||||
// 校验参数
|
||||
if (patientEmrDto.getPatientId() == null) {
|
||||
return R.ok(new Page<>(pageNo, pageSize));
|
||||
}
|
||||
Page<Emr> page = emrService.page(new Page<>(pageNo, pageSize),
|
||||
new LambdaQueryWrapper<Emr>().eq(Emr::getPatientId, patientEmrDto.getPatientId()));
|
||||
return R.ok(page);
|
||||
@@ -136,8 +144,12 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
*/
|
||||
@Override
|
||||
public R<?> getEmrDetail(Long encounterId) {
|
||||
// 校验参数
|
||||
if (encounterId == null) {
|
||||
return R.ok(null);
|
||||
}
|
||||
// 先查询门诊病历(emr表)
|
||||
Emr emrDetail = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId));
|
||||
Emr emrDetail = emrService.getOne(new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId).orderByDesc(Emr::getCreateTime).last("LIMIT 1"), false);
|
||||
if (emrDetail != null) {
|
||||
return R.ok(emrDetail);
|
||||
}
|
||||
@@ -147,7 +159,8 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
new LambdaQueryWrapper<DocRecord>()
|
||||
.eq(DocRecord::getEncounterId, encounterId)
|
||||
.orderByDesc(DocRecord::getCreateTime)
|
||||
.last("LIMIT 1")
|
||||
.last("LIMIT 1"),
|
||||
false
|
||||
);
|
||||
if (docRecord != null) {
|
||||
// 住院病历存在,也返回数据
|
||||
@@ -219,29 +232,52 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
* @return 待写病历列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getPendingEmrList(Long doctorId, Integer pageNo, Integer pageSize, String patientName) {
|
||||
// 先查询总数
|
||||
Long total = doctorStationEmrAppMapper.getPendingEmrCount(doctorId, patientName);
|
||||
public R<?> getPendingEmrList(Long doctorId) {
|
||||
// 由于Encounter实体中没有jzPractitionerUserId字段,我们需要通过关联查询来获取相关信息
|
||||
// 使用医生工作站的mapper来查询相关数据
|
||||
// 这里我们直接使用医生工作站的查询逻辑
|
||||
|
||||
// 计算分页偏移量,再查询分页数据
|
||||
int offset = (pageNo - 1) * pageSize;
|
||||
List<Map<String, Object>> pageRows = doctorStationEmrAppMapper.getPendingEmrList(doctorId, patientName, pageSize, offset);
|
||||
// 查询当前医生负责的、状态为"就诊中"但还没有写病历的患者
|
||||
// 需要通过EncounterParticipant表来关联医生信息
|
||||
List<Encounter> encounters = encounterMapper.selectList(
|
||||
new LambdaQueryWrapper<Encounter>()
|
||||
.eq(Encounter::getStatusEnum, EncounterStatus.IN_PROGRESS.getValue())
|
||||
);
|
||||
|
||||
// 计算年龄列
|
||||
for (Map<String, Object> row : pageRows) {
|
||||
Object birthDate = row.get("birthDate");
|
||||
if (birthDate instanceof Date) {
|
||||
row.put("age", calculateAge((Date) birthDate));
|
||||
} else {
|
||||
row.put("age", null);
|
||||
// 过滤出由指定医生负责且还没有写病历的就诊记录
|
||||
List<Map<String, Object>> pendingEmrs = new ArrayList<>();
|
||||
for (Encounter encounter : encounters) {
|
||||
// 检查该就诊记录是否已经有病历
|
||||
Emr existingEmr = emrService.getOne(
|
||||
new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounter.getId()).orderByDesc(Emr::getCreateTime).last("LIMIT 1"), false
|
||||
);
|
||||
|
||||
// 检查该就诊是否由指定医生负责
|
||||
boolean isAssignedToDoctor = isEncounterAssignedToDoctor(encounter.getId(), doctorId);
|
||||
|
||||
if (existingEmr == null && isAssignedToDoctor) {
|
||||
// 如果没有病历且由该医生负责,则添加到待写病历列表
|
||||
Map<String, Object> pendingEmr = new java.util.HashMap<>();
|
||||
|
||||
// 获取患者信息
|
||||
Patient patient = patientMapper.selectById(encounter.getPatientId());
|
||||
|
||||
pendingEmr.put("encounterId", encounter.getId());
|
||||
pendingEmr.put("patientId", encounter.getPatientId());
|
||||
pendingEmr.put("patientName", patient != null ? patient.getName() : "未知");
|
||||
pendingEmr.put("gender", patient != null ? patient.getGenderEnum() : null);
|
||||
// 使用出生日期计算年龄
|
||||
pendingEmr.put("age", patient != null && patient.getBirthDate() != null ?
|
||||
calculateAge(patient.getBirthDate()) : null);
|
||||
// 使用创建时间作为挂号时间
|
||||
pendingEmr.put("registerTime", encounter.getCreateTime());
|
||||
pendingEmr.put("busNo", encounter.getBusNo()); // 病历号
|
||||
|
||||
pendingEmrs.add(pendingEmr);
|
||||
}
|
||||
row.remove("birthDate");
|
||||
}
|
||||
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("rows", pageRows);
|
||||
result.put("total", total != null ? total : 0L);
|
||||
return R.ok(result);
|
||||
return R.ok(pendingEmrs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,9 +287,14 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
* @return 待写病历数量
|
||||
*/
|
||||
@Override
|
||||
public R<?> getPendingEmrCount(Long doctorId, String patientName) {
|
||||
Long count = doctorStationEmrAppMapper.getPendingEmrCount(doctorId, patientName);
|
||||
return R.ok(count != null ? count.intValue() : 0);
|
||||
public R<?> getPendingEmrCount(Long doctorId) {
|
||||
// 获取待写病历列表,然后返回数量
|
||||
R<?> result = getPendingEmrList(doctorId);
|
||||
if (result.getCode() == 200) {
|
||||
List<?> pendingEmrs = (List<?>) result.getData();
|
||||
return R.ok(pendingEmrs.size());
|
||||
}
|
||||
return R.ok(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,7 +307,7 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
public R<?> checkNeedWriteEmr(Long encounterId) {
|
||||
// 检查该就诊记录是否已经有病历
|
||||
Emr existingEmr = emrService.getOne(
|
||||
new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId)
|
||||
new LambdaQueryWrapper<Emr>().eq(Emr::getEncounterId, encounterId).orderByDesc(Emr::getCreateTime).last("LIMIT 1"), false
|
||||
);
|
||||
|
||||
// 如果没有病历,则需要写病历
|
||||
@@ -274,6 +315,24 @@ public class DoctorStationEmrAppServiceImpl implements IDoctorStationEmrAppServi
|
||||
return R.ok(needWrite);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查就诊是否分配给指定医生
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param doctorId 医生ID
|
||||
* @return 是否分配给指定医生
|
||||
*/
|
||||
private boolean isEncounterAssignedToDoctor(Long encounterId, Long doctorId) {
|
||||
// 查询就诊参与者表,检查是否有指定医生的接诊记录
|
||||
com.openhis.administration.domain.EncounterParticipant participant =
|
||||
encounterParticipantMapper.selectOne(
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.openhis.administration.domain.EncounterParticipant>()
|
||||
.eq(com.openhis.administration.domain.EncounterParticipant::getEncounterId, encounterId)
|
||||
.eq(com.openhis.administration.domain.EncounterParticipant::getPractitionerId, doctorId)
|
||||
);
|
||||
|
||||
return participant != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据出生日期计算年龄
|
||||
|
||||
@@ -77,10 +77,8 @@ public class DoctorStationAdviceController {
|
||||
*/
|
||||
@PostMapping(value = "/save-advice")
|
||||
@RepeatSubmit(interval = 5000, message = "请勿重复提交医嘱,请稍候再试")
|
||||
public R<?> saveAdvice(@RequestBody AdviceSaveParam adviceSaveParam,
|
||||
@RequestParam(required = false, defaultValue = "1") String adviceOpType) {
|
||||
// 🔧 Bug #445 修复:使用前端传入的 adviceOpType 参数(1=保存草稿,2=签发),而非硬编码
|
||||
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, adviceOpType);
|
||||
public R<?> saveAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
|
||||
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, AdviceOpType.SAVE_ADVICE.getCode());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,36 +26,34 @@ public class PendingEmrController {
|
||||
* 获取待写病历列表
|
||||
*
|
||||
* @param doctorId 医生ID
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 每页条数
|
||||
* @param patientName 患者姓名(可选)
|
||||
* @return 待写病历分页数据
|
||||
* @return 待写病历列表
|
||||
*/
|
||||
@GetMapping("/pending-list")
|
||||
public R<?> getPendingEmrList(@RequestParam(required = false) Long doctorId,
|
||||
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String patientName) {
|
||||
public R<?> getPendingEmrList(@RequestParam(required = false) Long doctorId) {
|
||||
// 如果没有传递医生ID,则使用当前登录用户ID
|
||||
if (doctorId == null) {
|
||||
doctorId = com.core.common.utils.SecurityUtils.getLoginUser().getPractitionerId();
|
||||
doctorId = com.core.common.utils.SecurityUtils.getLoginUser().getUserId();
|
||||
}
|
||||
return iDoctorStationEmrAppService.getPendingEmrList(doctorId, pageNum, pageSize, patientName);
|
||||
|
||||
// 调用服务获取待写病历列表
|
||||
return iDoctorStationEmrAppService.getPendingEmrList(doctorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待写病历数量
|
||||
*
|
||||
* @param doctorId 医生ID
|
||||
* @param patientName 患者姓名(可选)
|
||||
* @return 待写病历数量
|
||||
*/
|
||||
@GetMapping("/pending-count")
|
||||
public R<?> getPendingEmrCount(@RequestParam(required = false) Long doctorId,
|
||||
@RequestParam(required = false) String patientName) {
|
||||
public R<?> getPendingEmrCount(@RequestParam(required = false) Long doctorId) {
|
||||
// 如果没有传递医生ID,则使用当前登录用户ID
|
||||
if (doctorId == null) {
|
||||
doctorId = com.core.common.utils.SecurityUtils.getLoginUser().getPractitionerId();
|
||||
doctorId = com.core.common.utils.SecurityUtils.getLoginUser().getUserId();
|
||||
}
|
||||
return iDoctorStationEmrAppService.getPendingEmrCount(doctorId, patientName);
|
||||
|
||||
// 调用服务获取待写病历数量
|
||||
return iDoctorStationEmrAppService.getPendingEmrCount(doctorId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -198,10 +198,8 @@ public class AdviceBaseDto {
|
||||
/**
|
||||
* 所属科室
|
||||
*/
|
||||
@Dict(dictTable = "adm_organization", dictCode = "id", dictText = "name")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long orgId;
|
||||
private String orgId_dictText;
|
||||
|
||||
/**
|
||||
* 所在位置
|
||||
|
||||
@@ -8,10 +8,6 @@ import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonSetter;
|
||||
import com.fasterxml.jackson.annotation.Nulls;
|
||||
|
||||
@@ -30,14 +26,6 @@ public class AdviceSaveDto {
|
||||
/** 医嘱类型 */
|
||||
private Integer adviceType; // 1:药品 , 2: 耗材 , 3:项目
|
||||
|
||||
/**
|
||||
* 医嘱开始时间
|
||||
*/
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
|
||||
/**
|
||||
* 请求id
|
||||
*/
|
||||
|
||||
@@ -63,18 +63,6 @@ public class PatientDetailsDto {
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/** 地址省 */
|
||||
private String addressProvince;
|
||||
|
||||
/** 地址市 */
|
||||
private String addressCity;
|
||||
|
||||
/** 地址区 */
|
||||
private String addressDistrict;
|
||||
|
||||
/** 地址街道 */
|
||||
private String addressStreet;
|
||||
|
||||
/**
|
||||
* 工作单位
|
||||
*/
|
||||
|
||||
@@ -22,12 +22,6 @@ public class RequestBaseDto {
|
||||
*/
|
||||
private Integer adviceType; // 1:药品 , 2: 耗材 , 3:项目
|
||||
|
||||
/**
|
||||
* 医嘱开始时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 唯一标识
|
||||
*/
|
||||
@@ -127,11 +121,11 @@ public class RequestBaseDto {
|
||||
* 请求状态
|
||||
*/
|
||||
private Integer statusEnum;
|
||||
|
||||
/**
|
||||
* 退回原因
|
||||
*/
|
||||
private String reasonText;
|
||||
|
||||
private String statusEnum_enumText;
|
||||
|
||||
/**
|
||||
@@ -249,15 +243,4 @@ public class RequestBaseDto {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long patientId;
|
||||
|
||||
/**
|
||||
* 停嘱医生
|
||||
*/
|
||||
private String stopUserName;
|
||||
|
||||
/**
|
||||
* 停嘱时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date stopTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,11 @@
|
||||
package com.openhis.web.doctorstation.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 医生站-电子病历 应用Mapper
|
||||
*/
|
||||
@Repository
|
||||
public interface DoctorStationEmrAppMapper {
|
||||
|
||||
List<Map<String, Object>> getPendingEmrList(@Param("doctorId") Long doctorId,
|
||||
@Param("patientName") String patientName,
|
||||
@Param("pageSize") Integer pageSize,
|
||||
@Param("offset") Integer offset);
|
||||
|
||||
Long getPendingEmrCount(@Param("doctorId") Long doctorId,
|
||||
@Param("patientName") String patientName);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,8 @@ import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.*;
|
||||
import java.util.*;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -178,24 +180,11 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
inpatientAdviceParam.setEncounterIds(null);
|
||||
Integer exeStatus = inpatientAdviceParam.getExeStatus();
|
||||
inpatientAdviceParam.setExeStatus(null);
|
||||
// 提取requestStatus手动处理,支持COMPLETED(3)和CHECK_VERIFIED(10)同时查询
|
||||
Integer requestStatus = inpatientAdviceParam.getRequestStatus();
|
||||
inpatientAdviceParam.setRequestStatus(null);
|
||||
// requestStatus由前端tab传入,通过QueryWrapper自动添加到SQL外层WHERE过滤
|
||||
// 构建查询条件
|
||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||
|
||||
// 手动拼接requestStatus条件:COMPLETED(3)时同时包含CHECK_VERIFIED(10)
|
||||
// UNION查询外层列名为request_status(T1.status_enum AS request_status),不是status_enum
|
||||
if (requestStatus != null) {
|
||||
if (RequestStatus.COMPLETED.getValue().equals(requestStatus)) {
|
||||
queryWrapper.in("request_status",
|
||||
RequestStatus.COMPLETED.getValue(), RequestStatus.CHECK_VERIFIED.getValue());
|
||||
} else {
|
||||
queryWrapper.eq("request_status", requestStatus);
|
||||
}
|
||||
}
|
||||
|
||||
// 手动拼接住院患者id条件
|
||||
if (encounterIds != null && !encounterIds.isEmpty()) {
|
||||
List<Long> encounterIdList
|
||||
@@ -245,38 +234,48 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
}
|
||||
}
|
||||
|
||||
// 手动处理前端传来的执行条件
|
||||
if (exeStatus != null) {
|
||||
// 处理执行记录状态
|
||||
for (InpatientAdviceDto inpatientAdvice : inpatientAdviceList) {
|
||||
List<PerformRecordDto> performRecordList = procedureRecordGroup.get(inpatientAdvice.getRequestId());
|
||||
List<PerformRecordDto> exePerformRecordList = new ArrayList<>();
|
||||
List<PerformRecordDto> cancelPerformRecordList = new ArrayList<>();
|
||||
List<PerformRecordDto> stopPerformRecordList = new ArrayList<>();
|
||||
if (performRecordList != null && !performRecordList.isEmpty()) {
|
||||
// 按时间分组,处理每个时间点的多条记录
|
||||
Map<String, List<PerformRecordDto>> recordsByTime = performRecordList.stream()
|
||||
.collect(Collectors.groupingBy(record -> record.getOccurrenceTime().toString()));
|
||||
for (Map.Entry<String, List<PerformRecordDto>> entry : recordsByTime.entrySet()) {
|
||||
List<PerformRecordDto> records = entry.getValue();
|
||||
// 按操作顺序排序
|
||||
records.sort(Comparator.comparing(PerformRecordDto::getCreateTime));
|
||||
// 取最后一条记录,最终状态由最后一次操作决定
|
||||
PerformRecordDto lastRecord = records.get(records.size() - 1);
|
||||
if (EventStatus.COMPLETED.getValue().equals(lastRecord.getStatusEnum())) {
|
||||
exePerformRecordList.add(lastRecord);
|
||||
} else if (EventStatus.CANCEL.getValue().equals(lastRecord.getStatusEnum())) {
|
||||
cancelPerformRecordList.add(lastRecord);
|
||||
} else if (EventStatus.STOPPED.getValue().equals(lastRecord.getStatusEnum())) {
|
||||
stopPerformRecordList.add(lastRecord);
|
||||
}
|
||||
// 为所有医嘱计算执行记录状态(所有页签都需要展示执行进度)
|
||||
for (InpatientAdviceDto inpatientAdvice : inpatientAdviceList) {
|
||||
List<PerformRecordDto> performRecordList = procedureRecordGroup.get(inpatientAdvice.getRequestId());
|
||||
List<PerformRecordDto> exePerformRecordList = new ArrayList<>();
|
||||
List<PerformRecordDto> cancelPerformRecordList = new ArrayList<>();
|
||||
List<PerformRecordDto> stopPerformRecordList = new ArrayList<>();
|
||||
if (performRecordList != null && !performRecordList.isEmpty()) {
|
||||
// 按时间分组,处理每个时间点的多条记录
|
||||
Map<String, List<PerformRecordDto>> recordsByTime = performRecordList.stream()
|
||||
.collect(Collectors.groupingBy(record -> record.getOccurrenceTime().toString()));
|
||||
for (Map.Entry<String, List<PerformRecordDto>> entry : recordsByTime.entrySet()) {
|
||||
List<PerformRecordDto> records = entry.getValue();
|
||||
// 按操作顺序排序
|
||||
records.sort(Comparator.comparing(PerformRecordDto::getCreateTime));
|
||||
// 取最后一条记录,最终状态由最后一次操作决定
|
||||
PerformRecordDto lastRecord = records.get(records.size() - 1);
|
||||
if (EventStatus.COMPLETED.getValue().equals(lastRecord.getStatusEnum())) {
|
||||
exePerformRecordList.add(lastRecord);
|
||||
} else if (EventStatus.CANCEL.getValue().equals(lastRecord.getStatusEnum())) {
|
||||
cancelPerformRecordList.add(lastRecord);
|
||||
} else if (EventStatus.STOPPED.getValue().equals(lastRecord.getStatusEnum())) {
|
||||
stopPerformRecordList.add(lastRecord);
|
||||
}
|
||||
}
|
||||
inpatientAdvice.setExePerformRecordList(exePerformRecordList)
|
||||
.setCancelPerformRecordList(cancelPerformRecordList)
|
||||
.setStopPerformRecordList(stopPerformRecordList);
|
||||
}
|
||||
inpatientAdvice.setExePerformRecordList(exePerformRecordList)
|
||||
.setCancelPerformRecordList(cancelPerformRecordList)
|
||||
.setStopPerformRecordList(stopPerformRecordList);
|
||||
// 计算综合执行状态文本
|
||||
if (!exePerformRecordList.isEmpty()) {
|
||||
inpatientAdvice.setOverallStatusText("已执行");
|
||||
} else if (!cancelPerformRecordList.isEmpty()) {
|
||||
inpatientAdvice.setOverallStatusText("已取消执行");
|
||||
} else if (!stopPerformRecordList.isEmpty()) {
|
||||
inpatientAdvice.setOverallStatusText("已停止");
|
||||
} else {
|
||||
inpatientAdvice.setOverallStatusText(inpatientAdvice.getRequestStatus_enumText());
|
||||
}
|
||||
}
|
||||
|
||||
// 手动处理前端传来的执行条件
|
||||
if (exeStatus != null) {
|
||||
// 根据执行状态过滤医嘱列表
|
||||
List<InpatientAdviceDto> filteredList = new ArrayList<>();
|
||||
if (EventStatus.COMPLETED.getValue().equals(exeStatus)) {
|
||||
@@ -328,29 +327,19 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
Date checkDate = new Date();
|
||||
if (!serviceRequestList.isEmpty()) {
|
||||
List<Long> serviceReqIds = serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
||||
// 先查询服务请求,按 categoryEnum 分流:检查类(23)走 CHECK_VERIFIED,其余走 COMPLETED
|
||||
List<ServiceRequest> allServiceRequests = serviceRequestService.listByIds(serviceReqIds);
|
||||
List<Long> checkReqIds = allServiceRequests.stream()
|
||||
.filter(sr -> ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
List<Long> otherReqIds = allServiceRequests.stream()
|
||||
.filter(sr -> !ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
// 检查类 → 已校对(CHECK_VERIFIED=10)
|
||||
if (!checkReqIds.isEmpty()) {
|
||||
serviceRequestService.updateCheckVerifiedStatus(checkReqIds, practitionerId, checkDate);
|
||||
}
|
||||
// 其他类 → 已完成(COMPLETED=3)
|
||||
if (!otherReqIds.isEmpty()) {
|
||||
serviceRequestService.updateCompleteRequestStatus(otherReqIds, practitionerId, checkDate);
|
||||
}
|
||||
// 处理转科/出院等特殊医嘱
|
||||
for (ServiceRequest serviceRequest : allServiceRequests) {
|
||||
// 更新服务请求状态已完成
|
||||
serviceRequestService.updateCompleteRequestStatus(
|
||||
serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList(), practitionerId, checkDate);
|
||||
List<ServiceRequest> serviceRequests = serviceRequestService
|
||||
.listByIds(serviceRequestList.stream().map(PerformInfoDto::getRequestId).collect(Collectors.toList()));
|
||||
for (ServiceRequest serviceRequest : serviceRequests) {
|
||||
// 判断医嘱类型
|
||||
if (ActivityDefCategory.TRANSFER.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
// 更新患者状态 待转科
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.PENDING_TRANSFER.getValue());
|
||||
} else if (ActivityDefCategory.DISCHARGE.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
// 更新患者状态 待出院
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.AWAITING_DISCHARGE.getValue());
|
||||
}
|
||||
@@ -382,23 +371,28 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
medRequestList.add(item);
|
||||
}
|
||||
}
|
||||
// 校验医嘱是否已执行,已执行的医嘱需要先取消执行后才能退回
|
||||
List<Long> allRequestIds = performInfoList.stream().map(PerformInfoDto::getRequestId).toList();
|
||||
List<Procedure> allProcedures = procedureService.list(
|
||||
new LambdaQueryWrapper<Procedure>()
|
||||
.in(Procedure::getRequestId, allRequestIds)
|
||||
.eq(Procedure::getDeleteFlag, "0"));
|
||||
Set<Long> executedIds = allProcedures.stream()
|
||||
.filter(p -> EventStatus.COMPLETED.getValue().equals(p.getStatusEnum()))
|
||||
.map(Procedure::getId)
|
||||
.collect(Collectors.toSet());
|
||||
Set<Long> cancelledRefundIds = allProcedures.stream()
|
||||
.filter(p -> EventStatus.CANCEL.getValue().equals(p.getStatusEnum()) && p.getRefundId() != null)
|
||||
.map(Procedure::getRefundId)
|
||||
.collect(Collectors.toSet());
|
||||
executedIds.removeAll(cancelledRefundIds);
|
||||
if (!executedIds.isEmpty()) {
|
||||
return R.fail("该医嘱已执行,请先取消执行后再退回");
|
||||
// 校验医嘱是否已执行,已执行的医嘱不允许退回
|
||||
List<PerformInfoDto> allRequestList = new ArrayList<>();
|
||||
allRequestList.addAll(serviceRequestList);
|
||||
allRequestList.addAll(medRequestList);
|
||||
if (!allRequestList.isEmpty()) {
|
||||
// 按requestTable分组查询执行记录
|
||||
Map<String, List<Long>> requestTableIdMap = allRequestList.stream()
|
||||
.collect(Collectors.groupingBy(PerformInfoDto::getRequestTable,
|
||||
Collectors.mapping(PerformInfoDto::getRequestId, Collectors.toList())));
|
||||
for (Map.Entry<String, List<Long>> entry : requestTableIdMap.entrySet()) {
|
||||
String requestTable = entry.getKey();
|
||||
List<Long> requestIds = entry.getValue();
|
||||
List<Procedure> executedProcedures = procedureService.list(
|
||||
new LambdaQueryWrapper<Procedure>()
|
||||
.in(Procedure::getRequestId, requestIds)
|
||||
.eq(Procedure::getRequestTable, requestTable)
|
||||
.eq(Procedure::getStatusEnum, EventStatus.COMPLETED.getValue())
|
||||
.eq(Procedure::getCategoryEnum, ProcedureCategory.INPATIENT_ADVICE.getValue()));
|
||||
if (!executedProcedures.isEmpty()) {
|
||||
return R.fail("所选医嘱中存在已执行的医嘱,请先在【医嘱执行】界面取消执行后再退回");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 校验药品医嘱是否已发药,已发药的医嘱不允许退回
|
||||
if (!medRequestList.isEmpty()) {
|
||||
@@ -413,9 +407,14 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
}
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
Date checkDate = new Date();
|
||||
// 从请求中提取退回原因(所有项目共享同一原因)
|
||||
String backReason = performInfoList.stream()
|
||||
.map(PerformInfoDto::getBackReason)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (!serviceRequestList.isEmpty()) {
|
||||
// 更新服务请求状态待发送
|
||||
String backReason = performInfoList.get(0).getBackReason();
|
||||
serviceRequestService.updateDraftStatus(
|
||||
serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList(), practitionerId, checkDate, backReason);
|
||||
}
|
||||
@@ -466,15 +465,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
List<ServiceRequestUseExe> actUseExeList = this.assemblyActivity(activityList);
|
||||
// 处理诊疗执行
|
||||
this.exeActivity(actUseExeList, exeDate);
|
||||
// 检查类医嘱执行后,状态改为"待接收"(PENDING_RECEIVE=11)
|
||||
List<Long> actReqIds = activityList.stream().map(AdviceExecuteDetailParam::getRequestId).toList();
|
||||
List<ServiceRequest> executedReqs = serviceRequestService.listByIds(actReqIds);
|
||||
List<Long> checkReqIds = executedReqs.stream()
|
||||
.filter(sr -> ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
if (!checkReqIds.isEmpty()) {
|
||||
serviceRequestService.updatePendingReceiveStatus(checkReqIds);
|
||||
}
|
||||
}
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"医嘱执行"}));
|
||||
|
||||
@@ -78,10 +78,12 @@ public class MedicineSummaryAppServiceImpl implements IMedicineSummaryAppService
|
||||
.map(notPerformedReason -> new DispenseInitDto.NotPerformedReasonOption(notPerformedReason.getValue(),
|
||||
notPerformedReason.getInfo()))
|
||||
.collect(Collectors.toList());
|
||||
// 发药状态(汇总单:待配药→已提交,已发放→已发药)
|
||||
// 发药状态
|
||||
List<DispenseStatusOption> dispenseStatusOptions = new ArrayList<>();
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.PREPARATION.getValue(), "已提交"));
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.COMPLETED.getValue(), "已发药"));
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.PREPARATION.getValue(),
|
||||
DispenseStatus.PREPARATION.getInfo()));
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.COMPLETED.getInfo()));
|
||||
|
||||
initDto.setNotPerformedReasonOptions(notPerformedReasonOptions).setDispenseStatusOptions(dispenseStatusOptions);
|
||||
return R.ok(initDto);
|
||||
@@ -159,8 +161,8 @@ public class MedicineSummaryAppServiceImpl implements IMedicineSummaryAppService
|
||||
new Page<>(pageNo, pageSize), queryWrapper, DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.PREPARATION.getValue(), SupplyType.SUMMARY_DISPENSE.getValue());
|
||||
medicineSummaryFormPage.getRecords().forEach(e -> {
|
||||
// 发药状态(汇总单展示文案)
|
||||
e.setStatusEnum_enumText(getSummaryFormStatusText(e.getStatusEnum()));
|
||||
// 发药状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(DispenseStatus.class, e.getStatusEnum()));
|
||||
});
|
||||
return R.ok(medicineSummaryFormPage);
|
||||
}
|
||||
@@ -290,17 +292,4 @@ public class MedicineSummaryAppServiceImpl implements IMedicineSummaryAppService
|
||||
}
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"取消"}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总发药单状态展示文案(药品医嘱状态映射表:汇总申请→已提交,发药→已发药)
|
||||
*/
|
||||
private String getSummaryFormStatusText(Integer statusEnum) {
|
||||
if (DispenseStatus.PREPARATION.getValue().equals(statusEnum)) {
|
||||
return "已提交";
|
||||
}
|
||||
if (DispenseStatus.COMPLETED.getValue().equals(statusEnum)) {
|
||||
return "已发药";
|
||||
}
|
||||
return EnumUtils.getInfoByValue(DispenseStatus.class, statusEnum);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,9 @@ public class InpatientAdviceDto {
|
||||
private Integer requestStatus;
|
||||
private String requestStatus_enumText;
|
||||
|
||||
/** 综合执行状态(结合请求状态和执行记录计算) */
|
||||
private String overallStatusText;
|
||||
|
||||
/** 是否皮试 */
|
||||
private Integer skinTestFlag;
|
||||
private String skinTestFlag_enumText;
|
||||
|
||||
@@ -256,7 +256,7 @@ public class OutpatientInfusionAppServiceImpl implements IOutpatientInfusionAppS
|
||||
}
|
||||
boolean result = serviceRequestService.updateCancelledStatus(serviceReqId, now, practitionerId, orgId);
|
||||
// 更新主服务请求状态为待执行
|
||||
serviceRequestService.updateDraftStatus(List.of(serviceRequest.getBasedOnId()), null, null);
|
||||
serviceRequestService.updateDraftStatus(List.of(serviceRequest.getBasedOnId()), null, null, null);
|
||||
if (result) {
|
||||
// 判断是否全部取消执行
|
||||
boolean exists = serviceRequestMapper.exists(new LambdaQueryWrapper<ServiceRequest>()
|
||||
|
||||
@@ -86,12 +86,7 @@ public class OutpatientRecordServiceImpl implements IOutpatientRecordService {
|
||||
|
||||
// 处理就诊对象状态筛选
|
||||
if (outpatientRecordSearchParam.getSubjectStatusEnum() != null) {
|
||||
if (outpatientRecordSearchParam.getSubjectStatusEnum() == 0) {
|
||||
// 前端选择"无状态"(0)时,过滤 status_enum IS NULL 的记录
|
||||
queryWrapper.isNull("enc.status_enum");
|
||||
} else {
|
||||
queryWrapper.eq("enc.status_enum", outpatientRecordSearchParam.getSubjectStatusEnum());
|
||||
}
|
||||
queryWrapper.eq("enc.status_enum", outpatientRecordSearchParam.getSubjectStatusEnum());
|
||||
}
|
||||
|
||||
// 处理医生姓名查询(支持模糊查询)
|
||||
|
||||
@@ -69,12 +69,4 @@ public interface IAdviceManageAppService {
|
||||
*/
|
||||
R<?> stopRegAdvice(List<AdviceBatchOpParam> paramList);
|
||||
|
||||
/**
|
||||
* 住院医嘱取消停嘱(恢复)
|
||||
*
|
||||
* @param paramList 恢复参数
|
||||
* @return 结果
|
||||
*/
|
||||
R<?> cancelStopRegAdvice(List<AdviceBatchOpParam> paramList);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import com.openhis.common.constant.PromptMsgConstant;
|
||||
import com.openhis.common.enums.*;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.medication.domain.MedicationDispense;
|
||||
import com.openhis.medication.domain.MedicationRequest;
|
||||
import com.openhis.medication.service.IMedicationDispenseService;
|
||||
import com.openhis.medication.service.IMedicationRequestService;
|
||||
@@ -416,7 +415,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
}
|
||||
// 保存时处理的字段属性
|
||||
if (is_save) {
|
||||
longMedicationRequest.setEffectiveDoseStart(regAdviceSaveDto.getStartTime() != null ? regAdviceSaveDto.getStartTime() : startTime); // 医嘱开始时间
|
||||
longMedicationRequest.setEffectiveDoseStart(startTime); // 医嘱开始时间
|
||||
longMedicationRequest
|
||||
.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.MEDICATION_RES_NO.getPrefix(), 4));
|
||||
longMedicationRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
@@ -504,7 +503,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
}
|
||||
// 保存时处理的字段属性
|
||||
if (is_save) {
|
||||
tempMedicationRequest.setEffectiveDoseStart(regAdviceSaveDto.getStartTime() != null ? regAdviceSaveDto.getStartTime() : startTime); // 医嘱开始时间
|
||||
tempMedicationRequest.setEffectiveDoseStart(startTime); // 医嘱开始时间
|
||||
tempMedicationRequest
|
||||
.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.MEDICATION_RES_NO.getPrefix(), 4));
|
||||
tempMedicationRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
@@ -616,7 +615,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
}
|
||||
// 保存时处理的字段属性
|
||||
if (is_save) {
|
||||
longServiceRequest.setOccurrenceStartTime(regAdviceSaveDto.getStartTime() != null ? regAdviceSaveDto.getStartTime() : startTime); // 医嘱开始时间
|
||||
longServiceRequest.setOccurrenceStartTime(startTime); // 医嘱开始时间
|
||||
longServiceRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.SERVICE_RES_NO.getPrefix(), 4));
|
||||
longServiceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
longServiceRequest.setQuantity(new BigDecimal("1")); // 请求数量 | 诊疗的长期医嘱数量都是1
|
||||
@@ -628,7 +627,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
longServiceRequest.setPatientId(regAdviceSaveDto.getPatientId()); // 患者
|
||||
longServiceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
|
||||
longServiceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
|
||||
longServiceRequest.setOrgId(regAdviceSaveDto.getPositionId()); // 执行科室
|
||||
longServiceRequest.setOrgId(regAdviceSaveDto.getEffectiveOrgId()); // 执行科室
|
||||
longServiceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json
|
||||
longServiceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码
|
||||
longServiceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id
|
||||
@@ -667,7 +666,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
}
|
||||
// 保存时处理的字段属性
|
||||
if (is_save) {
|
||||
tempServiceRequest.setOccurrenceStartTime(regAdviceSaveDto.getStartTime() != null ? regAdviceSaveDto.getStartTime() : startTime); // 医嘱开始时间
|
||||
tempServiceRequest.setOccurrenceStartTime(startTime); // 医嘱开始时间
|
||||
tempServiceRequest.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.SERVICE_RES_NO.getPrefix(), 4));
|
||||
tempServiceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue()); // 生成来源
|
||||
tempServiceRequest.setQuantity(regAdviceSaveDto.getQuantity()); // 请求数量
|
||||
@@ -679,7 +678,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
tempServiceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
|
||||
tempServiceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
|
||||
tempServiceRequest.setAuthoredTime(curDate); // 请求签发时间
|
||||
tempServiceRequest.setOrgId(regAdviceSaveDto.getPositionId()); // 执行科室
|
||||
tempServiceRequest.setOrgId(regAdviceSaveDto.getEffectiveOrgId()); // 执行科室
|
||||
tempServiceRequest.setContentJson(regAdviceSaveDto.getContentJson()); // 请求内容json
|
||||
tempServiceRequest.setYbClassEnum(regAdviceSaveDto.getYbClassEnum());// 类别医保编码
|
||||
tempServiceRequest.setConditionId(regAdviceSaveDto.getConditionId()); // 诊断id
|
||||
@@ -813,7 +812,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
deviceRequest.setPatientId(regAdviceSaveDto.getPatientId()); // 患者
|
||||
deviceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
|
||||
deviceRequest.setOrgId(regAdviceSaveDto.getFounderOrgId()); // 开方人科室
|
||||
deviceRequest.setReqAuthoredTime(regAdviceSaveDto.getStartTime() != null ? regAdviceSaveDto.getStartTime() : startTime); // 医嘱开始时间
|
||||
deviceRequest.setReqAuthoredTime(startTime); // 医嘱开始时间
|
||||
deviceRequest.setPerformLocation(regAdviceSaveDto.getLocationId()); // 发放科室
|
||||
deviceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
|
||||
deviceRequest.setPackageId(regAdviceSaveDto.getPackageId()); // 组套id
|
||||
@@ -852,7 +851,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
deviceRequest.setPatientId(regAdviceSaveDto.getPatientId()); // 患者
|
||||
deviceRequest.setRequesterId(regAdviceSaveDto.getPractitionerId()); // 开方医生
|
||||
deviceRequest.setOrgId(regAdviceSaveDto.getFounderOrgId()); // 开方人科室
|
||||
deviceRequest.setReqAuthoredTime(regAdviceSaveDto.getStartTime() != null ? regAdviceSaveDto.getStartTime() : startTime); // 医嘱开始时间
|
||||
deviceRequest.setReqAuthoredTime(startTime); // 医嘱开始时间
|
||||
deviceRequest.setPerformLocation(regAdviceSaveDto.getLocationId()); // 发放科室
|
||||
deviceRequest.setEncounterId(regAdviceSaveDto.getEncounterId()); // 就诊id
|
||||
deviceRequest.setPackageId(regAdviceSaveDto.getPackageId()); // 组套id
|
||||
@@ -1017,7 +1016,7 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
}
|
||||
if (!medicineRequestIds.isEmpty()) {
|
||||
// 根据请求id更新请求状态
|
||||
iMedicationRequestService.updateDraftStatusBatch(medicineRequestIds, null, null);
|
||||
iMedicationRequestService.updateDraftStatusBatch(medicineRequestIds, null, null, null);
|
||||
}
|
||||
if (!activityRequestIds.isEmpty()) {
|
||||
// 根据请求id更新请求状态
|
||||
@@ -1044,14 +1043,8 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
*/
|
||||
@Override
|
||||
public R<?> stopRegAdvice(List<AdviceBatchOpParam> paramList) {
|
||||
// 获取停嘱时间:优先从前端传入的 stopTime,否则用当前时间
|
||||
Date stopTime = paramList.stream()
|
||||
.map(AdviceBatchOpParam::getStopTime)
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(new Date());
|
||||
// 获取当前操作用户昵称作为停嘱医生
|
||||
String stopUserName = SecurityUtils.getNickName();
|
||||
// 当前时间
|
||||
Date date = new Date();
|
||||
// 药品
|
||||
List<AdviceBatchOpParam> medicineList = paramList.stream()
|
||||
.filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())).collect(Collectors.toList());
|
||||
@@ -1066,112 +1059,15 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
||||
= activityList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList());
|
||||
if (!medicineRequestIds.isEmpty()) {
|
||||
iMedicationRequestService.update(new LambdaUpdateWrapper<MedicationRequest>()
|
||||
.in(MedicationRequest::getId, medicineRequestIds)
|
||||
.set(MedicationRequest::getEffectiveDoseEnd, stopTime)
|
||||
.set(MedicationRequest::getStatusEnum, RequestStatus.STOPPED.getValue())
|
||||
.set(MedicationRequest::getUpdateBy, stopUserName));
|
||||
.in(MedicationRequest::getId, medicineRequestIds).set(MedicationRequest::getEffectiveDoseEnd, date)
|
||||
.set(MedicationRequest::getStatusEnum, RequestStatus.STOPPED.getValue()));
|
||||
}
|
||||
if (!activityRequestIds.isEmpty()) {
|
||||
iServiceRequestService.update(new LambdaUpdateWrapper<ServiceRequest>()
|
||||
.in(ServiceRequest::getId, activityRequestIds)
|
||||
.set(ServiceRequest::getOccurrenceEndTime, stopTime)
|
||||
.set(ServiceRequest::getStatusEnum, RequestStatus.STOPPED.getValue())
|
||||
.set(ServiceRequest::getUpdateBy, stopUserName));
|
||||
.in(ServiceRequest::getId, activityRequestIds).set(ServiceRequest::getOccurrenceEndTime, date)
|
||||
.set(ServiceRequest::getStatusEnum, RequestStatus.STOPPED.getValue()));
|
||||
}
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"医嘱停止"}));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 住院医嘱取消停嘱(恢复)
|
||||
*
|
||||
* 核心业务逻辑:
|
||||
* 1. 护士站校验:护士站尚未对该医嘱的停止进行"停止核对/确认"(即 dispense 状态未进入已发药/完成状态)
|
||||
* 2. 药房端校验:药房尚未对该停嘱单进行退药接收/退费入库确认
|
||||
* 3. 若校验通过,将医嘱状态复原为"已签发";清空停嘱时间与停嘱医生字段;
|
||||
* 同时自动作废已生成的待发药退回/退药申请
|
||||
*
|
||||
* @param paramList 恢复参数
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> cancelStopRegAdvice(List<AdviceBatchOpParam> paramList) {
|
||||
// 药品
|
||||
List<AdviceBatchOpParam> medicineList = paramList.stream()
|
||||
.filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())).collect(Collectors.toList());
|
||||
List<Long> medicineRequestIds
|
||||
= medicineList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList());
|
||||
// 诊疗(包含护理adviceType=26)
|
||||
List<AdviceBatchOpParam> activityList = paramList.stream()
|
||||
.filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType())
|
||||
|| (e.getAdviceType() != null && e.getAdviceType() == 26))
|
||||
.collect(Collectors.toList());
|
||||
List<Long> activityRequestIds
|
||||
= activityList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList());
|
||||
|
||||
// ============ 前置校验 ============
|
||||
// 1. 护士站校验:查询药品发放记录,确认护士站是否已执行停止核对(发药)
|
||||
if (!medicineRequestIds.isEmpty()) {
|
||||
List<MedicationDispense> dispenseList = iMedicationDispenseService.selectByRequestIdList(medicineRequestIds);
|
||||
for (MedicationDispense dispense : dispenseList) {
|
||||
// 如果发放状态 >= COMPLETED(4),说明护士站已发药/已确认停止
|
||||
if (dispense.getStatusEnum() != null && dispense.getStatusEnum() >= DispenseStatus.COMPLETED.getValue()
|
||||
&& !DispenseStatus.ON_HOLD.getValue().equals(dispense.getStatusEnum())
|
||||
&& !DispenseStatus.STOPPED.getValue().equals(dispense.getStatusEnum())
|
||||
&& !DispenseStatus.CANCELLED.getValue().equals(dispense.getStatusEnum())) {
|
||||
throw new ServiceException("护士站已确认停止该医嘱,无法取消停嘱!");
|
||||
}
|
||||
// 2. 药房端校验:如果已有退药/退费记录,说明药房已处理
|
||||
if (DispenseStatus.RETURNED.getValue().equals(dispense.getStatusEnum())
|
||||
|| DispenseStatus.REFUNDED.getValue().equals(dispense.getStatusEnum())
|
||||
|| DispenseStatus.PART_REFUND.getValue().equals(dispense.getStatusEnum())) {
|
||||
throw new ServiceException("药房已完成退药处理,无法取消停嘱!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 执行恢复 ============
|
||||
if (!medicineRequestIds.isEmpty()) {
|
||||
// 恢复药品请求状态为"已发送"(ACTIVE=2),清空停嘱时间和更新人
|
||||
iMedicationRequestService.update(new LambdaUpdateWrapper<MedicationRequest>()
|
||||
.in(MedicationRequest::getId, medicineRequestIds)
|
||||
.set(MedicationRequest::getStatusEnum, RequestStatus.ACTIVE.getValue())
|
||||
.set(MedicationRequest::getEffectiveDoseEnd, null)
|
||||
.set(MedicationRequest::getUpdateBy, null));
|
||||
|
||||
// 作废/删除与这些药品请求相关的待退药发放记录
|
||||
List<MedicationDispense> relatedDispenseList = iMedicationDispenseService.selectByRequestIdList(medicineRequestIds);
|
||||
for (MedicationDispense dispense : relatedDispenseList) {
|
||||
if (DispenseStatus.PENDING_REFUND.getValue().equals(dispense.getStatusEnum())
|
||||
|| DispenseStatus.CANCELLED.getValue().equals(dispense.getStatusEnum())
|
||||
|| DispenseStatus.ON_HOLD.getValue().equals(dispense.getStatusEnum())) {
|
||||
// 将待退药/暂停/撤回的记录标记为草稿,或删除
|
||||
iMedicationDispenseService.update(new LambdaUpdateWrapper<MedicationDispense>()
|
||||
.eq(MedicationDispense::getId, dispense.getId())
|
||||
.set(MedicationDispense::getStatusEnum, DispenseStatus.DRAFT.getValue())
|
||||
.set(MedicationDispense::getStatusChangedTime, new Date()));
|
||||
}
|
||||
// 如果 dispense 已处于 STOPPED(6) 状态,也恢复为草稿以重新触发配药流程
|
||||
if (DispenseStatus.STOPPED.getValue().equals(dispense.getStatusEnum())) {
|
||||
iMedicationDispenseService.update(new LambdaUpdateWrapper<MedicationDispense>()
|
||||
.eq(MedicationDispense::getId, dispense.getId())
|
||||
.set(MedicationDispense::getStatusEnum, DispenseStatus.PREPARATION.getValue())
|
||||
.set(MedicationDispense::getStatusChangedTime, new Date()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!activityRequestIds.isEmpty()) {
|
||||
// 恢复诊疗请求状态为"已发送"(ACTIVE=2),清空停嘱时间和更新人
|
||||
iServiceRequestService.update(new LambdaUpdateWrapper<ServiceRequest>()
|
||||
.in(ServiceRequest::getId, activityRequestIds)
|
||||
.set(ServiceRequest::getStatusEnum, RequestStatus.ACTIVE.getValue())
|
||||
.set(ServiceRequest::getOccurrenceEndTime, null)
|
||||
.set(ServiceRequest::getUpdateBy, null));
|
||||
}
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"医嘱恢复"}));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.enums.DelFlag;
|
||||
import com.core.common.exception.ServiceException;
|
||||
import com.core.common.utils.AssignSeqUtil;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
@@ -18,8 +17,6 @@ import com.openhis.common.constant.PromptMsgConstant;
|
||||
import com.openhis.common.enums.*;
|
||||
import com.openhis.document.domain.RequestForm;
|
||||
import com.openhis.document.service.IRequestFormService;
|
||||
import com.openhis.lab.domain.Specimen;
|
||||
import com.openhis.lab.service.ISpecimenService;
|
||||
import com.openhis.web.doctorstation.dto.ActivityChildrenJsonParams;
|
||||
import com.openhis.web.doctorstation.utils.AdviceUtils;
|
||||
import com.openhis.web.regdoctorstation.appservice.IRequestFormManageAppService;
|
||||
@@ -70,39 +67,6 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
@Resource
|
||||
IActivityDefinitionService iActivityDefinitionService;
|
||||
|
||||
@Resource
|
||||
ISpecimenService iSpecimenService;
|
||||
|
||||
/**
|
||||
* 校验当前用户是否有权操作该申请单(申请者本人或管理员)
|
||||
*/
|
||||
private R<?> validateRequestFormPermission(RequestForm requestForm) {
|
||||
if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
|
||||
return null;
|
||||
}
|
||||
Long currentPractitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
Long requesterId = requestForm.getRequesterId();
|
||||
if (currentPractitionerId == null || requesterId == null
|
||||
|| !currentPractitionerId.equals(requesterId)) {
|
||||
return R.fail("无操作权限,仅申请开立者或管理员可操作");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验关联医嘱是否已采证(存在已采集/已接收标本则不可撤回)
|
||||
*/
|
||||
private boolean hasCollectedSpecimen(List<Long> serviceRequestIds) {
|
||||
if (serviceRequestIds == null || serviceRequestIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
long count = iSpecimenService.count(
|
||||
new LambdaQueryWrapper<Specimen>()
|
||||
.in(Specimen::getServiceId, serviceRequestIds)
|
||||
.ge(Specimen::getCollectionStatusEnum, SpecCollectStatus.COLLECTED.getValue()));
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存申请单
|
||||
*
|
||||
@@ -155,13 +119,10 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
return R.fail("无待签发的医嘱,该申请单不可编辑");
|
||||
}
|
||||
} else {
|
||||
// 根据申请单类型生成不同前缀的单号
|
||||
// 检查申请单号:JC(检查)+ Z(住院标识)+ yyMMdd(日期)+ 5位顺序号
|
||||
String dateStr = new java.text.SimpleDateFormat("yyMMdd").format(new Date());
|
||||
AssignSeqEnum seqEnum = ActivityDefCategory.PROCEDURE.getCode().equals(typeCode)
|
||||
? AssignSeqEnum.SURGERY_APPLY_NO
|
||||
: AssignSeqEnum.CHECK_APPLY_NO;
|
||||
int seq = assignSeqUtil.getSeqNoByDay(seqEnum.getPrefix());
|
||||
prescriptionNo = seqEnum.getPrefix() + dateStr + String.format("%05d", seq);
|
||||
int seq = assignSeqUtil.getSeqNoByDay(AssignSeqEnum.CHECK_APPLY_NO.getPrefix());
|
||||
prescriptionNo = "JCZ" + dateStr + String.format("%05d", seq);
|
||||
}
|
||||
|
||||
// 当前时间
|
||||
@@ -567,17 +528,12 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
if (requestForm == null) {
|
||||
return R.fail("申请单不存在");
|
||||
}
|
||||
R<?> permissionResult = validateRequestFormPermission(requestForm);
|
||||
if (permissionResult != null) {
|
||||
return permissionResult;
|
||||
}
|
||||
String prescriptionNo = requestForm.getPrescriptionNo();
|
||||
|
||||
// 查询该申请单下所有 ServiceRequest(含子项)
|
||||
List<ServiceRequest> serviceRequests = iServiceRequestService.list(
|
||||
new LambdaQueryWrapper<ServiceRequest>()
|
||||
.eq(ServiceRequest::getPrescriptionNo, prescriptionNo)
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
.eq(ServiceRequest::getPrescriptionNo, prescriptionNo));
|
||||
if (serviceRequests == null || serviceRequests.isEmpty()) {
|
||||
return R.fail("未找到关联的诊疗医嘱");
|
||||
}
|
||||
@@ -607,7 +563,7 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
// 4. 删除申请单
|
||||
iRequestFormService.removeById(requestFormId);
|
||||
|
||||
log.info("检验申请单删除成功,requestFormId={}, prescriptionNo={}", requestFormId, prescriptionNo);
|
||||
log.info("检查申请单删除成功,requestFormId={}, prescriptionNo={}", requestFormId, prescriptionNo);
|
||||
return R.ok("删除成功");
|
||||
}
|
||||
|
||||
@@ -620,47 +576,32 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
||||
if (requestForm == null) {
|
||||
return R.fail("申请单不存在");
|
||||
}
|
||||
R<?> permissionResult = validateRequestFormPermission(requestForm);
|
||||
if (permissionResult != null) {
|
||||
return permissionResult;
|
||||
}
|
||||
String prescriptionNo = requestForm.getPrescriptionNo();
|
||||
|
||||
// 查询该申请单下所有 ServiceRequest
|
||||
List<ServiceRequest> serviceRequests = iServiceRequestService.list(
|
||||
new LambdaQueryWrapper<ServiceRequest>()
|
||||
.eq(ServiceRequest::getPrescriptionNo, prescriptionNo)
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
.eq(ServiceRequest::getPrescriptionNo, prescriptionNo));
|
||||
if (serviceRequests == null || serviceRequests.isEmpty()) {
|
||||
return R.fail("未找到关联的诊疗医嘱");
|
||||
}
|
||||
|
||||
// 校验:只有已签发(status=2)的申请单可撤回
|
||||
boolean allActive = serviceRequests.stream()
|
||||
.allMatch(sr -> RequestStatus.ACTIVE.getValue().equals(sr.getStatusEnum()));
|
||||
if (!allActive) {
|
||||
return R.fail("只有已签发状态的申请单可撤回");
|
||||
}
|
||||
|
||||
// 将所有 ServiceRequest 状态改回待签发(DRAFT=0)
|
||||
List<Long> serviceRequestIds = serviceRequests.stream()
|
||||
.map(ServiceRequest::getId).collect(Collectors.toList());
|
||||
|
||||
// 校验:标本已采集则不可撤回
|
||||
if (hasCollectedSpecimen(serviceRequestIds)) {
|
||||
return R.fail("标本已采集,无法撤回");
|
||||
}
|
||||
|
||||
// 校验:任一ServiceRequest为ACTIVE(status=2)即可撤回,与SQL的EXISTS逻辑一致
|
||||
boolean hasActive = serviceRequests.stream()
|
||||
.anyMatch(sr -> RequestStatus.ACTIVE.getValue().equals(sr.getStatusEnum()));
|
||||
if (!hasActive) {
|
||||
return R.fail("只有已签发且未采证的申请单可撤回");
|
||||
}
|
||||
|
||||
// 将所有已签发的 ServiceRequest 状态改回待签发,与申请单展示状态同步
|
||||
boolean updated = iServiceRequestService.update(
|
||||
iServiceRequestService.update(
|
||||
new ServiceRequest().setStatusEnum(RequestStatus.DRAFT.getValue()),
|
||||
new LambdaUpdateWrapper<ServiceRequest>()
|
||||
.in(ServiceRequest::getId, serviceRequestIds)
|
||||
.eq(ServiceRequest::getStatusEnum, RequestStatus.ACTIVE.getValue()));
|
||||
if (!updated) {
|
||||
return R.fail("撤回失败,医嘱状态已变更,请刷新后重试");
|
||||
}
|
||||
.in(ServiceRequest::getId, serviceRequestIds));
|
||||
|
||||
log.info("检验申请单撤回成功,requestFormId={}, prescriptionNo={}", requestFormId, prescriptionNo);
|
||||
log.info("检查申请单撤回成功,requestFormId={}, prescriptionNo={}", requestFormId, prescriptionNo);
|
||||
return R.ok("撤回成功");
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -162,7 +161,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
adviceBaseDto.setAdviceDefinitionId(definitionId); // 医嘱定义id
|
||||
// 对应的诊疗医嘱信息
|
||||
activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, null, null,
|
||||
null, null, 1, 1, null, List.of(3), null, null).getRecords().get(0);
|
||||
null, null, 1, 1, Whether.NO.getValue(), List.of(3), null, null).getRecords().get(0);
|
||||
// 逻辑1---------------------直接新增
|
||||
longServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());// 请求状态
|
||||
longServiceRequest.setOccurrenceStartTime(startTime); // 医嘱开始时间
|
||||
@@ -209,7 +208,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
adviceBaseDto.setAdviceDefinitionId(definitionId); // 医嘱定义id
|
||||
// 对应的诊疗医嘱信息
|
||||
activityAdviceBaseDto = iDoctorStationAdviceAppService
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, null, List.of(3), null, null)
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, Whether.NO.getValue(), List.of(3), null, null)
|
||||
.getRecords().get(0);
|
||||
|
||||
longServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());// 请求状态
|
||||
@@ -349,7 +348,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
adviceBaseDto.setAdviceDefinitionId(transferOrganizationDefinitionId); // 医嘱定义id
|
||||
// 转科的医嘱信息
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, null, List.of(3), null, null)
|
||||
.getAdviceBaseInfo(adviceBaseDto, null, null, null, null, 1, 1, Whether.NO.getValue(), List.of(3), null, null)
|
||||
.getRecords().get(0);
|
||||
// 保存转科医嘱请求
|
||||
ServiceRequest serviceRequest = new ServiceRequest();
|
||||
@@ -401,7 +400,7 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
// 计划出院时间
|
||||
Date endTime = leaveHospitalParam.getEndTime();
|
||||
if (endTime == null) {
|
||||
endTime = new Date();
|
||||
endTime = endTime;
|
||||
}
|
||||
// 就诊id
|
||||
Long encounterId = leaveHospitalParam.getEncounterId();
|
||||
@@ -430,12 +429,9 @@ public class SpecialAdviceAppServiceImpl implements ISpecialAdviceAppService {
|
||||
}
|
||||
|
||||
// 出院的医嘱信息
|
||||
List<AdviceBaseDto> adviceList = iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||
List.of(transferOrganizationDefinitionId), null, 1, 1, null, List.of(3), null, null).getRecords();
|
||||
if (CollectionUtils.isEmpty(adviceList)) {
|
||||
return R.fail("未找到出院医嘱定义数据,请确认诊疗目录中已配置出院医嘱");
|
||||
}
|
||||
AdviceBaseDto activityAdviceBaseDto = adviceList.get(0);
|
||||
AdviceBaseDto activityAdviceBaseDto = iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
|
||||
List.of(transferOrganizationDefinitionId), null, 1, 1, Whether.NO.getValue(), List.of(3), null, null).getRecords()
|
||||
.get(0);
|
||||
// 保存出院医嘱请求
|
||||
ServiceRequest serviceRequest = new ServiceRequest();
|
||||
serviceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());// 请求状态
|
||||
|
||||
@@ -143,15 +143,4 @@ public class AdviceManageController {
|
||||
return iAdviceManageAppService.stopRegAdvice(paramList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 住院医嘱取消停嘱(恢复)
|
||||
*
|
||||
* @param paramList 恢复参数
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping(value = "/cancel-stop-reg-advice")
|
||||
public R<?> cancelStopRegAdvice(@RequestBody List<AdviceBatchOpParam> paramList) {
|
||||
return iAdviceManageAppService.cancelStopRegAdvice(paramList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -143,23 +143,14 @@ public class RequestFormManageController {
|
||||
* 查询手术申请单
|
||||
*
|
||||
* @param encounterId 就诊id
|
||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||
* @param status 单据状态(可选)
|
||||
* @param keyword 关键字(可选,申请单号/手术项目名称模糊匹配)
|
||||
* @return 手术申请单
|
||||
*/
|
||||
@GetMapping(value = "/get-surgery")
|
||||
public R<?> getSurgeryRequestForm(
|
||||
@RequestParam(required = false) Long encounterId,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) String keyword) {
|
||||
public R<?> getSurgeryRequestForm(@RequestParam(required = false) Long encounterId) {
|
||||
if (encounterId == null) {
|
||||
return R.fail("就诊ID不能为空");
|
||||
}
|
||||
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.PROCEDURE.getCode(), startDate, endDate, status, keyword));
|
||||
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.PROCEDURE.getCode()));
|
||||
}
|
||||
/**
|
||||
* 分页查询手术申请单(全局,不需要encounterId,用于门诊手术安排查找弹窗)
|
||||
@@ -203,8 +194,8 @@ public class RequestFormManageController {
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping(value = "/delete")
|
||||
public R<?> deleteRequestForm(@RequestBody Map<String, Object> data) {
|
||||
return iRequestFormManageAppService.deleteRequestForm(parseLong(data.get("requestFormId")));
|
||||
public R<?> deleteRequestForm(@RequestBody Map<String, Long> data) {
|
||||
return iRequestFormManageAppService.deleteRequestForm(data.get("requestFormId"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,24 +205,7 @@ public class RequestFormManageController {
|
||||
* @return 结果
|
||||
*/
|
||||
@PostMapping(value = "/withdraw")
|
||||
public R<?> withdrawRequestForm(@RequestBody Map<String, Object> data) {
|
||||
return iRequestFormManageAppService.withdrawRequestForm(parseLong(data.get("requestFormId")));
|
||||
}
|
||||
|
||||
private Long parseLong(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Long) {
|
||||
return (Long) value;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(value.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
public R<?> withdrawRequestForm(@RequestBody Map<String, Long> data) {
|
||||
return iRequestFormManageAppService.withdrawRequestForm(data.get("requestFormId"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package com.openhis.web.regdoctorstation.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 医嘱批量操作参数类
|
||||
*/
|
||||
@@ -24,10 +21,4 @@ public class AdviceBatchOpParam {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long requestId;
|
||||
|
||||
/**
|
||||
* 停嘱时间
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date stopTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,4 @@ import lombok.experimental.Accessors;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class RegAdviceSaveDto extends AdviceSaveDto {
|
||||
|
||||
/** 请求类型 */
|
||||
private Integer categoryEnum;
|
||||
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ public class HomeController {
|
||||
HomeStatisticsDto statisticsDto = homeStatisticsService.getHomeStatistics();
|
||||
|
||||
// 获取待写病历数量
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
R<?> pendingEmrCount = doctorStationEmrAppService.getPendingEmrCount(practitionerId, null);
|
||||
Long userId = SecurityUtils.getLoginUser().getUserId();
|
||||
R<?> pendingEmrCount = doctorStationEmrAppService.getPendingEmrCount(userId);
|
||||
|
||||
// 将待写病历数量添加到统计数据中
|
||||
statisticsDto.setPendingEmr((Integer) pendingEmrCount.getData());
|
||||
|
||||
@@ -74,6 +74,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getQueueDate, qd)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.ne(TriageQueueItem::getStatus, TriageQueueStatus.COMPLETED.getValue())
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder);
|
||||
|
||||
// 如果指定了科室,按科室过滤;否则查询所有科室(全科模式)
|
||||
@@ -91,6 +92,14 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 双重保险:再次过滤掉 COMPLETED 状态的患者(防止数据库中有异常数据)
|
||||
if (list != null && !list.isEmpty()) {
|
||||
int beforeSize = list.size();
|
||||
list = list.stream()
|
||||
.filter(item -> !TriageQueueStatus.COMPLETED.getValue().equals(item.getStatus()))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
|
||||
@@ -586,9 +586,6 @@
|
||||
WHERE T1.delete_flag = '0'
|
||||
AND T1.service_table = #{MED_MEDICATION_REQUEST}
|
||||
<if test="historyFlag == '0'.toString()">
|
||||
<if test="generateSourceEnum != null">
|
||||
AND (T2.generate_source_enum IS NULL OR T2.generate_source_enum = #{generateSourceEnum})
|
||||
</if>
|
||||
AND T1.encounter_id = #{encounterId}
|
||||
</if>
|
||||
<if test="historyFlag == '1'.toString()">
|
||||
@@ -902,6 +899,7 @@
|
||||
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
|
||||
</if>
|
||||
ORDER BY t1.ID, t1.name ASC, t2.ID ASC
|
||||
LIMIT #{limit} OFFSET #{offset}
|
||||
</select>
|
||||
|
||||
<!-- 检查/检验项目专用分页查询:仅查指定 category_code + 定价,无库存/草稿库存/取药科室等无关逻辑 -->
|
||||
|
||||
@@ -4,38 +4,4 @@
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.openhis.web.doctorstation.mapper.DoctorStationEmrAppMapper">
|
||||
|
||||
<select id="getPendingEmrList" resultType="java.util.HashMap">
|
||||
SELECT e.id AS "encounterId",
|
||||
e.patient_id AS "patientId",
|
||||
p.name AS "patientName",
|
||||
p.gender_enum AS "gender",
|
||||
p.birth_date AS "birthDate",
|
||||
e.create_time AS "registerTime",
|
||||
e.bus_no AS "busNo"
|
||||
FROM adm_encounter e
|
||||
INNER JOIN adm_encounter_participant ep ON e.id = ep.encounter_id AND ep.practitioner_id = #{doctorId}
|
||||
LEFT JOIN adm_patient p ON e.patient_id = p.id
|
||||
LEFT JOIN doc_emr emr ON e.id = emr.encounter_id
|
||||
WHERE e.status_enum = 2
|
||||
AND emr.id IS NULL
|
||||
<if test="patientName != null and patientName != ''">
|
||||
AND p.name LIKE CONCAT('%', #{patientName}, '%')
|
||||
</if>
|
||||
ORDER BY e.create_time DESC
|
||||
LIMIT #{pageSize} OFFSET #{offset}
|
||||
</select>
|
||||
|
||||
<select id="getPendingEmrCount" resultType="java.lang.Long">
|
||||
SELECT COUNT(*)
|
||||
FROM adm_encounter e
|
||||
INNER JOIN adm_encounter_participant ep ON e.id = ep.encounter_id AND ep.practitioner_id = #{doctorId}
|
||||
LEFT JOIN adm_patient p ON e.patient_id = p.id
|
||||
LEFT JOIN doc_emr emr ON e.id = emr.encounter_id
|
||||
WHERE e.status_enum = 2
|
||||
AND emr.id IS NULL
|
||||
<if test="patientName != null and patientName != ''">
|
||||
AND p.name LIKE CONCAT('%', #{patientName}, '%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -11,10 +11,6 @@
|
||||
p.birth_date,
|
||||
p.phone,
|
||||
p.address,
|
||||
p.address_province,
|
||||
p.address_city,
|
||||
p.address_district,
|
||||
p.address_street,
|
||||
p.work_company,
|
||||
p.nationality_code,
|
||||
p.marital_status_enum,
|
||||
|
||||
@@ -214,13 +214,10 @@
|
||||
T1.dispense_per_duration AS dispense_per_duration,
|
||||
T2.part_percent AS part_percent,
|
||||
ccd.name AS condition_definition_name,
|
||||
T1.effective_dose_start AS start_time,
|
||||
T1.therapy_enum AS therapyEnum,
|
||||
T1.sort_number AS sort_number,
|
||||
T1.based_on_id AS based_on_id,
|
||||
T1.medication_id AS advice_definition_id
|
||||
T1.effective_dose_end AS stop_time,
|
||||
T1.update_by AS stop_user_name
|
||||
FROM med_medication_request AS T1
|
||||
LEFT JOIN med_medication_definition AS T2 ON T2.ID = T1.medication_id
|
||||
AND T2.delete_flag = '0'
|
||||
@@ -272,11 +269,8 @@
|
||||
'' AS condition_definition_name,
|
||||
2 AS therapyEnum,
|
||||
99 AS sort_number,
|
||||
T1.req_authored_time AS start_time,
|
||||
T1.based_on_id AS based_on_id,
|
||||
T1.device_def_id AS advice_definition_id
|
||||
NULL AS stop_time,
|
||||
'' AS stop_user_name
|
||||
FROM wor_device_request AS T1
|
||||
LEFT JOIN adm_device_definition AS T2 ON T2.ID = T1.device_def_id
|
||||
AND T2.delete_flag = '0'
|
||||
@@ -325,11 +319,8 @@
|
||||
'' AS condition_definition_name,
|
||||
COALESCE(T1.therapy_enum, 2) AS therapyEnum,
|
||||
99 AS sort_number,
|
||||
T1.occurrence_start_time AS start_time,
|
||||
T1.based_on_id AS based_on_id,
|
||||
T1.activity_id AS advice_definition_id
|
||||
T1.occurrence_end_time AS stop_time,
|
||||
T1.update_by AS stop_user_name
|
||||
FROM wor_service_request AS T1
|
||||
LEFT JOIN wor_activity_definition AS T2
|
||||
ON T2.ID = T1.activity_id
|
||||
|
||||
@@ -35,36 +35,21 @@
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 8
|
||||
) THEN 6
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 5
|
||||
) THEN 7
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 3
|
||||
) THEN 5
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 12
|
||||
) THEN 4
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 11
|
||||
) THEN 3
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 10
|
||||
) THEN 2
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 2
|
||||
) THEN 1
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 5
|
||||
) THEN 7
|
||||
ELSE 0
|
||||
END AS computed_status
|
||||
FROM doc_request_form AS drf
|
||||
|
||||
@@ -274,10 +274,6 @@ public enum AssignSeqEnum {
|
||||
* 检查申请单号(住院)
|
||||
*/
|
||||
CHECK_APPLY_NO("72", "检查申请单号", "JCZ"),
|
||||
/**
|
||||
* 手术申请单号(住院)
|
||||
*/
|
||||
SURGERY_APPLY_NO("73", "手术申请单号", "SSZ"),
|
||||
/**
|
||||
* b 病历文书
|
||||
*/
|
||||
|
||||
@@ -57,22 +57,7 @@ public enum RequestStatus implements HisEnumInterface {
|
||||
/**
|
||||
* 未知
|
||||
*/
|
||||
UNKNOWN(9, "unknown", "未知"),
|
||||
|
||||
/**
|
||||
* 已校对(检查申请:护士校对通过)
|
||||
*/
|
||||
CHECK_VERIFIED(10, "check_verified", "已校对"),
|
||||
|
||||
/**
|
||||
* 待接收(检查申请:等待医技科室接单)
|
||||
*/
|
||||
PENDING_RECEIVE(11, "pending_receive", "待接收"),
|
||||
|
||||
/**
|
||||
* 已接收(检查申请:医技科室已接单)
|
||||
*/
|
||||
CHECK_RECEIVED(12, "check_received", "已接收");
|
||||
UNKNOWN(9, "unknown", "未知");
|
||||
|
||||
@EnumValue
|
||||
private final Integer value;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.lab.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
@@ -106,10 +107,12 @@ public class InspectionPackage {
|
||||
|
||||
/** 创建时间 */
|
||||
@TableField("create_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
@TableField("update_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/** 删除标志(false-正常,true-删除) */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.lab.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
@@ -75,10 +76,12 @@ public class InspectionPackageDetail {
|
||||
|
||||
/** 创建时间 */
|
||||
@TableField("create_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
@TableField("update_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/** 删除标志(false-正常,true-删除) */
|
||||
|
||||
@@ -78,9 +78,6 @@ public class MedicationRequestServiceImpl extends ServiceImpl<MedicationRequestM
|
||||
if (checkDate != null) {
|
||||
updateWrapper.set(MedicationRequest::getCheckTime, checkDate);
|
||||
}
|
||||
if (backReason != null) {
|
||||
updateWrapper.set(MedicationRequest::getBackReason, backReason);
|
||||
}
|
||||
baseMapper.update(null, updateWrapper);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,22 +39,6 @@ public interface IServiceRequestService extends IService<ServiceRequest> {
|
||||
*/
|
||||
void updateCompleteRequestStatus(List<Long> serReqIdList, Long practitionerId, Date checkDate);
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:已校对(护士校对检查申请后状态为CHECK_VERIFIED,而非COMPLETED)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
* @param practitionerId 校对人
|
||||
* @param checkDate 校对时间
|
||||
*/
|
||||
void updateCheckVerifiedStatus(List<Long> serReqIdList, Long practitionerId, Date checkDate);
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:待接收(护士执行检查申请后状态为PENDING_RECEIVE)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
*/
|
||||
void updatePendingReceiveStatus(List<Long> serReqIdList);
|
||||
|
||||
/**
|
||||
* 获取执行过的诊疗数据
|
||||
*
|
||||
|
||||
@@ -66,31 +66,6 @@ public class ServiceRequestServiceImpl extends ServiceImpl<ServiceRequestMapper,
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:已校对(护士校对检查申请后状态为CHECK_VERIFIED,而非COMPLETED)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
*/
|
||||
@Override
|
||||
public void updateCheckVerifiedStatus(List<Long> serReqIdList, Long practitionerId, Date checkDate) {
|
||||
baseMapper.update(new ServiceRequest().setStatusEnum(RequestStatus.CHECK_VERIFIED.getValue())
|
||||
.setPerformerCheckId(SecurityUtils.getLoginUser().getPractitionerId()).setCheckTime(DateUtils.getNowDate()),
|
||||
new LambdaUpdateWrapper<ServiceRequest>().in(ServiceRequest::getId, serReqIdList)
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:待接收(护士执行检查申请后状态为PENDING_RECEIVE)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
*/
|
||||
@Override
|
||||
public void updatePendingReceiveStatus(List<Long> serReqIdList) {
|
||||
baseMapper.update(new ServiceRequest().setStatusEnum(RequestStatus.PENDING_RECEIVE.getValue()),
|
||||
new LambdaUpdateWrapper<ServiceRequest>().in(ServiceRequest::getId, serReqIdList)
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行过的诊疗数据
|
||||
*
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
-- Bug #613: 医嘱退回流程 — med_medication_request 表缺少退回原因字段
|
||||
-- 退回原因必填(NOT NULL),前端弹窗 + 后端都做校验
|
||||
-- 执行前检查:如果列已存在则跳过
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'med_medication_request' AND column_name = 'back_reason'
|
||||
) THEN
|
||||
ALTER TABLE med_medication_request ADD COLUMN back_reason VARCHAR(500) NOT NULL DEFAULT '';
|
||||
COMMENT ON COLUMN med_medication_request.back_reason IS '退回原因(必填)';
|
||||
ELSE
|
||||
-- 列已存在,确保 NOT NULL
|
||||
ALTER TABLE med_medication_request ALTER COLUMN back_reason SET NOT NULL;
|
||||
ALTER TABLE med_medication_request ALTER COLUMN back_reason SET DEFAULT '';
|
||||
ALTER TABLE med_medication_request ADD COLUMN back_reason VARCHAR(500) DEFAULT NULL;
|
||||
COMMENT ON COLUMN med_medication_request.back_reason IS '退回原因';
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
77
openhis-ui-vue3/package-lock.json
generated
77
openhis-ui-vue3/package-lock.json
generated
@@ -65,7 +65,7 @@
|
||||
"typescript": "^5.9.3",
|
||||
"unplugin-auto-import": "0.17.1",
|
||||
"unplugin-vue-setup-extend-plus": "1.0.0",
|
||||
"vite": "^5.0.4",
|
||||
"vite": "5.0.4",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vite-plugin-vue-mcp": "^0.3.2",
|
||||
@@ -3093,6 +3093,41 @@
|
||||
"url": "https://opencollective.com/vitest"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@vitest/mocker/-/mocker-4.1.2.tgz",
|
||||
"integrity": "sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vitest/spy": "4.1.2",
|
||||
"estree-walker": "^3.0.3",
|
||||
"magic-string": "^0.30.21"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"msw": "^2.4.9",
|
||||
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"msw": {
|
||||
"optional": true
|
||||
},
|
||||
"vite": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker/node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/pretty-format": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@vitest/pretty-format/-/pretty-format-4.1.2.tgz",
|
||||
@@ -12636,10 +12671,9 @@
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.4.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.0.4.tgz",
|
||||
"integrity": "sha512-RzAr8LSvM8lmhB4tQ5OPcBhpjOZRZjuxv9zO5UcxeoY2bd3kP3Ticd40Qma9/BqZ8JS96Ll/jeBX9u+LJZrhVg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.19.3",
|
||||
"postcss": "^8.4.31",
|
||||
@@ -13302,33 +13336,6 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/vitest/node_modules/@vitest/mocker": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.2.tgz",
|
||||
"integrity": "sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/spy": "4.1.2",
|
||||
"estree-walker": "^3.0.3",
|
||||
"magic-string": "^0.30.21"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"msw": "^2.4.9",
|
||||
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"msw": {
|
||||
"optional": true
|
||||
},
|
||||
"vite": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vitest/node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
@@ -13391,16 +13398,6 @@
|
||||
"@esbuild/win32-x64": "0.27.7"
|
||||
}
|
||||
},
|
||||
"node_modules/vitest/node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vitest/node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
"typescript": "^5.9.3",
|
||||
"unplugin-auto-import": "0.17.1",
|
||||
"unplugin-vue-setup-extend-plus": "1.0.0",
|
||||
"vite": "^5.0.4",
|
||||
"vite": "5.0.4",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vite-plugin-vue-mcp": "^0.3.2",
|
||||
|
||||
@@ -162,24 +162,6 @@ export function getG(svg, viewConfig) {
|
||||
// 设置数据
|
||||
export function getData(allData) {
|
||||
const rowsData = allData.rows; // allData, '【全部数据】'
|
||||
// 兼容旧数据:将旧 typeCode 映射到新 typeCode(心率 004→014,脉搏 005→002,呼吸 006→001)
|
||||
const OLD_CODE_MAP = { '004': '014', '005': '002', '006': '001' };
|
||||
rowsData.forEach(row => {
|
||||
if (row.rowBOS) {
|
||||
const prependItems = [];
|
||||
row.rowBOS.forEach(item => {
|
||||
const newCode = OLD_CODE_MAP[item.typeCode];
|
||||
// 始终添加映射条目,用 unshift 插入数组头部
|
||||
// 这样 getType 的 find() 优先匹配映射后的编码(如脉冲、呼吸)
|
||||
// 即使存在同编码的旧条目(如血压舒张压用 002、收缩压用 001),
|
||||
// 映射后的脉搏(002)和呼吸(001)条目排在前面,确保图表正确渲染
|
||||
if (newCode) {
|
||||
prependItems.push({ ...item, typeCode: newCode });
|
||||
}
|
||||
});
|
||||
row.rowBOS.unshift(...prependItems);
|
||||
}
|
||||
});
|
||||
const infoData = allData.grParamBOS;
|
||||
const typesData = getTypeDatas(allData.types, allData.grParamBOS.beginDate);
|
||||
const selectOp = allData.selectOp;
|
||||
|
||||
@@ -10,27 +10,15 @@
|
||||
@click="clickAct"
|
||||
>
|
||||
<div v-if="data.bedOperationalStatus==='U'">
|
||||
<img
|
||||
:src="emptyBed"
|
||||
class="pf_card_emptyBed_img"
|
||||
>
|
||||
<div class="pf_card_emptyBed_text">
|
||||
{{ data.bedName }}
|
||||
</div>
|
||||
<img :src="emptyBed" class="pf_card_emptyBed_img">
|
||||
<div class="pf_card_emptyBed_text">{{ data.bedName }}</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div
|
||||
v-if="data.isDischarge"
|
||||
class="pf_card_discharge"
|
||||
>
|
||||
<div v-if="data.isDischarge" class="pf_card_discharge">
|
||||
<span style="margin-left: 6px">离</span>
|
||||
</div>
|
||||
<div class="pf_card_card">
|
||||
<CardSign
|
||||
:color="getBedBackColor(data.triageLevel)"
|
||||
:title="data.bedName"
|
||||
:tail="getDisplay(data.triageLevel)"
|
||||
/>
|
||||
<CardSign :color="getBedBackColor(data.triageLevel)" :title="data.bedName" :tail="getDisplay(data.triageLevel)" />
|
||||
</div>
|
||||
<div class="pf_card_nameSexAndAge">
|
||||
<span class="pf_card_name">{{ data.patientName }}</span>
|
||||
@@ -40,48 +28,20 @@
|
||||
<span style="margin-right: 16px">入室时间</span>
|
||||
{{ moment(data.checkInWardTime).format('YYYY-MM-DD HH:mm') }}
|
||||
</div>
|
||||
<div class="pf_card_noCode">
|
||||
{{ data.hisId }}
|
||||
</div>
|
||||
<div class="pf_card_rescueTimeText">
|
||||
{{ rescueTimeText() }}
|
||||
</div>
|
||||
<div
|
||||
v-if="data.diag!==''"
|
||||
class="pf_card_diagnosis"
|
||||
>
|
||||
<div class="card-rectangle-text">
|
||||
{{ data.diag }}
|
||||
</div>
|
||||
<div class="pf_card_noCode">{{ data.hisId }}</div>
|
||||
<div class="pf_card_rescueTimeText">{{ rescueTimeText() }}</div>
|
||||
<div v-if="data.diag!==''" class="pf_card_diagnosis">
|
||||
<div class="card-rectangle-text">{{ data.diag }}</div>
|
||||
<span style="margin-left: 4px">(诊断)</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="isNewSign()"
|
||||
class="card-rectangle"
|
||||
>
|
||||
新
|
||||
</div>
|
||||
<div
|
||||
v-if="is72HourSign()"
|
||||
class="card-rectangle2"
|
||||
>
|
||||
超72H
|
||||
</div>
|
||||
<div v-if="isNewSign()" class="card-rectangle">新</div>
|
||||
<div v-if="is72HourSign()" class="card-rectangle2">超72H</div>
|
||||
<hr class="pf_card_line">
|
||||
<div class="pf_card_nursingMeasuresString">
|
||||
{{ getStringByCode(data.nursingMeasures, nursingMeasures) }}
|
||||
</div>
|
||||
<div class="pf_card_specialArrangementString">
|
||||
{{ getStringByCode(data.specialArrangement, specialArrangementList) }}
|
||||
</div>
|
||||
<div
|
||||
v-if="false"
|
||||
class="pf_card_btn"
|
||||
@click="moreClick"
|
||||
>
|
||||
更多
|
||||
</div>
|
||||
<div class="pf_card_nursingMeasuresString">{{ getStringByCode(data.nursingMeasures, nursingMeasures) }}</div>
|
||||
<div class="pf_card_specialArrangementString">{{ getStringByCode(data.specialArrangement, specialArrangementList) }}</div>
|
||||
<div v-if="false" class="pf_card_btn" @click="moreClick">更多</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
:data="item"
|
||||
:bed-config="bedConfig"
|
||||
@click="clickAct"
|
||||
@more-click="moreClickAct"
|
||||
@moreClick="moreClickAct"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
<template>
|
||||
<div class="printCard">
|
||||
<div
|
||||
ref="refQr"
|
||||
style="float: left; margin: 30px 15px"
|
||||
>
|
||||
<img
|
||||
:src="emptyBed"
|
||||
style="height: 120px"
|
||||
class="pf_card_emptyBed_img"
|
||||
>
|
||||
<div ref="refQr" style="float: left; margin: 30px 15px">
|
||||
<img :src="emptyBed" style="height: 120px" class="pf_card_emptyBed_img">
|
||||
</div>
|
||||
<div
|
||||
class="printView_content"
|
||||
style=" margin: 30px 0"
|
||||
>
|
||||
<div class="printView_content" style=" margin: 30px 0">
|
||||
<div>
|
||||
<span>床号:</span>
|
||||
<span>{{ printData.bedName }}</span>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<div class="recordBill">
|
||||
<div
|
||||
id="div1"
|
||||
class="printView_header"
|
||||
>
|
||||
<div id="div1" class="printView_header">
|
||||
<div style="text-align: center; height: 40px">
|
||||
护理交接班
|
||||
</div>
|
||||
@@ -21,83 +18,35 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="div2"
|
||||
class="printView_content"
|
||||
>
|
||||
<table
|
||||
border="1"
|
||||
cellSpacing="0"
|
||||
width="98%"
|
||||
cellPadding="1"
|
||||
style=" border-collapse:collapse; font-size: 14px"
|
||||
bordercolor="#333333"
|
||||
>
|
||||
<div id="div2" class="printView_content">
|
||||
<table border="1" cellSpacing="0" width="98%" cellPadding="1" style=" border-collapse:collapse; font-size: 14px" bordercolor="#333333">
|
||||
<thead>
|
||||
<TR>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 40px"
|
||||
align="center"
|
||||
>
|
||||
类别
|
||||
</DIV>
|
||||
<DIV style="width: 40px" align="center">类别</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 50px"
|
||||
align="center"
|
||||
>
|
||||
床号
|
||||
</DIV>
|
||||
<DIV style="width: 50px" align="center">床号</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 60px"
|
||||
align="center"
|
||||
>
|
||||
姓名
|
||||
</DIV>
|
||||
<DIV style="width: 60px" align="center">姓名</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 90px"
|
||||
align="center"
|
||||
>
|
||||
主诉
|
||||
</DIV>
|
||||
<DIV style="width: 90px" align="center">主诉</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 90px"
|
||||
align="center"
|
||||
>
|
||||
既往史
|
||||
</DIV>
|
||||
<DIV style="width: 90px" align="center">既往史</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 90px"
|
||||
align="center"
|
||||
>
|
||||
诊断
|
||||
</DIV>
|
||||
<DIV style="width: 90px" align="center">诊断</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 155px"
|
||||
align="center"
|
||||
>
|
||||
交接信息
|
||||
</DIV>
|
||||
<DIV style="width: 155px" align="center">交接信息</DIV>
|
||||
</TD>
|
||||
</TR>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="item in printData.shiftRecordItems"
|
||||
:key="item.id"
|
||||
>
|
||||
<tr v-for="item in printData.shiftRecordItems" :key="item.id">
|
||||
<td v-html="item.typeDisplay" />
|
||||
<td v-html="item.bedName" />
|
||||
<td v-html="item.patientName" />
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<div class="recordBill">
|
||||
<div
|
||||
:id="'exeSheetTitle' + printData.id"
|
||||
class="printView_header"
|
||||
>
|
||||
<div :id="'exeSheetTitle' + printData.id" class="printView_header">
|
||||
<div style="text-align: center; height: 60px">
|
||||
{{ userStore.hospitalName }}医嘱执行单
|
||||
</div>
|
||||
@@ -19,119 +16,51 @@
|
||||
<span style="display: inline-block; width: 140px">性别:{{!printData.patientInfo.gender? '':printData.patientInfo.gender.display}}</span>
|
||||
</div>-->
|
||||
</div>
|
||||
<div
|
||||
:id="'exeSheet' + printData.id"
|
||||
class="printView_content"
|
||||
>
|
||||
<table
|
||||
border="1"
|
||||
cellSpacing="0"
|
||||
width="97%"
|
||||
cellPadding="1"
|
||||
style=" border-collapse:collapse; font-size: 13px"
|
||||
bordercolor="#333333"
|
||||
>
|
||||
<div :id="'exeSheet' + printData.id" class="printView_content">
|
||||
<table border="1" cellSpacing="0" width="97%" cellPadding="1" style=" border-collapse:collapse; font-size: 13px" bordercolor="#333333">
|
||||
<thead>
|
||||
<TR>
|
||||
<TD rowspan="1">
|
||||
<DIV style="width: 65px;text-align: center">
|
||||
医嘱日期
|
||||
</DIV>
|
||||
<DIV style="width: 65px;text-align: center">医嘱日期</DIV>
|
||||
</TD>
|
||||
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 120px"
|
||||
align="center"
|
||||
>
|
||||
医嘱
|
||||
</DIV>
|
||||
<DIV style="width: 120px" align="center">医嘱</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 10px"
|
||||
align="center"
|
||||
/>
|
||||
<DIV style="width: 10px" align="center" />
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 70px"
|
||||
align="center"
|
||||
>
|
||||
嘱托
|
||||
</DIV>
|
||||
<DIV style="width: 70px" align="center">嘱托</DIV>
|
||||
</TD>
|
||||
<TD rowspan="1">
|
||||
<DIV
|
||||
style="width: 60px"
|
||||
align="center"
|
||||
>
|
||||
用量
|
||||
</DIV>
|
||||
<DIV style="width: 60px" align="center">用量</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 40px"
|
||||
align="center"
|
||||
>
|
||||
用法
|
||||
</DIV>
|
||||
<DIV style="width: 40px" align="center">用法</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 40px"
|
||||
align="center"
|
||||
>
|
||||
频次
|
||||
</DIV>
|
||||
<DIV style="width: 40px" align="center">频次</DIV>
|
||||
</TD>
|
||||
<TD rowspan="1">
|
||||
<DIV
|
||||
style="width: 65px"
|
||||
align="center"
|
||||
>
|
||||
开立医生
|
||||
</DIV>
|
||||
<DIV style="width: 65px" align="center">开立医生</DIV>
|
||||
</TD>
|
||||
<TD rowspan="1">
|
||||
<DIV
|
||||
style="width: 65px"
|
||||
align="center"
|
||||
>
|
||||
执行时间
|
||||
</DIV>
|
||||
<DIV style="width: 65px" align="center">执行时间</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 65px"
|
||||
align="center"
|
||||
>
|
||||
执行护士
|
||||
</DIV>
|
||||
<DIV style="width: 65px" align="center">执行护士</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 55px"
|
||||
align="center"
|
||||
>
|
||||
终止时间
|
||||
</DIV>
|
||||
<DIV style="width: 55px" align="center">终止时间</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 55px"
|
||||
align="center"
|
||||
>
|
||||
终止人
|
||||
</DIV>
|
||||
<DIV style="width: 55px" align="center">终止人</DIV>
|
||||
</TD>
|
||||
</TR>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="item in printData.recordData"
|
||||
:key="item.id"
|
||||
>
|
||||
<tr v-for="item in printData.recordData" :key="item.id">
|
||||
<td v-html="item.moTime" />
|
||||
<td v-html="item.orderName" />
|
||||
<td v-html="item.flag" />
|
||||
@@ -141,20 +70,12 @@
|
||||
<td v-html="item.frequency" />
|
||||
<td :id="item.id">
|
||||
<span v-if="(item.docSignImage === ''||item.docSignImage === null)">{{ item.moDocName }}</span>
|
||||
<img
|
||||
v-if="(item.docSignImage !== ''&&item.docSignImage !== null)"
|
||||
:src="'data:image/png;base64,'+ item.docSignImage"
|
||||
style="height: 100%; width: 100%;object-fit: cover;"
|
||||
>
|
||||
<img v-if="(item.docSignImage !== ''&&item.docSignImage !== null)" :src="'data:image/png;base64,'+ item.docSignImage" style="height: 100%; width: 100%;object-fit: cover;">
|
||||
</td>
|
||||
<td v-html="item.occurrence" />
|
||||
<td :id="item.id">
|
||||
<span v-if="(item.perNurserSignImage === ''||item.perNurserSignImage === null)">{{ item.performName }}</span>
|
||||
<img
|
||||
v-if="(item.perNurserSignImage !== ''&&item.perNurserSignImage !== null)"
|
||||
:src="'data:image/png;base64,'+ item.perNurserSignImage"
|
||||
style="height: 100%; width: 100%;object-fit: cover;"
|
||||
>
|
||||
<img v-if="(item.perNurserSignImage !== ''&&item.perNurserSignImage !== null)" :src="'data:image/png;base64,'+ item.perNurserSignImage" style="height: 100%; width: 100%;object-fit: cover;">
|
||||
</td>
|
||||
<td />
|
||||
<td />
|
||||
@@ -170,6 +91,10 @@ import { simplePrint, PRINT_TEMPLATE } from '@/utils/printUtils.js'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const userStore = useUserStore();
|
||||
return { userStore };
|
||||
},
|
||||
props: {
|
||||
printData: {
|
||||
type: Object,
|
||||
@@ -178,10 +103,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const userStore = useUserStore();
|
||||
return { userStore };
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
@@ -12,51 +12,23 @@
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: block; width: 120px; height: 60px; float:left; ">
|
||||
<div
|
||||
:id="getId(printData.id)"
|
||||
style="float: left; margin: 5px;"
|
||||
/>
|
||||
<div :id="getId(printData.id)" style="float: left; margin: 5px;" />
|
||||
<span style="float: left; margin: 5px">{{ printData.priority }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div :id="printData.id + 'div2'">
|
||||
<table
|
||||
border="1"
|
||||
cellSpacing="0"
|
||||
width="390px"
|
||||
cellPadding="1"
|
||||
style="margin-left: 8px; border-collapse:collapse; table-layout: fixed; font-size: 14px"
|
||||
bordercolor="#333333"
|
||||
>
|
||||
<table border="1" cellSpacing="0" width="390px" cellPadding="1" style="margin-left: 8px; border-collapse:collapse; table-layout: fixed; font-size: 14px" bordercolor="#333333">
|
||||
<thead>
|
||||
<TR>
|
||||
<Th
|
||||
style="width: 160px"
|
||||
v-html="'药品名称'"
|
||||
/>
|
||||
<Th
|
||||
style="width: 75px"
|
||||
v-html="'用量'"
|
||||
/>
|
||||
<Th
|
||||
style="width: 10px"
|
||||
v-html="''"
|
||||
/>
|
||||
<Th
|
||||
style="width: 50px"
|
||||
v-html="'频次'"
|
||||
/>
|
||||
<Th
|
||||
style="width: 75px"
|
||||
v-html="'用法'"
|
||||
/>
|
||||
<Th style="width: 160px" v-html="'药品名称'" />
|
||||
<Th style="width: 75px" v-html="'用量'" />
|
||||
<Th style="width: 10px" v-html="''" />
|
||||
<Th style="width: 50px" v-html="'频次'" />
|
||||
<Th style="width: 75px" v-html="'用法'" />
|
||||
</TR>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="item in printData.orderDetail"
|
||||
:key="item.id"
|
||||
>
|
||||
<tr v-for="item in printData.orderDetail" :key="item.id">
|
||||
<td v-html="item.orderName" />
|
||||
<td v-html="item.doseOnce + item.doseUnit" />
|
||||
<td v-html="item.flag" />
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<div class="recordBill">
|
||||
<div
|
||||
id="div1"
|
||||
class="printView_header"
|
||||
>
|
||||
<div id="div1" class="printView_header">
|
||||
<div style="text-align: center; font-size: 20px; height: 40px">
|
||||
{{ userStore.hospitalName }}输液执行单
|
||||
</div>
|
||||
@@ -16,88 +13,38 @@
|
||||
<span style="margin-left: 18px">科室:{{ printData.patientInfo.deptName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="div2"
|
||||
class="printView_content"
|
||||
>
|
||||
<table
|
||||
border="1"
|
||||
cellSpacing="0"
|
||||
cellPadding="1"
|
||||
style=" border-collapse:collapse; font-size: 14px"
|
||||
bordercolor="#333333"
|
||||
>
|
||||
<div id="div2" class="printView_content">
|
||||
<table border="1" cellSpacing="0" cellPadding="1" style=" border-collapse:collapse; font-size: 14px" bordercolor="#333333">
|
||||
<thead>
|
||||
<TR style="height: 30px">
|
||||
<TD rowspan="1">
|
||||
<DIV
|
||||
style="width: 35px"
|
||||
align="center"
|
||||
>
|
||||
时间
|
||||
</DIV>
|
||||
<DIV style="width: 35px" align="center">时间</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 280px"
|
||||
align="center"
|
||||
>
|
||||
药品名称
|
||||
</DIV>
|
||||
<DIV style="width: 280px" align="center">药品名称</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 10px"
|
||||
align="center"
|
||||
/>
|
||||
<DIV style="width: 10px" align="center" />
|
||||
</TD>
|
||||
<TD rowspan="1">
|
||||
<DIV
|
||||
style="width: 55px"
|
||||
align="center"
|
||||
>
|
||||
剂量
|
||||
</DIV>
|
||||
<DIV style="width: 55px" align="center">剂量</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 30px"
|
||||
align="center"
|
||||
>
|
||||
频次
|
||||
</DIV>
|
||||
<DIV style="width: 30px" align="center">频次</DIV>
|
||||
</TD>
|
||||
<TD colspan="1">
|
||||
<DIV
|
||||
style="width: 55px"
|
||||
align="center"
|
||||
>
|
||||
用法
|
||||
</DIV>
|
||||
<DIV style="width: 55px" align="center">用法</DIV>
|
||||
</TD>
|
||||
<TD rowspan="1">
|
||||
<DIV
|
||||
style="width: 70px"
|
||||
align="center"
|
||||
>
|
||||
执行时间
|
||||
</DIV>
|
||||
<DIV style="width: 70px" align="center">执行时间</DIV>
|
||||
</TD>
|
||||
<TD rowspan="1">
|
||||
<DIV
|
||||
style="width: 55px"
|
||||
align="center"
|
||||
>
|
||||
执行人
|
||||
</DIV>
|
||||
<DIV style="width: 55px" align="center">执行人</DIV>
|
||||
</TD>
|
||||
</TR>
|
||||
</thead>
|
||||
<tbody style=" border-collapse:collapse;">
|
||||
<tr
|
||||
v-for="item in printData.recordData"
|
||||
:key="item.id"
|
||||
>
|
||||
<tr v-for="item in printData.recordData" :key="item.id">
|
||||
<td v-html="item.moTime.substring(0,16)" />
|
||||
<td v-html="item.orderName" />
|
||||
<td v-html="item.flag" />
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div ref="print">
|
||||
<div
|
||||
v-for="item in printData"
|
||||
:key="item.id"
|
||||
>
|
||||
<div v-for="item in printData" :key="item.id">
|
||||
<div class="myccs2">
|
||||
<injectLabel
|
||||
:ref="item.id"
|
||||
:print-data="item"
|
||||
/>
|
||||
<injectLabel :ref="item.id" :print-data="item" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,21 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<div ref="print">
|
||||
<div
|
||||
v-for="item in printData"
|
||||
:key="item.id"
|
||||
>
|
||||
<div v-for="item in printData" :key="item.id">
|
||||
<div class="myccs2">
|
||||
<orderSheet
|
||||
v-if="!item.type"
|
||||
:ref="item.id"
|
||||
:print-data="item"
|
||||
/>
|
||||
<exeOrderSheet
|
||||
v-if="item.type"
|
||||
:ref="item.id"
|
||||
:print-data="item"
|
||||
/>
|
||||
<orderSheet v-if="!item.type" :ref="item.id" :print-data="item" />
|
||||
<exeOrderSheet v-if="item.type" :ref="item.id" :print-data="item" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<template>
|
||||
<Graphics
|
||||
v-if="graphicsDataDone"
|
||||
:value="resInfo"
|
||||
print
|
||||
@done="printPage"
|
||||
/>
|
||||
<Graphics v-if="graphicsDataDone" :value="resInfo" print @done="printPage" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
<span>分诊时间:</span>
|
||||
<span>{{ printData.triageTime }}</span>
|
||||
</div>
|
||||
<img
|
||||
ref="refQr"
|
||||
style="position: absolute; top: 10px; left: 100px"
|
||||
>
|
||||
<img ref="refQr" style="position: absolute; top: 10px; left: 100px" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -33,6 +30,10 @@ import useUserStore from '@/store/modules/user';
|
||||
|
||||
export default {
|
||||
name: 'TriageTicket',
|
||||
setup() {
|
||||
const userStore = useUserStore();
|
||||
return { userStore };
|
||||
},
|
||||
props: {
|
||||
printData: {
|
||||
type: Object,
|
||||
@@ -47,10 +48,6 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const userStore = useUserStore();
|
||||
return { userStore };
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
<div>
|
||||
<div ref="print">
|
||||
<div class="myccs2">
|
||||
<triageTicketNew
|
||||
ref="printTriage"
|
||||
:print-data="printData"
|
||||
/>
|
||||
<triageTicketNew ref="printTriage" :print-data="printData" />
|
||||
</div>
|
||||
<!-- <div v-for="item in printData" :key="item.id">-->
|
||||
<!-- <div class="myccs2">-->
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
<span style="font-weight: bolder; font-size: 18px; line-height: 36px">{{ printData.greenText }}</span>
|
||||
<span style="font-weight: bolder; font-size: 18px; line-height: 36px">分诊单</span>
|
||||
</div>
|
||||
<div style="position: absolute; top: 135px; text-align: center; width: 300px">
|
||||
{{ printData.hisId }}
|
||||
</div>
|
||||
<div style="position: absolute; top: 135px; text-align: center; width: 300px">{{ printData.hisId }}</div>
|
||||
<div style="position: absolute; top: 155px; text-align: center; width: 300px">
|
||||
{{ printData.triageLevel }}({{ printData.dept }})
|
||||
</div>
|
||||
@@ -109,18 +107,10 @@
|
||||
"
|
||||
/>
|
||||
<div style="margin-left: 15px">
|
||||
<div style="font-size: 14px; margin-top: 15px; font-weight: bolder">
|
||||
请仔细核对个人信息后进行挂号
|
||||
</div>
|
||||
<div style="margin-top: 5px; font-size: 14px">
|
||||
为了您家人和其他患者的健康
|
||||
</div>
|
||||
<div style="font-size: 14px">
|
||||
请您保持就诊秩序保持诊区安静
|
||||
</div>
|
||||
<div style="font-size: 14px">
|
||||
祝您早日康复
|
||||
</div>
|
||||
<div style="font-size: 14px; margin-top: 15px; font-weight: bolder">请仔细核对个人信息后进行挂号</div>
|
||||
<div style="margin-top: 5px; font-size: 14px">为了您家人和其他患者的健康</div>
|
||||
<div style="font-size: 14px">请您保持就诊秩序保持诊区安静</div>
|
||||
<div style="font-size: 14px">祝您早日康复</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<div class="printWrist">
|
||||
<div
|
||||
id="div1"
|
||||
class="printView_content"
|
||||
>
|
||||
<div id="div1" class="printView_content">
|
||||
<div style="margin: 1px;font-size: 12px">
|
||||
<span>姓名: </span>
|
||||
<span>{{ printData.patientName }}</span>
|
||||
@@ -25,11 +22,7 @@
|
||||
<span style="position: absolute; left: 140px">{{ printData.triageLevel }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="qrcode"
|
||||
ref="refQr"
|
||||
style="padding-top: 1px"
|
||||
/>
|
||||
<div id="qrcode" ref="refQr" style="padding-top: 1px" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
<template>
|
||||
<el-breadcrumb
|
||||
class="app-breadcrumb"
|
||||
separator="/"
|
||||
>
|
||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item
|
||||
v-for="(item,index) in levelList"
|
||||
:key="item.path"
|
||||
>
|
||||
<span
|
||||
v-if="item.redirect === 'noRedirect' || index == levelList.length - 1"
|
||||
class="no-redirect"
|
||||
>{{ item.meta.title }}</span>
|
||||
<a
|
||||
v-else
|
||||
@click.prevent="handleLink(item)"
|
||||
>{{ item.meta.title }}</a>
|
||||
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
||||
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
|
||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
|
||||
@@ -1,107 +1,55 @@
|
||||
<template>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="1"
|
||||
>
|
||||
日,允许的通配符[, - * ? / L W]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
日,允许的通配符[, - * ? / L W]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="2"
|
||||
>
|
||||
不指定
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
不指定
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="3"
|
||||
>
|
||||
周期从
|
||||
<el-input-number
|
||||
v-model="cycle01"
|
||||
:min="1"
|
||||
:max="30"
|
||||
/> -
|
||||
<el-input-number
|
||||
v-model="cycle02"
|
||||
:min="cycle01 + 1"
|
||||
:max="31"
|
||||
/> 日
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="1" :max="30" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="31" /> 日
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="4"
|
||||
>
|
||||
从
|
||||
<el-input-number
|
||||
v-model="average01"
|
||||
:min="1"
|
||||
:max="30"
|
||||
/> 号开始,每
|
||||
<el-input-number
|
||||
v-model="average02"
|
||||
:min="1"
|
||||
:max="31 - average01"
|
||||
/> 日执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="1" :max="30" /> 号开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="31 - average01" /> 日执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="5"
|
||||
>
|
||||
每月
|
||||
<el-input-number
|
||||
v-model="workday"
|
||||
:min="1"
|
||||
:max="31"
|
||||
/> 号最近的那个工作日
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="5">
|
||||
每月
|
||||
<el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="6"
|
||||
>
|
||||
本月最后一天
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="6">
|
||||
本月最后一天
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="7"
|
||||
>
|
||||
指定
|
||||
<el-select
|
||||
v-model="checkboxList"
|
||||
clearable
|
||||
placeholder="可多选"
|
||||
multiple
|
||||
:multiple-limit="10"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in 31"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="7">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
|
||||
<el-option v-for="item in 31" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<script setup>
|
||||
const emit = defineEmits(['update'])
|
||||
|
||||
@@ -1,75 +1,36 @@
|
||||
<template>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="1"
|
||||
>
|
||||
小时,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
小时,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="2"
|
||||
>
|
||||
周期从
|
||||
<el-input-number
|
||||
v-model="cycle01"
|
||||
:min="0"
|
||||
:max="22"
|
||||
/> -
|
||||
<el-input-number
|
||||
v-model="cycle02"
|
||||
:min="cycle01 + 1"
|
||||
:max="23"
|
||||
/> 时
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="22" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="23" /> 时
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="3"
|
||||
>
|
||||
从
|
||||
<el-input-number
|
||||
v-model="average01"
|
||||
:min="0"
|
||||
:max="22"
|
||||
/> 时开始,每
|
||||
<el-input-number
|
||||
v-model="average02"
|
||||
:min="1"
|
||||
:max="23 - average01"
|
||||
/> 小时执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="22" /> 时开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="23 - average01" /> 小时执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="4"
|
||||
>
|
||||
指定
|
||||
<el-select
|
||||
v-model="checkboxList"
|
||||
clearable
|
||||
placeholder="可多选"
|
||||
multiple
|
||||
:multiple-limit="10"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in 24"
|
||||
:key="item"
|
||||
:label="item - 1"
|
||||
:value="item - 1"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
|
||||
<el-option v-for="item in 24" :key="item" :label="item - 1" :value="item - 1" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -1,211 +1,123 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane
|
||||
v-if="shouldHide('second')"
|
||||
label="秒"
|
||||
>
|
||||
<CrontabSecond
|
||||
ref="cronsecond"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
@update="updateCrontabValue"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="秒" v-if="shouldHide('second')">
|
||||
<CrontabSecond
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronsecond"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="shouldHide('min')"
|
||||
label="分钟"
|
||||
>
|
||||
<CrontabMin
|
||||
ref="cronmin"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
@update="updateCrontabValue"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="分钟" v-if="shouldHide('min')">
|
||||
<CrontabMin
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronmin"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="shouldHide('hour')"
|
||||
label="小时"
|
||||
>
|
||||
<CrontabHour
|
||||
ref="cronhour"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
@update="updateCrontabValue"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="小时" v-if="shouldHide('hour')">
|
||||
<CrontabHour
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronhour"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="shouldHide('day')"
|
||||
label="日"
|
||||
>
|
||||
<CrontabDay
|
||||
ref="cronday"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
@update="updateCrontabValue"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="日" v-if="shouldHide('day')">
|
||||
<CrontabDay
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronday"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="shouldHide('month')"
|
||||
label="月"
|
||||
>
|
||||
<CrontabMonth
|
||||
ref="cronmonth"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
@update="updateCrontabValue"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="月" v-if="shouldHide('month')">
|
||||
<CrontabMonth
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronmonth"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="shouldHide('week')"
|
||||
label="周"
|
||||
>
|
||||
<CrontabWeek
|
||||
ref="cronweek"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
@update="updateCrontabValue"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="周" v-if="shouldHide('week')">
|
||||
<CrontabWeek
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronweek"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="shouldHide('year')"
|
||||
label="年"
|
||||
>
|
||||
<CrontabYear
|
||||
ref="cronyear"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
@update="updateCrontabValue"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-tab-pane label="年" v-if="shouldHide('year')">
|
||||
<CrontabYear
|
||||
@update="updateCrontabValue"
|
||||
:check="checkNumber"
|
||||
:cron="crontabValueObj"
|
||||
ref="cronyear"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="popup-main">
|
||||
<div class="popup-result">
|
||||
<p class="title">
|
||||
时间表达式
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
<th
|
||||
v-for="item of tabTitles"
|
||||
:key="item"
|
||||
>
|
||||
{{ item }}
|
||||
</th>
|
||||
<th>Cron 表达式</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.second.length < 10">{{ crontabValueObj.second }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueObj.second"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueObj.second }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.min.length < 10">{{ crontabValueObj.min }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueObj.min"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueObj.min }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.hour.length < 10">{{ crontabValueObj.hour }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueObj.hour"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueObj.hour }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.day.length < 10">{{ crontabValueObj.day }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueObj.day"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueObj.day }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.month.length < 10">{{ crontabValueObj.month }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueObj.month"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueObj.month }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.week.length < 10">{{ crontabValueObj.week }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueObj.week"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueObj.week }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.year.length < 10">{{ crontabValueObj.year }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueObj.year"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueObj.year }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
<td class="result">
|
||||
<span v-if="crontabValueString.length < 90">{{ crontabValueString }}</span>
|
||||
<el-tooltip
|
||||
v-else
|
||||
:content="crontabValueString"
|
||||
placement="top"
|
||||
>
|
||||
<span>{{ crontabValueString }}</span>
|
||||
</el-tooltip>
|
||||
</td>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<CrontabResult :ex="crontabValueString" />
|
||||
<div class="popup-main">
|
||||
<div class="popup-result">
|
||||
<p class="title">时间表达式</p>
|
||||
<table>
|
||||
<thead>
|
||||
<th v-for="item of tabTitles" :key="item">{{item}}</th>
|
||||
<th>Cron 表达式</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.second.length < 10">{{crontabValueObj.second}}</span>
|
||||
<el-tooltip v-else :content="crontabValueObj.second" placement="top"><span>{{crontabValueObj.second}}</span></el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.min.length < 10">{{crontabValueObj.min}}</span>
|
||||
<el-tooltip v-else :content="crontabValueObj.min" placement="top"><span>{{crontabValueObj.min}}</span></el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.hour.length < 10">{{crontabValueObj.hour}}</span>
|
||||
<el-tooltip v-else :content="crontabValueObj.hour" placement="top"><span>{{crontabValueObj.hour}}</span></el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.day.length < 10">{{crontabValueObj.day}}</span>
|
||||
<el-tooltip v-else :content="crontabValueObj.day" placement="top"><span>{{crontabValueObj.day}}</span></el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.month.length < 10">{{crontabValueObj.month}}</span>
|
||||
<el-tooltip v-else :content="crontabValueObj.month" placement="top"><span>{{crontabValueObj.month}}</span></el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.week.length < 10">{{crontabValueObj.week}}</span>
|
||||
<el-tooltip v-else :content="crontabValueObj.week" placement="top"><span>{{crontabValueObj.week}}</span></el-tooltip>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="crontabValueObj.year.length < 10">{{crontabValueObj.year}}</span>
|
||||
<el-tooltip v-else :content="crontabValueObj.year" placement="top"><span>{{crontabValueObj.year}}</span></el-tooltip>
|
||||
</td>
|
||||
<td class="result">
|
||||
<span v-if="crontabValueString.length < 90">{{crontabValueString}}</span>
|
||||
<el-tooltip v-else :content="crontabValueString" placement="top"><span>{{crontabValueString}}</span></el-tooltip>
|
||||
</td>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<CrontabResult :ex="crontabValueString"></CrontabResult>
|
||||
|
||||
<div class="pop_btn">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submitFill"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
@click="clearCron"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
<el-button @click="hidePopup">
|
||||
取消
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="pop_btn">
|
||||
<el-button type="primary" @click="submitFill">确定</el-button>
|
||||
<el-button type="warning" @click="clearCron">重置</el-button>
|
||||
<el-button @click="hidePopup">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -1,75 +1,36 @@
|
||||
<template>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="1"
|
||||
>
|
||||
分钟,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
分钟,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="2"
|
||||
>
|
||||
周期从
|
||||
<el-input-number
|
||||
v-model="cycle01"
|
||||
:min="0"
|
||||
:max="58"
|
||||
/> -
|
||||
<el-input-number
|
||||
v-model="cycle02"
|
||||
:min="cycle01 + 1"
|
||||
:max="59"
|
||||
/> 分钟
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" /> 分钟
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="3"
|
||||
>
|
||||
从
|
||||
<el-input-number
|
||||
v-model="average01"
|
||||
:min="0"
|
||||
:max="58"
|
||||
/> 分钟开始, 每
|
||||
<el-input-number
|
||||
v-model="average02"
|
||||
:min="1"
|
||||
:max="59 - average01"
|
||||
/> 分钟执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始, 每
|
||||
<el-input-number v-model='average02' :min="1" :max="59 - average01" /> 分钟执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="4"
|
||||
>
|
||||
指定
|
||||
<el-select
|
||||
v-model="checkboxList"
|
||||
clearable
|
||||
placeholder="可多选"
|
||||
multiple
|
||||
:multiple-limit="10"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in 60"
|
||||
:key="item"
|
||||
:label="item - 1"
|
||||
:value="item - 1"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
|
||||
<el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<script setup>
|
||||
const emit = defineEmits(['update'])
|
||||
|
||||
@@ -1,75 +1,36 @@
|
||||
<template>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="1"
|
||||
>
|
||||
月,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
月,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="2"
|
||||
>
|
||||
周期从
|
||||
<el-input-number
|
||||
v-model="cycle01"
|
||||
:min="1"
|
||||
:max="11"
|
||||
/> -
|
||||
<el-input-number
|
||||
v-model="cycle02"
|
||||
:min="cycle01 + 1"
|
||||
:max="12"
|
||||
/> 月
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="1" :max="11" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="12" /> 月
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="3"
|
||||
>
|
||||
从
|
||||
<el-input-number
|
||||
v-model="average01"
|
||||
:min="1"
|
||||
:max="11"
|
||||
/> 月开始,每
|
||||
<el-input-number
|
||||
v-model="average02"
|
||||
:min="1"
|
||||
:max="12 - average01"
|
||||
/> 月月执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="1" :max="11" /> 月开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="12 - average01" /> 月月执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="4"
|
||||
>
|
||||
指定
|
||||
<el-select
|
||||
v-model="checkboxList"
|
||||
clearable
|
||||
placeholder="可多选"
|
||||
multiple
|
||||
:multiple-limit="8"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in monthList"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
|
||||
<el-option v-for="item in monthList" :key="item.key" :label="item.value" :value="item.key" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
<template>
|
||||
<div class="popup-result">
|
||||
<p class="title">
|
||||
最近5次运行时间
|
||||
</p>
|
||||
<ul class="popup-result-scroll">
|
||||
<template v-if="isShow">
|
||||
<li
|
||||
v-for="item in resultList"
|
||||
:key="item"
|
||||
>
|
||||
{{ item }}
|
||||
</li>
|
||||
</template>
|
||||
<li v-else>
|
||||
计算结果中...
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="popup-result">
|
||||
<p class="title">最近5次运行时间</p>
|
||||
<ul class="popup-result-scroll">
|
||||
<template v-if='isShow'>
|
||||
<li v-for='item in resultList' :key="item">{{item}}</li>
|
||||
</template>
|
||||
<li v-else>计算结果中...</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -1,75 +1,36 @@
|
||||
<template>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="1"
|
||||
>
|
||||
秒,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
秒,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="2"
|
||||
>
|
||||
周期从
|
||||
<el-input-number
|
||||
v-model="cycle01"
|
||||
:min="0"
|
||||
:max="58"
|
||||
/> -
|
||||
<el-input-number
|
||||
v-model="cycle02"
|
||||
:min="cycle01 + 1"
|
||||
:max="59"
|
||||
/> 秒
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min="0" :max="58" /> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" /> 秒
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="3"
|
||||
>
|
||||
从
|
||||
<el-input-number
|
||||
v-model="average01"
|
||||
:min="0"
|
||||
:max="58"
|
||||
/> 秒开始,每
|
||||
<el-input-number
|
||||
v-model="average02"
|
||||
:min="1"
|
||||
:max="59 - average01"
|
||||
/> 秒执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
从
|
||||
<el-input-number v-model='average01' :min="0" :max="58" /> 秒开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="59 - average01" /> 秒执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="4"
|
||||
>
|
||||
指定
|
||||
<el-select
|
||||
v-model="checkboxList"
|
||||
clearable
|
||||
placeholder="可多选"
|
||||
multiple
|
||||
:multiple-limit="10"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in 60"
|
||||
:key="item"
|
||||
:label="item - 1"
|
||||
:value="item - 1"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="10">
|
||||
<el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -1,130 +1,71 @@
|
||||
<template>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="1"
|
||||
>
|
||||
周,允许的通配符[, - * ? / L #]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="1">
|
||||
周,允许的通配符[, - * ? / L #]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="2"
|
||||
>
|
||||
不指定
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="2">
|
||||
不指定
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="3"
|
||||
>
|
||||
周期从
|
||||
<el-select
|
||||
v-model="cycle01"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="(item,index) of weekList"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
:disabled="item.key === 7"
|
||||
>
|
||||
{{ item.value }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
-
|
||||
<el-select
|
||||
v-model="cycle02"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="(item,index) of weekList"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
:disabled="item.key <= cycle01"
|
||||
>
|
||||
{{ item.value }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="3">
|
||||
周期从
|
||||
<el-select clearable v-model="cycle01">
|
||||
<el-option
|
||||
v-for="(item,index) of weekList"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
:disabled="item.key === 7"
|
||||
>{{item.value}}</el-option>
|
||||
</el-select>
|
||||
-
|
||||
<el-select clearable v-model="cycle02">
|
||||
<el-option
|
||||
v-for="(item,index) of weekList"
|
||||
:key="index"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
:disabled="item.key <= cycle01"
|
||||
>{{item.value}}</el-option>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="4"
|
||||
>
|
||||
第
|
||||
<el-input-number
|
||||
v-model="average01"
|
||||
:min="1"
|
||||
:max="4"
|
||||
/> 周的
|
||||
<el-select
|
||||
v-model="average02"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in weekList"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="4">
|
||||
第
|
||||
<el-input-number v-model='average01' :min="1" :max="4" /> 周的
|
||||
<el-select clearable v-model="average02">
|
||||
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="5"
|
||||
>
|
||||
本月最后一个
|
||||
<el-select
|
||||
v-model="weekday"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in weekList"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="5">
|
||||
本月最后一个
|
||||
<el-select clearable v-model="weekday">
|
||||
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="6"
|
||||
>
|
||||
指定
|
||||
<el-select
|
||||
v-model="checkboxList"
|
||||
class="multiselect"
|
||||
clearable
|
||||
placeholder="可多选"
|
||||
multiple
|
||||
:multiple-limit="6"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in weekList"
|
||||
:key="item.key"
|
||||
:label="item.value"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form-item>
|
||||
<el-radio v-model='radioValue' :label="6">
|
||||
指定
|
||||
<el-select class="multiselect" clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="6">
|
||||
<el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -1,84 +1,43 @@
|
||||
<template>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="1"
|
||||
>
|
||||
不填,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form>
|
||||
<el-form-item>
|
||||
<el-radio :label="1" v-model='radioValue'>
|
||||
不填,允许的通配符[, - * /]
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="2"
|
||||
>
|
||||
每年
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio :label="2" v-model='radioValue'>
|
||||
每年
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="3"
|
||||
>
|
||||
周期从
|
||||
<el-input-number
|
||||
v-model="cycle01"
|
||||
:min="fullYear"
|
||||
:max="2098"
|
||||
/> -
|
||||
<el-input-number
|
||||
v-model="cycle02"
|
||||
:min="cycle01 ? cycle01 + 1 : fullYear + 1"
|
||||
:max="2099"
|
||||
/>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio :label="3" v-model='radioValue'>
|
||||
周期从
|
||||
<el-input-number v-model='cycle01' :min='fullYear' :max="2098"/> -
|
||||
<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099"/>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="4"
|
||||
>
|
||||
从
|
||||
<el-input-number
|
||||
v-model="average01"
|
||||
:min="fullYear"
|
||||
:max="2098"
|
||||
/> 年开始,每
|
||||
<el-input-number
|
||||
v-model="average02"
|
||||
:min="1"
|
||||
:max="2099 - average01 || fullYear"
|
||||
/> 年执行一次
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio :label="4" v-model='radioValue'>
|
||||
从
|
||||
<el-input-number v-model='average01' :min='fullYear' :max="2098"/> 年开始,每
|
||||
<el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear"/> 年执行一次
|
||||
</el-radio>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio
|
||||
v-model="radioValue"
|
||||
:label="5"
|
||||
>
|
||||
指定
|
||||
<el-select
|
||||
v-model="checkboxList"
|
||||
clearable
|
||||
placeholder="可多选"
|
||||
multiple
|
||||
:multiple-limit="8"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in 9"
|
||||
:key="item"
|
||||
:value="item - 1 + fullYear"
|
||||
:label="item -1 + fullYear"
|
||||
/>
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-radio :label="5" v-model='radioValue'>
|
||||
指定
|
||||
<el-select clearable v-model="checkboxList" placeholder="可多选" multiple :multiple-limit="8">
|
||||
<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
|
||||
</el-select>
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
@@ -10,14 +10,12 @@
|
||||
>{{ item.label + " " }}</span>
|
||||
<el-tag
|
||||
v-else
|
||||
:key="item.value + ''"
|
||||
:disable-transitions="true"
|
||||
:key="item.value + ''"
|
||||
:index="index"
|
||||
:type="getValidTagType(item.elTagType)"
|
||||
:class="item.elTagClass"
|
||||
>
|
||||
{{ item.label + " " }}
|
||||
</el-tag>
|
||||
>{{ item.label + " " }}</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="unmatch && showValue">
|
||||
|
||||
@@ -1,33 +1,15 @@
|
||||
<template>
|
||||
<div class="editor-container">
|
||||
<div>
|
||||
<el-upload
|
||||
v-if="type == 'url'"
|
||||
:action="uploadUrl"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-error="handleUploadError"
|
||||
name="file"
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
class="editor-img-uploader"
|
||||
>
|
||||
<i
|
||||
ref="uploadRef"
|
||||
class="editor-img-uploader"
|
||||
/>
|
||||
<el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
|
||||
:on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers" class="editor-img-uploader"
|
||||
v-if="type == 'url'">
|
||||
<i ref="uploadRef" class="editor-img-uploader"></i>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div class="editor">
|
||||
<quill-editor
|
||||
ref="quillEditorRef"
|
||||
:content="content"
|
||||
content-type="html"
|
||||
:options="options"
|
||||
:style="styles"
|
||||
@update:content="content = $event"
|
||||
@text-change="(e) => $emit('update:modelValue', content)"
|
||||
/>
|
||||
<quill-editor ref="quillEditorRef" :content="content" @update:content="content = $event" contentType="html"
|
||||
@textChange="(e) => $emit('update:modelValue', content)" :options="options" :style="styles" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<div class="upload-file">
|
||||
<el-upload
|
||||
multiple
|
||||
ref="fileUpload"
|
||||
:action="uploadFileUrl"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:file-list="fileList"
|
||||
@@ -13,52 +12,26 @@
|
||||
:show-file-list="false"
|
||||
:headers="headers"
|
||||
class="upload-file-uploader"
|
||||
ref="fileUpload"
|
||||
>
|
||||
<!-- 上传按钮 -->
|
||||
<el-button type="primary">
|
||||
选取文件
|
||||
</el-button>
|
||||
<el-button type="primary">选取文件</el-button>
|
||||
</el-upload>
|
||||
<!-- 上传提示 -->
|
||||
<div
|
||||
v-if="showTip"
|
||||
class="el-upload__tip"
|
||||
>
|
||||
<div class="el-upload__tip" v-if="showTip">
|
||||
请上传
|
||||
<template v-if="fileSize">
|
||||
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
</template>
|
||||
<template v-if="fileType">
|
||||
格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
|
||||
</template>
|
||||
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
|
||||
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
|
||||
的文件
|
||||
</div>
|
||||
<!-- 文件列表 -->
|
||||
<transition-group
|
||||
class="upload-file-list el-upload-list el-upload-list--text"
|
||||
name="el-fade-in-linear"
|
||||
tag="ul"
|
||||
>
|
||||
<li
|
||||
v-for="(file, index) in fileList"
|
||||
:key="file.uid"
|
||||
class="el-upload-list__item ele-upload-list__item-content"
|
||||
>
|
||||
<el-link
|
||||
:href="`${baseUrl}${file.url}`"
|
||||
:underline="false"
|
||||
target="_blank"
|
||||
>
|
||||
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||
<li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
|
||||
<el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
|
||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||
</el-link>
|
||||
<div class="ele-upload-list__item-content-action">
|
||||
<el-link
|
||||
:underline="false"
|
||||
type="danger"
|
||||
@click="handleDelete(index)"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
|
||||
</div>
|
||||
</li>
|
||||
</transition-group>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
style="padding: 0 15px;"
|
||||
@click="toggleClick"
|
||||
>
|
||||
<div style="padding: 0 15px;" @click="toggleClick">
|
||||
<svg
|
||||
:class="{'is-active':isActive}"
|
||||
class="hamburger"
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{ show: show }"
|
||||
class="header-search"
|
||||
>
|
||||
<svg-icon
|
||||
v-if="!show"
|
||||
class-name="search-icon"
|
||||
icon-class="search"
|
||||
@click.stop="click"
|
||||
/>
|
||||
<div :class="{ show: show }" class="header-search">
|
||||
<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" v-if="!show" />
|
||||
<el-select
|
||||
v-else
|
||||
ref="headerSearchSelectRef"
|
||||
|
||||
@@ -8,24 +8,13 @@
|
||||
@clear="filterIcons"
|
||||
@input="filterIcons"
|
||||
>
|
||||
<template #suffix>
|
||||
<i class="el-icon-search el-input__icon" />
|
||||
</template>
|
||||
<template #suffix><i class="el-icon-search el-input__icon" /></template>
|
||||
</el-input>
|
||||
<div class="icon-list">
|
||||
<div class="list-container">
|
||||
<div
|
||||
v-for="(item, index) in iconList"
|
||||
:key="index"
|
||||
class="icon-item-wrapper"
|
||||
@click="selectedIcon(item)"
|
||||
>
|
||||
<div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)">
|
||||
<div :class="['icon-item', { active: activeIcon === item }]">
|
||||
<svg-icon
|
||||
:icon-class="item"
|
||||
class-name="icon"
|
||||
style="height: 25px;width: 16px;"
|
||||
/>
|
||||
<svg-icon :icon-class="item" class-name="icon" style="height: 25px;width: 16px;"/>
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div class="component-upload-image">
|
||||
<el-upload
|
||||
ref="imageUpload"
|
||||
multiple
|
||||
:action="uploadImgUrl"
|
||||
list-type="picture-card"
|
||||
@@ -10,6 +9,7 @@
|
||||
:limit="limit"
|
||||
:on-error="handleUploadError"
|
||||
:on-exceed="handleExceed"
|
||||
ref="imageUpload"
|
||||
:before-remove="handleDelete"
|
||||
:show-file-list="true"
|
||||
:headers="headers"
|
||||
@@ -17,15 +17,10 @@
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:class="{ hide: fileList.length >= limit }"
|
||||
>
|
||||
<el-icon class="avatar-uploader-icon">
|
||||
<plus />
|
||||
</el-icon>
|
||||
<el-icon class="avatar-uploader-icon"><plus /></el-icon>
|
||||
</el-upload>
|
||||
<!-- 上传提示 -->
|
||||
<div
|
||||
v-if="showTip"
|
||||
class="el-upload__tip"
|
||||
>
|
||||
<div class="el-upload__tip" v-if="showTip">
|
||||
请上传
|
||||
<template v-if="fileSize">
|
||||
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
|
||||
@@ -45,7 +40,7 @@
|
||||
<img
|
||||
:src="dialogImageUrl"
|
||||
style="display: block; max-width: 100%; margin: 0 auto"
|
||||
>
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<div
|
||||
v-if="$slots.header"
|
||||
class="page-header"
|
||||
>
|
||||
<div v-if="$slots.header" class="page-header">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<slot />
|
||||
</div>
|
||||
<div
|
||||
v-if="$slots.footer"
|
||||
class="page-footer"
|
||||
>
|
||||
<div v-if="$slots.footer" class="page-footer">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,51 +1,20 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
v-model="noticeVisible"
|
||||
title="公告/通知"
|
||||
direction="rtl"
|
||||
size="400px"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-empty
|
||||
v-if="noticeList.length === 0"
|
||||
description="暂无公告/通知"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="notice-list"
|
||||
>
|
||||
<div
|
||||
v-for="item in noticeList"
|
||||
:key="item.noticeId"
|
||||
class="notice-item"
|
||||
:class="{ 'is-read': isRead(item.noticeId), 'unread': !isRead(item.noticeId) }"
|
||||
@click="viewDetail(item)"
|
||||
>
|
||||
<el-drawer v-model="noticeVisible" title="公告/通知" direction="rtl" size="400px" destroy-on-close>
|
||||
<el-empty v-if="noticeList.length === 0" description="暂无公告/通知" />
|
||||
<div v-else class="notice-list">
|
||||
<div v-for="item in noticeList" :key="item.noticeId" class="notice-item" :class="{ 'is-read': isRead(item.noticeId), 'unread': !isRead(item.noticeId) }" @click="viewDetail(item)">
|
||||
<div class="notice-title">
|
||||
<span
|
||||
v-if="!isRead(item.noticeId)"
|
||||
class="unread-dot"
|
||||
/>
|
||||
<span v-if="!isRead(item.noticeId)" class="unread-dot"></span>
|
||||
{{ item.noticeTitle }}
|
||||
</div>
|
||||
<div class="notice-info">
|
||||
<span class="notice-type">
|
||||
<el-tag
|
||||
:type="getNoticeTypeTagType(item.noticeType)"
|
||||
size="small"
|
||||
>
|
||||
<el-tag :type="getNoticeTypeTagType(item.noticeType)" size="small">
|
||||
{{ getNoticeTypeText(item.noticeType) }}
|
||||
</el-tag>
|
||||
</span>
|
||||
<span
|
||||
v-if="item.priority"
|
||||
class="notice-priority"
|
||||
>
|
||||
<el-tag
|
||||
:type="getPriorityTagType(item.priority)"
|
||||
size="small"
|
||||
effect="plain"
|
||||
>
|
||||
<span class="notice-priority" v-if="item.priority">
|
||||
<el-tag :type="getPriorityTagType(item.priority)" size="small" effect="plain">
|
||||
{{ getPriorityText(item.priority) }}
|
||||
</el-tag>
|
||||
</span>
|
||||
@@ -55,41 +24,23 @@
|
||||
</div>
|
||||
|
||||
<!-- 公告/通知详情对话框 -->
|
||||
<el-dialog
|
||||
v-model="detailVisible"
|
||||
:title="currentNotice.noticeTitle"
|
||||
width="800px"
|
||||
append-to-body
|
||||
>
|
||||
<el-dialog v-model="detailVisible" :title="currentNotice.noticeTitle" width="800px" append-to-body>
|
||||
<div class="notice-detail">
|
||||
<div class="detail-header">
|
||||
<div class="detail-type">
|
||||
<el-tag
|
||||
:type="getNoticeTypeTagType(currentNotice.noticeType)"
|
||||
size="small"
|
||||
>
|
||||
<el-tag :type="getNoticeTypeTagType(currentNotice.noticeType)" size="small">
|
||||
{{ getNoticeTypeText(currentNotice.noticeType) }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:type="getPriorityTagType(currentNotice.priority)"
|
||||
size="small"
|
||||
effect="plain"
|
||||
style="margin-left: 8px;"
|
||||
>
|
||||
<el-tag :type="getPriorityTagType(currentNotice.priority)" size="small" effect="plain" style="margin-left: 8px;">
|
||||
{{ getPriorityText(currentNotice.priority) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span class="detail-time">{{ parseTime(currentNotice.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="detail-content"
|
||||
v-html="currentNotice.noticeContent"
|
||||
/>
|
||||
<div class="detail-content" v-html="currentNotice.noticeContent"></div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="detailVisible = false">
|
||||
关闭
|
||||
</el-button>
|
||||
<el-button @click="detailVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-drawer>
|
||||
|
||||
@@ -13,12 +13,7 @@
|
||||
<div class="notice-list">
|
||||
<div class="notice-list-header">
|
||||
<span class="notice-list-title">公告列表</span>
|
||||
<el-button
|
||||
v-if="unreadCount > 0"
|
||||
text
|
||||
type="primary"
|
||||
@click="markAllAsRead"
|
||||
>
|
||||
<el-button text type="primary" @click="markAllAsRead" v-if="unreadCount > 0">
|
||||
全部标记为已读
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -31,10 +26,7 @@
|
||||
@click="handleSelectNotice(notice)"
|
||||
>
|
||||
<div class="notice-item-left">
|
||||
<el-icon
|
||||
class="notice-type-icon"
|
||||
:class="getNoticeTypeClass(notice.noticeType)"
|
||||
>
|
||||
<el-icon class="notice-type-icon" :class="getNoticeTypeClass(notice.noticeType)">
|
||||
<component :is="getNoticeTypeIcon(notice.noticeType)" />
|
||||
</el-icon>
|
||||
<div class="notice-item-content">
|
||||
@@ -47,14 +39,7 @@
|
||||
{{ getPriorityText(notice.priority) }}
|
||||
</el-tag>
|
||||
<span class="notice-title-text">{{ notice.noticeTitle }}</span>
|
||||
<el-tag
|
||||
v-if="!notice.isRead"
|
||||
type="danger"
|
||||
size="small"
|
||||
effect="dark"
|
||||
>
|
||||
未读
|
||||
</el-tag>
|
||||
<el-tag v-if="!notice.isRead" type="danger" size="small" effect="dark">未读</el-tag>
|
||||
</div>
|
||||
<div class="notice-meta">
|
||||
<span class="notice-date">{{ formatDate(notice.createTime) }}</span>
|
||||
@@ -62,77 +47,45 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-icon
|
||||
v-if="activeNoticeId === notice.noticeId"
|
||||
class="arrow-icon"
|
||||
>
|
||||
<el-icon class="arrow-icon" v-if="activeNoticeId === notice.noticeId">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div
|
||||
v-if="noticeList.length === 0"
|
||||
class="empty-state"
|
||||
>
|
||||
<el-empty
|
||||
description="暂无公告"
|
||||
:image-size="100"
|
||||
/>
|
||||
<div v-if="noticeList.length === 0" class="empty-state">
|
||||
<el-empty description="暂无公告" :image-size="100" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
|
||||
<!-- 公告详情 -->
|
||||
<div
|
||||
v-if="activeNotice"
|
||||
class="notice-detail"
|
||||
>
|
||||
<div class="notice-detail" v-if="activeNotice">
|
||||
<div class="notice-detail-header">
|
||||
<h3 class="notice-detail-title">
|
||||
{{ activeNotice.noticeTitle }}
|
||||
</h3>
|
||||
<h3 class="notice-detail-title">{{ activeNotice.noticeTitle }}</h3>
|
||||
<div class="notice-detail-meta">
|
||||
<el-tag
|
||||
:type="getPriorityTagType(activeNotice.priority)"
|
||||
size="small"
|
||||
effect="dark"
|
||||
>
|
||||
<el-tag :type="getPriorityTagType(activeNotice.priority)" size="small" effect="dark">
|
||||
{{ getPriorityText(activeNotice.priority) }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:type="getNoticeTypeTagType(activeNotice.noticeType)"
|
||||
size="small"
|
||||
>
|
||||
<el-tag :type="getNoticeTypeTagType(activeNotice.noticeType)" size="small">
|
||||
{{ getNoticeTypeText(activeNotice.noticeType) }}
|
||||
</el-tag>
|
||||
<span class="notice-detail-date">{{ formatFullDate(activeNotice.createTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div
|
||||
class="notice-detail-body"
|
||||
v-html="activeNotice.noticeContent"
|
||||
/>
|
||||
<div class="notice-detail-body" v-html="activeNotice.noticeContent"></div>
|
||||
</div>
|
||||
|
||||
<!-- 未选择状态 -->
|
||||
<div
|
||||
v-else
|
||||
class="no-selection"
|
||||
>
|
||||
<el-empty
|
||||
description="请选择公告查看详情"
|
||||
:image-size="120"
|
||||
/>
|
||||
<div v-else class="no-selection">
|
||||
<el-empty description="请选择公告查看详情" :image-size="120" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">
|
||||
关闭
|
||||
</el-button>
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
@click="handleSelectNotice(notice)"
|
||||
>
|
||||
<div class="notice-item-left">
|
||||
<el-icon
|
||||
class="notice-type-icon"
|
||||
:class="getNoticeTypeClass(notice.noticeType)"
|
||||
>
|
||||
<el-icon class="notice-type-icon" :class="getNoticeTypeClass(notice.noticeType)">
|
||||
<component :is="getNoticeTypeIcon(notice.noticeType)" />
|
||||
</el-icon>
|
||||
<div class="notice-item-content">
|
||||
@@ -37,14 +34,7 @@
|
||||
{{ getPriorityText(notice.priority) }}
|
||||
</el-tag>
|
||||
<span class="notice-title-text">{{ notice.noticeTitle }}</span>
|
||||
<el-tag
|
||||
v-if="!notice.isRead"
|
||||
type="danger"
|
||||
size="small"
|
||||
effect="dark"
|
||||
>
|
||||
未读
|
||||
</el-tag>
|
||||
<el-tag v-if="!notice.isRead" type="danger" size="small" effect="dark">未读</el-tag>
|
||||
</div>
|
||||
<div class="notice-meta">
|
||||
<span class="notice-date">{{ formatDate(notice.createTime) }}</span>
|
||||
@@ -52,10 +42,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-icon
|
||||
v-if="activeNoticeId === notice.noticeId"
|
||||
class="arrow-icon"
|
||||
>
|
||||
<el-icon class="arrow-icon" v-if="activeNoticeId === notice.noticeId">
|
||||
<ArrowRight />
|
||||
</el-icon>
|
||||
</div>
|
||||
@@ -63,63 +50,35 @@
|
||||
</div>
|
||||
|
||||
<!-- 公告详情 -->
|
||||
<div
|
||||
v-if="activeNotice"
|
||||
class="notice-detail"
|
||||
>
|
||||
<div class="notice-detail" v-if="activeNotice">
|
||||
<div class="notice-detail-header">
|
||||
<h3 class="notice-detail-title">
|
||||
{{ activeNotice.noticeTitle }}
|
||||
</h3>
|
||||
<h3 class="notice-detail-title">{{ activeNotice.noticeTitle }}</h3>
|
||||
<div class="notice-detail-meta">
|
||||
<el-tag
|
||||
:type="getPriorityTagType(activeNotice.priority)"
|
||||
size="small"
|
||||
effect="dark"
|
||||
>
|
||||
<el-tag :type="getPriorityTagType(activeNotice.priority)" size="small" effect="dark">
|
||||
{{ getPriorityText(activeNotice.priority) }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
:type="getNoticeTypeTagType(activeNotice.noticeType)"
|
||||
size="small"
|
||||
>
|
||||
<el-tag :type="getNoticeTypeTagType(activeNotice.noticeType)" size="small">
|
||||
{{ getNoticeTypeText(activeNotice.noticeType) }}
|
||||
</el-tag>
|
||||
<span class="notice-detail-date">{{ formatDate(activeNotice.createTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div
|
||||
class="notice-detail-body"
|
||||
v-html="activeNotice.noticeContent"
|
||||
/>
|
||||
<div class="notice-detail-body" v-html="activeNotice.noticeContent"></div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div
|
||||
v-else
|
||||
class="empty-state"
|
||||
>
|
||||
<el-empty
|
||||
description="暂无公告"
|
||||
:image-size="120"
|
||||
/>
|
||||
<div v-else class="empty-state">
|
||||
<el-empty description="暂无公告" :image-size="120" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button
|
||||
v-if="unreadCount > 0"
|
||||
type="info"
|
||||
@click="markAllAsRead"
|
||||
>
|
||||
<el-button @click="markAllAsRead" v-if="unreadCount > 0" type="info">
|
||||
全部标记为已读
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleClose"
|
||||
>
|
||||
<el-button type="primary" @click="handleClose">
|
||||
{{ hasUnread ? '稍后再看' : '知道了' }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg-icon
|
||||
icon-class="question"
|
||||
@click="goto"
|
||||
/>
|
||||
<svg-icon icon-class="question" @click="goto" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="props.openDialog"
|
||||
title="药品追溯码"
|
||||
v-model="props.openDialog"
|
||||
width="842"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
@@ -15,15 +15,13 @@
|
||||
>
|
||||
<div>
|
||||
<div style="font-size: 16px">
|
||||
<div style="margin-bottom: 15px">
|
||||
药品名称: {{ props.ypName }}
|
||||
</div>
|
||||
<div style="margin-bottom: 15px">药品名称: {{ props.ypName }}</div>
|
||||
扫描追溯码
|
||||
<el-input
|
||||
ref="traceNoTempRef"
|
||||
v-model="traceNoTemp"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
v-model="traceNoTemp"
|
||||
style="width: 180px; margin-right: 20px"
|
||||
@input="throttledGetList(traceNoTemp)"
|
||||
/>
|
||||
@@ -33,22 +31,8 @@
|
||||
style="width: 180px; margin-right: 20px"
|
||||
@keyup.enter="handelTraceNo(traceNoInput)"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="CircleClose"
|
||||
@click="handleReturn"
|
||||
>
|
||||
撤回
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="CircleClose"
|
||||
@click="handleClear"
|
||||
>
|
||||
清除
|
||||
</el-button>
|
||||
<el-button type="primary" plain icon="CircleClose" @click="handleReturn"> 撤回 </el-button>
|
||||
<el-button type="danger" plain icon="CircleClose" @click="handleClear"> 清除 </el-button>
|
||||
</div>
|
||||
<!-- <el-input
|
||||
ref="inputRef"
|
||||
@@ -85,10 +69,11 @@
|
||||
<span style="margin-right: 6px">
|
||||
[{{ index + 1 }}]
|
||||
<template v-if="index < 9"> </template>
|
||||
<template v-else />
|
||||
<template v-else></template>
|
||||
{{ item }}
|
||||
</span>
|
||||
<div
|
||||
@click="removeTraceNo(index)"
|
||||
style="
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -99,12 +84,8 @@
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
"
|
||||
@click="removeTraceNo(index)"
|
||||
>
|
||||
<el-icon
|
||||
size="10"
|
||||
color="white"
|
||||
>
|
||||
<el-icon size="10" color="white">
|
||||
<Close />
|
||||
</el-icon>
|
||||
</div>
|
||||
@@ -117,15 +98,8 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submit"
|
||||
>
|
||||
确 定
|
||||
</el-button>
|
||||
<el-button @click="cancel">
|
||||
取 消
|
||||
</el-button>
|
||||
<el-button type="primary" @click="submit">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
@@ -6,11 +6,7 @@
|
||||
trigger="manual"
|
||||
:width="width"
|
||||
>
|
||||
<slot
|
||||
name="popover-content"
|
||||
:row="row"
|
||||
:index="index"
|
||||
>
|
||||
<slot name="popover-content" :row="row" :index="index">
|
||||
<div>列表内容</div>
|
||||
</slot>
|
||||
<template #reference>
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{ 'hidden': hidden }"
|
||||
class="pagination-container"
|
||||
>
|
||||
<div :class="{ 'hidden': hidden }" class="pagination-container">
|
||||
<el-pagination
|
||||
:background="background"
|
||||
v-model:current-page="currentPage"
|
||||
v-model:page-size="pageSize"
|
||||
:background="background"
|
||||
:layout="layout"
|
||||
:page-sizes="pageSizes"
|
||||
:pager-count="pagerCount"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<template>
|
||||
<template >
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
@@ -1,69 +1,21 @@
|
||||
<template>
|
||||
<div
|
||||
class="top-right-btn"
|
||||
:style="style"
|
||||
>
|
||||
<div class="top-right-btn" :style="style">
|
||||
<el-row>
|
||||
<el-tooltip
|
||||
v-if="search"
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="showSearch ? '隐藏搜索' : '显示搜索'"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
circle
|
||||
icon="Search"
|
||||
@click="toggleSearch()"
|
||||
/>
|
||||
<el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
|
||||
<el-button circle icon="Search" @click="toggleSearch()" />
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
content="刷新"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
circle
|
||||
icon="Refresh"
|
||||
@click="refresh()"
|
||||
/>
|
||||
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
|
||||
<el-button circle icon="Refresh" @click="refresh()" />
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
v-if="columns"
|
||||
class="item"
|
||||
effect="dark"
|
||||
content="显隐列"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
v-if="showColumnsType == 'transfer'"
|
||||
circle
|
||||
icon="Menu"
|
||||
@click="showColumn()"
|
||||
/>
|
||||
<el-dropdown
|
||||
v-if="showColumnsType == 'checkbox'"
|
||||
trigger="click"
|
||||
:hide-on-click="false"
|
||||
style="padding-left: 12px"
|
||||
>
|
||||
<el-button
|
||||
circle
|
||||
icon="Menu"
|
||||
/>
|
||||
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
|
||||
<el-button circle icon="Menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
|
||||
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
|
||||
<el-button circle icon="Menu" />
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<template
|
||||
v-for="item in columns"
|
||||
:key="item.key"
|
||||
>
|
||||
<template v-for="item in columns" :key="item.key">
|
||||
<el-dropdown-item>
|
||||
<el-checkbox
|
||||
:checked="item.visible"
|
||||
:label="item.label"
|
||||
@change="checkboxChange($event, item.label)"
|
||||
/>
|
||||
<el-checkbox :checked="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" />
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
@@ -71,17 +23,13 @@
|
||||
</el-dropdown>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<el-dialog
|
||||
v-model="open"
|
||||
:title="title"
|
||||
append-to-body
|
||||
>
|
||||
<el-dialog :title="title" v-model="open" append-to-body>
|
||||
<el-transfer
|
||||
v-model="value"
|
||||
:titles="['显示', '隐藏']"
|
||||
v-model="value"
|
||||
:data="columns"
|
||||
@change="dataChange"
|
||||
/>
|
||||
></el-transfer>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg-icon
|
||||
:icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||
@click="toggle"
|
||||
/>
|
||||
<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
@command="handleSetSize"
|
||||
>
|
||||
<el-dropdown trigger="click" @command="handleSetSize">
|
||||
<div class="size-icon--style">
|
||||
<svg-icon
|
||||
class-name="size-icon"
|
||||
icon-class="size"
|
||||
/>
|
||||
<svg-icon class-name="size-icon" icon-class="size" />
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item of sizeOptions"
|
||||
:key="item.value"
|
||||
:disabled="size === item.value"
|
||||
:command="item.value"
|
||||
>
|
||||
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size === item.value" :command="item.value">
|
||||
{{ item.label }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<template>
|
||||
<svg
|
||||
:class="svgClass"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<use
|
||||
:xlink:href="iconName"
|
||||
:fill="color"
|
||||
/>
|
||||
<svg :class="svgClass" aria-hidden="true">
|
||||
<use :xlink:href="iconName" :fill="color" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,22 +1,8 @@
|
||||
<template>
|
||||
<div
|
||||
v-loading="loading"
|
||||
class="table-section"
|
||||
>
|
||||
<EditableTable
|
||||
ref="editableTableRef"
|
||||
v-bind="$attrs"
|
||||
class="editable-table"
|
||||
>
|
||||
<template
|
||||
v-for="(_, slotName) in $slots"
|
||||
:key="slotName"
|
||||
#[slotName]="slotProps"
|
||||
>
|
||||
<slot
|
||||
:name="slotName"
|
||||
v-bind="slotProps"
|
||||
/>
|
||||
<div class="table-section" v-loading="loading">
|
||||
<EditableTable ref="editableTableRef" v-bind="$attrs" class="editable-table">
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</EditableTable>
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
<template>
|
||||
<div class="form-section">
|
||||
<FormLayout
|
||||
ref="formLayoutRef"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<template
|
||||
v-for="(_, slotName) in $slots"
|
||||
:key="slotName"
|
||||
#[slotName]="slotProps"
|
||||
>
|
||||
<slot
|
||||
:name="slotName"
|
||||
v-bind="slotProps"
|
||||
/>
|
||||
<FormLayout ref="formLayoutRef" v-bind="$attrs">
|
||||
<template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
|
||||
<slot :name="slotName" v-bind="slotProps" />
|
||||
</template>
|
||||
</FormLayout>
|
||||
</div>
|
||||
|
||||
@@ -8,12 +8,7 @@
|
||||
@blur="handleBlur"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template
|
||||
v-if="suffix"
|
||||
#suffix
|
||||
>
|
||||
{{ suffix }}
|
||||
</template>
|
||||
<template v-if="suffix" #suffix>{{ suffix }}</template>
|
||||
</el-input>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
<template
|
||||
v-if="$slots.footer"
|
||||
#footer
|
||||
>
|
||||
<template v-if="$slots.footer" #footer>
|
||||
<slot name="footer" />
|
||||
</template>
|
||||
</Layout>
|
||||
|
||||
@@ -2,28 +2,20 @@
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
mode="horizontal"
|
||||
:ellipsis="false"
|
||||
@select="handleSelect"
|
||||
:ellipsis="false"
|
||||
>
|
||||
<template v-for="(item, index) in topMenus">
|
||||
<!-- 处理有子菜单的情况 -->
|
||||
<template v-if="item.children && item.children.length > 0 && index < visibleNumber">
|
||||
<el-sub-menu
|
||||
:key="index"
|
||||
:style="{'--theme': theme}"
|
||||
:index="item.path"
|
||||
>
|
||||
<el-sub-menu :style="{'--theme': theme}" :index="item.path" :key="index">
|
||||
<template #title>
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"
|
||||
/>
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</template>
|
||||
<template
|
||||
v-for="(child, childIndex) in item.children"
|
||||
:key="childIndex"
|
||||
>
|
||||
<template v-for="(child, childIndex) in item.children" :key="childIndex">
|
||||
<el-menu-item :index="item.path + '/' + (child.path || '')">
|
||||
{{ child.meta.title }}
|
||||
</el-menu-item>
|
||||
@@ -32,47 +24,29 @@
|
||||
</template>
|
||||
<!-- 处理无子菜单的情况 -->
|
||||
<template v-else-if="index < visibleNumber">
|
||||
<el-menu-item
|
||||
:key="index"
|
||||
:style="{'--theme': theme}"
|
||||
:index="item.path"
|
||||
>
|
||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"
|
||||
/>
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- 顶部菜单超出数量折叠 -->
|
||||
<el-sub-menu
|
||||
v-if="topMenus.length > visibleNumber"
|
||||
:style="{'--theme': theme}"
|
||||
index="more"
|
||||
>
|
||||
<template #title>
|
||||
更多菜单
|
||||
</template>
|
||||
<template
|
||||
v-for="(item, index) in topMenus"
|
||||
:key="index"
|
||||
>
|
||||
<el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber">
|
||||
<template #title>更多菜单</template>
|
||||
<template v-for="(item, index) in topMenus" :key="index">
|
||||
<!-- 处理有子菜单的情况 -->
|
||||
<template v-if="item.children && item.children.length > 0 && index >= visibleNumber">
|
||||
<el-sub-menu :index="item.path">
|
||||
<template #title>
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"
|
||||
/>
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</template>
|
||||
<template
|
||||
v-for="(child, childIndex) in item.children"
|
||||
:key="childIndex"
|
||||
>
|
||||
<template v-for="(child, childIndex) in item.children" :key="childIndex">
|
||||
<el-menu-item :index="item.path + '/' + (child.path || '')">
|
||||
{{ child.meta.title }}
|
||||
</el-menu-item>
|
||||
@@ -83,9 +57,8 @@
|
||||
<template v-else-if="index >= visibleNumber">
|
||||
<el-menu-item :index="item.path">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"
|
||||
/>
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
<template>
|
||||
<div class="el-tree-select">
|
||||
<el-select
|
||||
ref="treeSelect"
|
||||
v-model="valueId"
|
||||
style="width: 100%"
|
||||
v-model="valueId"
|
||||
ref="treeSelect"
|
||||
:filterable="true"
|
||||
:clearable="true"
|
||||
@clear="clearHandle"
|
||||
:filter-method="selectFilterData"
|
||||
:placeholder="placeholder"
|
||||
@clear="clearHandle"
|
||||
>
|
||||
<el-option
|
||||
:value="valueId"
|
||||
:label="valueTitle"
|
||||
>
|
||||
<el-option :value="valueId" :label="valueTitle">
|
||||
<el-tree
|
||||
id="tree-option"
|
||||
ref="selectTree"
|
||||
@@ -25,7 +22,7 @@
|
||||
:default-expanded-keys="defaultExpandedKey"
|
||||
:filter-node-method="filterNode"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
></el-tree>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
<template>
|
||||
<div
|
||||
v-loading="loading"
|
||||
:style="'height:' + height"
|
||||
>
|
||||
<div v-loading="loading" :style="'height:' + height">
|
||||
<iframe
|
||||
:src="url"
|
||||
frameborder="no"
|
||||
style="width: 100%; height: 100%"
|
||||
scrolling="auto"
|
||||
/>
|
||||
scrolling="auto" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -4,11 +4,7 @@
|
||||
* @Description:
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
v-show="tagId"
|
||||
class="ball-tag"
|
||||
:style="{ backgroundColor: _tag?.color }"
|
||||
>
|
||||
<div class="ball-tag" v-show="tagId" :style="{ backgroundColor: _tag?.color }">
|
||||
{{ _tag?.name }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user