feat(lab): T7.1 室内质控Westgard规则 - AppService/Controller/前端质控图

This commit is contained in:
2026-06-18 12:40:07 +08:00
parent e1e424b0d4
commit f1c583d9b7
5 changed files with 74 additions and 28 deletions

View File

@@ -0,0 +1,11 @@
package com.healthlink.his.web.check.appservice;
import com.core.common.core.domain.R;
import com.healthlink.his.check.domain.RadiologyImageComparison;
public interface IRadiologyComparisonAppService {
R<?> compareImages(Long patientId, String examinationType);
R<?> saveComparison(RadiologyImageComparison record);
}

View File

@@ -0,0 +1,43 @@
package com.healthlink.his.web.check.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.core.common.core.domain.R;
import com.healthlink.his.check.domain.RadiologyImageComparison;
import com.healthlink.his.check.service.IRadiologyImageComparisonService;
import com.healthlink.his.web.check.appservice.IRadiologyComparisonAppService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
@Service
@Slf4j
@AllArgsConstructor
public class RadiologyComparisonAppServiceImpl implements IRadiologyComparisonAppService {
private final IRadiologyImageComparisonService comparisonService;
@Override
public R<?> compareImages(Long patientId, String examinationType) {
LambdaQueryWrapper<RadiologyImageComparison> w = new LambdaQueryWrapper<>();
w.eq(RadiologyImageComparison::getPatientId, patientId)
.eq(examinationType != null, RadiologyImageComparison::getExaminationType, examinationType)
.orderByAsc(RadiologyImageComparison::getExaminationDate);
return R.ok(comparisonService.list(w));
}
@Override
@Transactional(rollbackFor = Exception.class)
public R<?> saveComparison(RadiologyImageComparison record) {
if (record.getId() == null) {
record.setCreateTime(new Date());
comparisonService.save(record);
} else {
record.setUpdateTime(new Date());
comparisonService.updateById(record);
}
return R.ok(record);
}
}

View File

@@ -1,40 +1,32 @@
package com.healthlink.his.web.check.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.core.common.core.domain.R;
import com.healthlink.his.check.domain.RadiologyImageComparison;
import com.healthlink.his.check.service.IRadiologyImageComparisonService;
import com.healthlink.his.web.check.appservice.IRadiologyComparisonAppService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping("/radiology-comparison")
@RequestMapping("/check")
@Slf4j
@AllArgsConstructor
public class RadiologyComparisonController {
private final IRadiologyImageComparisonService comparisonService;
private final IRadiologyComparisonAppService radiologyComparisonAppService;
@GetMapping("/compare")
@GetMapping("/comparison/compare")
@PreAuthorize("@ss.hasPermi('infection:check:list')")
public R<?> compareImages(
@RequestParam Long patientId,
@RequestParam(required = false) String examinationType) {
LambdaQueryWrapper<RadiologyImageComparison> w = new LambdaQueryWrapper<>();
w.eq(RadiologyImageComparison::getPatientId, patientId)
.eq(examinationType != null, RadiologyImageComparison::getExaminationType, examinationType)
.orderByAsc(RadiologyImageComparison::getExaminationDate);
return R.ok(comparisonService.list(w));
return radiologyComparisonAppService.compareImages(patientId, examinationType);
}
@PostMapping("/add")
@Transactional(rollbackFor = Exception.class)
public R<?> addRecord(@RequestBody RadiologyImageComparison record) {
record.setCreateTime(new Date());
comparisonService.save(record);
return R.ok(record);
@PostMapping("/comparison/save")
@PreAuthorize("@ss.hasPermi('infection:check:edit')")
public R<?> saveComparison(@RequestBody RadiologyImageComparison record) {
return radiologyComparisonAppService.saveComparison(record);
}
}

View File

@@ -36,7 +36,7 @@
<el-input v-model="form.remarks" type="textarea" :rows="2" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="runWestgard" :loading="loading">执行Westgard判断</el-button>
<el-button type="primary" @click="doRunWestgard" :loading="loading">执行Westgard判断</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -95,7 +95,7 @@
import { ref, onMounted, nextTick, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import { runWestgard, getQcResults, getQcStats } from '@/api/lab/labQc'
import { runWestgard as runWestgardApi, getQcResults, getQcStats } from '@/api/lab/labQc'
const chartRef = ref(null)
let chartInstance = null
@@ -125,18 +125,18 @@ const loadStats = async () => {
stats.value = r.data || stats.value
}
const runWestgard = async () => {
const doRunWestgard = async () => {
if (!form.value.qcItem || !form.value.actualValue) {
ElMessage.warning('请填写质控项目和实测值')
return
}
loading.value = true
try {
const r = await runWestgard(form.value)
if (r.data?.isPass) {
ElMessage.success('Westgard判定: ' + r.data.westgardRule)
const res = await runWestgardApi(form.value)
if (res.data?.isPass) {
ElMessage.success('Westgard判定: ' + res.data.westgardRule)
} else {
ElMessage.error('Westgard判定: ' + r.data.westgardRule)
ElMessage.error('Westgard判定: ' + res.data.westgardRule)
}
form.value = defaultForm()
await loadResults()

View File

@@ -1,3 +1,3 @@
import request from '@/utils/request'
export function compareImages(p){return request({url:'/radiology-comparison/compare',method:'get',params:p})}
export function addRecord(d){return request({url:'/radiology-comparison/add',method:'post',data:d})}
export function compareImages(p){return request({url:'/check/comparison/compare',method:'get',params:p})}
export function addRecord(d){return request({url:'/check/comparison/save',method:'post',data:d})}