package jnpf.limsService.impl;
|
|
import jnpf.lims.api.model.TestWorkItemSnapshotBatch;
|
import jnpf.lims.api.model.TestWorkItemSnapshot;
|
import jnpf.lims.api.model.TestWorkItemSnapshotProperty;
|
import jnpf.lims.api.model.TestWorkItemSnapshotRequest;
|
import jnpf.limsEntity.JianyanStatus;
|
import jnpf.limsEntity.LimsJianyanXiangEntity;
|
import jnpf.limsMapper.LimsJianyanXiangMapper;
|
import jnpf.limsService.LimsTestWorkItemSnapshotService;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.StringUtils;
|
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.LinkedHashMap;
|
import java.util.LinkedHashSet;
|
import java.util.List;
|
import java.util.Map;
|
|
@Service
|
public class LimsTestWorkItemSnapshotServiceImpl implements LimsTestWorkItemSnapshotService {
|
|
static final String TEST_BASIS = "test.basis";
|
private static final String LEGACY_INSPECTION_BASIS = "inspection.basis";
|
static final String SAMPLE_NAME = "sample.name";
|
static final String SAMPLE_BATCH_NO = "sample.batch_no";
|
static final String SAMPLE_PRODUCTION_DATE = "sample.production_date";
|
static final String QUALITY_STANDARD_SOURCE = "quality_standard.source";
|
static final String SAMPLE_SPECIFICATION = "sample.specification";
|
static final String TEST_TYPE = "test.type";
|
private static final String LEGACY_INSPECTION_TYPE = "inspection.type";
|
private static final String LIMS_TASK = "LIMS_TASK";
|
private static final String TEXT = "TEXT";
|
private static final String DATE = "DATE";
|
private static final List<String> ALLOWED_STATUSES = Arrays.asList(
|
JianyanStatus.PENDING_TEST.getCode(),
|
JianyanStatus.AUDIT_REJECTED.getCode(),
|
JianyanStatus.CANCELLED.getCode());
|
|
private final TaskLookup taskLookup;
|
|
@Autowired
|
public LimsTestWorkItemSnapshotServiceImpl(LimsJianyanXiangMapper mapper) {
|
this(mapper::selectSnapshotTasks);
|
}
|
|
LimsTestWorkItemSnapshotServiceImpl(TaskLookup taskLookup) {
|
this.taskLookup = taskLookup;
|
}
|
|
@Override
|
public TestWorkItemSnapshotBatch resolve(TestWorkItemSnapshotRequest request,
|
String tenantId, String userId) {
|
List<String> itemIds = requestedItemIds(request);
|
List<String> properties = requestedProperties(request);
|
Map<String, LimsJianyanXiangEntity> tasks = findTasks(tenantId, itemIds);
|
TestWorkItemSnapshotBatch batch = new TestWorkItemSnapshotBatch();
|
for (String itemId : itemIds) {
|
LimsJianyanXiangEntity task = tasks.get(itemId);
|
TestWorkItemSnapshot item = item(itemId, task);
|
boolean readable = false;
|
if (task == null) {
|
reject(item, "NOT_FOUND", "检验项不存在或无权访问");
|
} else if (isDeleted(task)) {
|
reject(item, "DELETED", "检验项已删除");
|
} else if (!ALLOWED_STATUSES.contains(task.getJianyanZhuangtai())) {
|
reject(item, "STATE_NOT_ALLOWED", "检验项当前状态不允许读取任务快照");
|
} else if (!isResponsible(task, userId)) {
|
reject(item, "FORBIDDEN", "当前用户不是检验项负责人");
|
} else if (!StringUtils.hasText(task.getQingyandanId())) {
|
reject(item, "TEST_REQUEST_INVALID", "检验项缺少请验单身份");
|
} else if (!hasUniqueTestDefinitionReference(task)) {
|
reject(item, "TEST_DEFINITION_INVALID", "检验项缺少唯一检验项目关联");
|
} else {
|
item.setTestRequestId(task.getQingyandanId().trim());
|
applyTestDefinitionReference(item, task);
|
item.setOutcomeCode("SUCCESS");
|
readable = true;
|
}
|
addProperties(item, readable ? task : null, properties, readable);
|
batch.getItems().add(item);
|
}
|
return batch;
|
}
|
|
private Map<String, LimsJianyanXiangEntity> findTasks(String tenantId, List<String> itemIds) {
|
if (!StringUtils.hasText(tenantId) || itemIds.isEmpty()) {
|
return Collections.emptyMap();
|
}
|
Map<String, LimsJianyanXiangEntity> tasks = new LinkedHashMap<>();
|
for (LimsJianyanXiangEntity task : taskLookup.find(tenantId, itemIds)) {
|
if (task != null && StringUtils.hasText(task.getId())
|
&& tenantId.equals(task.getTenantId())) {
|
tasks.put(task.getId(), task);
|
}
|
}
|
return tasks;
|
}
|
|
private static List<String> requestedItemIds(TestWorkItemSnapshotRequest request) {
|
if (request == null || request.getTestWorkItemIds() == null) {
|
return Collections.emptyList();
|
}
|
LinkedHashSet<String> ids = new LinkedHashSet<>();
|
for (String id : request.getTestWorkItemIds()) {
|
if (StringUtils.hasText(id)) {
|
ids.add(id.trim());
|
}
|
}
|
return new ArrayList<>(ids);
|
}
|
|
private static List<String> requestedProperties(TestWorkItemSnapshotRequest request) {
|
return request == null || request.getProperties() == null
|
? Collections.<String>emptyList() : request.getProperties();
|
}
|
|
private static TestWorkItemSnapshot item(String itemId, LimsJianyanXiangEntity task) {
|
TestWorkItemSnapshot item = new TestWorkItemSnapshot();
|
item.setTestWorkItemId(itemId);
|
item.setTaskStatus(task == null ? null : task.getJianyanZhuangtai());
|
return item;
|
}
|
|
private static boolean hasUniqueTestDefinitionReference(LimsJianyanXiangEntity task) {
|
return StringUtils.hasText(task.getTestDefinitionId())
|
&& StringUtils.hasText(task.getJianyanXiangmuBianma())
|
&& StringUtils.hasText(task.getJianyanXiangmuMingcheng())
|
&& Long.valueOf(1L).equals(task.getTestDefinitionMatchCount());
|
}
|
|
private static void applyTestDefinitionReference(TestWorkItemSnapshot item,
|
LimsJianyanXiangEntity task) {
|
item.setTestDefinitionId(task.getTestDefinitionId().trim());
|
item.setTestDefinitionCode(task.getJianyanXiangmuBianma().trim());
|
item.setTestDefinitionName(task.getJianyanXiangmuMingcheng().trim());
|
}
|
|
private static void addProperties(TestWorkItemSnapshot item, LimsJianyanXiangEntity task,
|
List<String> requestedProperties, boolean readable) {
|
for (String property : requestedProperties) {
|
TestWorkItemSnapshotProperty result = new TestWorkItemSnapshotProperty();
|
result.setProperty(property);
|
PropertySpec spec = propertySpec(property);
|
if (spec == null) {
|
result.setOutcomeCode("UNSUPPORTED_PROPERTY");
|
result.setReason("未支持的 LIMS_TASK property:" + property);
|
} else {
|
result.setDataType(spec.dataType);
|
result.setSource(LIMS_TASK);
|
result.setSourceRef(item.getTestWorkItemId());
|
if (!readable) {
|
result.setOutcomeCode("NOT_AVAILABLE");
|
result.setReason("检验项任务快照不可读取");
|
} else if (!StringUtils.hasText(spec.value(task))) {
|
result.setOutcomeCode("MISSING");
|
result.setReason("检验任务快照中缺少" + spec.label);
|
} else {
|
result.setValue(spec.value(task));
|
result.setOutcomeCode("SUCCESS");
|
}
|
}
|
item.getProperties().add(result);
|
}
|
}
|
|
private static PropertySpec propertySpec(String property) {
|
if (TEST_BASIS.equals(property) || LEGACY_INSPECTION_BASIS.equals(property)) {
|
return new PropertySpec(TEXT, "检验依据", LimsJianyanXiangEntity::getBiaozhunGuiding);
|
}
|
if (SAMPLE_NAME.equals(property)) return new PropertySpec(TEXT, "供试品名称", LimsJianyanXiangEntity::getChanpinMingcheng);
|
if (SAMPLE_BATCH_NO.equals(property)) return new PropertySpec(TEXT, "批号", LimsJianyanXiangEntity::getPihao);
|
if (SAMPLE_PRODUCTION_DATE.equals(property)) return new PropertySpec(DATE, "生产日期", task -> formatDate(task.getShengchanRiqi()));
|
if (QUALITY_STANDARD_SOURCE.equals(property)) return new PropertySpec(TEXT, "质量标准来源", LimsJianyanXiangEntity::getQualityStandardSource);
|
if (SAMPLE_SPECIFICATION.equals(property)) return new PropertySpec(TEXT, "规格/浓度", LimsJianyanXiangEntity::getGuige);
|
if (TEST_TYPE.equals(property) || LEGACY_INSPECTION_TYPE.equals(property)) {
|
return new PropertySpec(TEXT, "检验类型", LimsJianyanXiangEntity::getJianyanLeixing);
|
}
|
return null;
|
}
|
|
private static String formatDate(java.util.Date value) {
|
if (value == null) return null;
|
return new java.text.SimpleDateFormat("yyyy-MM-dd").format(value);
|
}
|
|
private interface PropertyValue {
|
String value(LimsJianyanXiangEntity task);
|
}
|
|
private static final class PropertySpec {
|
private final String dataType;
|
private final String label;
|
private final PropertyValue value;
|
|
private PropertySpec(String dataType, String label, PropertyValue value) {
|
this.dataType = dataType;
|
this.label = label;
|
this.value = value;
|
}
|
|
private String value(LimsJianyanXiangEntity task) {
|
return value.value(task);
|
}
|
}
|
|
private static boolean isDeleted(LimsJianyanXiangEntity task) {
|
return task.getDeleteMark() != null && task.getDeleteMark() == 1;
|
}
|
|
private static boolean isResponsible(LimsJianyanXiangEntity task, String userId) {
|
if (!StringUtils.hasText(userId)) {
|
return false;
|
}
|
String responsible = "yes".equalsIgnoreCase(task.getShifouWaijian())
|
? task.getWaijianLururen() : task.getJianchaRen();
|
return userId.equals(responsible);
|
}
|
|
private static void reject(TestWorkItemSnapshot item, String code, String reason) {
|
item.setOutcomeCode(code);
|
item.setReason(reason);
|
}
|
|
@FunctionalInterface
|
interface TaskLookup {
|
List<LimsJianyanXiangEntity> find(String tenantId, List<String> ids);
|
}
|
}
|