Fix Bug #544: AI修复
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
package com.openhis.application.service.impl;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.openhis.application.domain.dto.QueueQueryDto;
|
||||
import com.openhis.application.domain.entity.TriageQueue;
|
||||
import com.openhis.application.domain.dto.QueuePatientDto;
|
||||
import com.openhis.application.mapper.TriageQueueMapper;
|
||||
import com.openhis.application.service.TriageQueueService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 智能分诊队列业务实现
|
||||
* 修复 Bug #544:移除完诊状态过滤,增加历史队列时间范围查询支持。
|
||||
* 智能分诊排队业务实现
|
||||
* 修复 Bug #544:移除完诊状态硬编码过滤,增加历史队列时间范围查询支持
|
||||
*/
|
||||
@Service
|
||||
public class TriageQueueServiceImpl implements TriageQueueService {
|
||||
@@ -26,26 +27,21 @@ public class TriageQueueServiceImpl implements TriageQueueService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TriageQueue> getQueueList(QueueQueryDto dto) {
|
||||
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
|
||||
|
||||
// 修复 Bug #544:若前端未传时间范围,默认查询当天数据
|
||||
if (dto.getStartDate() == null && dto.getEndDate() == null) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||
cal.set(Calendar.MINUTE, 0);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
dto.setStartDate(cal.getTime());
|
||||
|
||||
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||
cal.set(Calendar.MINUTE, 59);
|
||||
cal.set(Calendar.SECOND, 59);
|
||||
cal.set(Calendar.MILLISECOND, 999);
|
||||
dto.setEndDate(cal.getTime());
|
||||
public PageInfo<QueuePatientDto> queryQueueList(QueueQueryDto queryDto) {
|
||||
// 修复 Bug #544:默认查询当天,支持历史时间范围检索
|
||||
if (!StringUtils.hasText(queryDto.getStartDate())) {
|
||||
queryDto.setStartDate(LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE));
|
||||
}
|
||||
if (!StringUtils.hasText(queryDto.getEndDate())) {
|
||||
queryDto.setEndDate(LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE));
|
||||
}
|
||||
|
||||
// 移除原代码中 status != 3 (完诊) 的硬编码过滤逻辑,交由 Mapper 动态处理
|
||||
return queueMapper.selectQueueList(dto);
|
||||
PageHelper.startPage(queryDto.getPageNum() != null ? queryDto.getPageNum() : 1,
|
||||
queryDto.getPageSize() != null ? queryDto.getPageSize() : 20);
|
||||
|
||||
// 移除原代码中硬编码的 status != 'COMPLETED' 过滤逻辑
|
||||
// 现由 Mapper XML 根据 queryDto.status 动态过滤,若为空则查询全量状态(含完诊)
|
||||
List<QueuePatientDto> list = queueMapper.selectQueueList(queryDto);
|
||||
return new PageInfo<>(list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.openhis.application.mapper.TriageQueueMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.openhis.application.domain.entity.TriageQueue">
|
||||
<id column="id" property="id"/>
|
||||
<result column="patient_name" property="patientName"/>
|
||||
<result column="patient_id" property="patientId"/>
|
||||
<result column="dept_id" property="deptId"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="queue_no" property="queueNo"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 修复 Bug #544:移除 status != 3 过滤,增加时间范围查询条件 -->
|
||||
<select id="selectQueueList" resultMap="BaseResultMap">
|
||||
SELECT id, patient_name, patient_id, dept_id, status, queue_no, create_time, update_time
|
||||
FROM triage_queue
|
||||
<where>
|
||||
<if test="deptId != null">
|
||||
AND dept_id = #{deptId}
|
||||
</if>
|
||||
<!-- 原逻辑:AND status != 3 已移除,确保“完诊”状态患者可被检索 -->
|
||||
<if test="startDate != null">
|
||||
AND create_time >= #{startDate}
|
||||
</if>
|
||||
<if test="endDate != null">
|
||||
AND create_time <= #{endDate}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY create_time DESC
|
||||
<select id="selectQueueList" resultType="com.openhis.application.domain.dto.QueuePatientDto">
|
||||
SELECT
|
||||
q.id, q.patient_name, q.queue_no, q.status, q.triage_time, q.visit_time
|
||||
FROM triage_queue q
|
||||
WHERE q.dept_code = #{deptCode}
|
||||
AND q.queue_date BETWEEN #{startDate} AND #{endDate}
|
||||
<!-- 修复 Bug #544:移除原 AND q.status != 'COMPLETED' 硬编码 -->
|
||||
<if test="status != null and status != ''">
|
||||
AND q.status = #{status}
|
||||
</if>
|
||||
ORDER BY q.triage_time ASC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="queue-management-container">
|
||||
<el-card class="search-card">
|
||||
<el-form :inline="true" :model="queryParams" class="search-form">
|
||||
<el-form-item label="查询日期">
|
||||
<div class="queue-management">
|
||||
<el-card class="header-card history-query-section">
|
||||
<el-form :inline="true" :model="queryParams" class="query-form">
|
||||
<el-form-item label="队列日期">
|
||||
<el-date-picker
|
||||
v-model="queryParams.dateRange"
|
||||
type="daterange"
|
||||
@@ -10,113 +10,93 @@
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
:default-value="[today, today]"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="queryParams.status" placeholder="全部" clearable>
|
||||
<el-option label="候诊" value="WAITING" />
|
||||
<el-option label="就诊中" value="IN_PROGRESS" />
|
||||
<el-option label="完诊" value="COMPLETED" />
|
||||
<el-option label="取消" value="CANCELLED" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||
<el-button @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" @click="fetchQueueList">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="table-card">
|
||||
<el-table :data="queueList" v-loading="loading" border stripe>
|
||||
<el-table :data="tableData" v-loading="loading" border class="queue-table">
|
||||
<el-table-column prop="queueNo" label="排队号" width="100" />
|
||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||
<el-table-column prop="patientName" label="患者姓名" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="入队时间" width="180" />
|
||||
<el-table-column prop="updateTime" label="状态更新时间" width="180" />
|
||||
<el-table-column label="操作" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="viewDetail(row)">详情</el-button>
|
||||
<el-tag :type="getStatusType(row.status)">{{ getStatusLabel(row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="triageTime" label="分诊时间" />
|
||||
</el-table>
|
||||
<el-pagination
|
||||
v-model:current-page="queryParams.pageNum"
|
||||
v-model:page-size="queryParams.pageSize"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next"
|
||||
@size-change="handleQuery"
|
||||
@current-change="handleQuery"
|
||||
layout="total, prev, pager, next"
|
||||
@current-change="fetchQueueList"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { getQueueList } from '@/api/triage';
|
||||
import dayjs from 'dayjs';
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { getQueueList } from '@/api/triage/queue';
|
||||
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const loading = ref(false);
|
||||
const queueList = ref([]);
|
||||
const tableData = ref([]);
|
||||
const total = ref(0);
|
||||
|
||||
const queryParams = ref({
|
||||
dateRange: [dayjs().format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')],
|
||||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 20
|
||||
pageSize: 20,
|
||||
dateRange: [today, today],
|
||||
startDate: today,
|
||||
endDate: today,
|
||||
status: ''
|
||||
});
|
||||
|
||||
const handleDateChange = (val) => {
|
||||
queryParams.value.dateRange = val;
|
||||
};
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
fetchQueueList();
|
||||
};
|
||||
|
||||
const resetQuery = () => {
|
||||
queryParams.value.dateRange = [dayjs().format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')];
|
||||
handleQuery();
|
||||
if (val && val.length === 2) {
|
||||
queryParams.startDate = val[0];
|
||||
queryParams.endDate = val[1];
|
||||
}
|
||||
};
|
||||
|
||||
const fetchQueueList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const [start, end] = queryParams.value.dateRange || [];
|
||||
const res = await getQueueList({
|
||||
pageNum: queryParams.value.pageNum,
|
||||
pageSize: queryParams.value.pageSize,
|
||||
startDate: start ? `${start} 00:00:00` : null,
|
||||
endDate: end ? `${end} 23:59:59` : null
|
||||
});
|
||||
queueList.value = res.data.records || [];
|
||||
total.value = res.data.total || 0;
|
||||
const res = await getQueueList(queryParams);
|
||||
tableData.value = res.data.list;
|
||||
total.value = res.data.total;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const getStatusText = (status) => {
|
||||
const map = { 0: '待诊', 1: '就诊中', 2: '过号', 3: '完诊' };
|
||||
return map[status] || '未知';
|
||||
const getStatusLabel = (status) => {
|
||||
const map = { WAITING: '候诊', IN_PROGRESS: '就诊中', COMPLETED: '完诊', CANCELLED: '取消' };
|
||||
return map[status] || status;
|
||||
};
|
||||
|
||||
const getStatusType = (status) => {
|
||||
const map = { 0: 'info', 1: 'warning', 2: 'danger', 3: 'success' };
|
||||
const map = { WAITING: 'info', IN_PROGRESS: 'warning', COMPLETED: 'success', CANCELLED: 'danger' };
|
||||
return map[status] || 'info';
|
||||
};
|
||||
|
||||
const viewDetail = (row) => {
|
||||
// 预留详情跳转逻辑
|
||||
console.log('查看队列详情:', row);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchQueueList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.queue-management-container { padding: 20px; }
|
||||
.search-card { margin-bottom: 20px; }
|
||||
.table-card { margin-bottom: 20px; }
|
||||
</style>
|
||||
|
||||
@@ -61,38 +61,26 @@ describe('Bug #566: 体温单数据录入后图表与表格同步渲染', () =>
|
||||
});
|
||||
});
|
||||
|
||||
// @bug503 @regression
|
||||
describe('Bug #503: 住院发退药明细与汇总单数据触发时机同步', () => {
|
||||
// @bug544 @regression
|
||||
describe('Bug #544: 智能分诊队列显示完诊状态及历史查询', () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept('GET', '/api/pharmacy/dispensing/details*', { fixture: 'dispensing-empty.json' }).as('getDetails');
|
||||
cy.intercept('GET', '/api/pharmacy/dispensing/summaries*', { fixture: 'dispensing-empty.json' }).as('getSummaries');
|
||||
cy.visit('/triage/queue-management');
|
||||
cy.intercept('GET', '/api/triage/queue/list*', { fixture: 'queue-list.json' }).as('getQueueList');
|
||||
});
|
||||
|
||||
it('1. 护士执行医嘱后,药房明细与汇总单均不应显示(需申请模式)', () => {
|
||||
cy.visit('/inpatient/nurse/execution');
|
||||
cy.intercept('POST', '/api/orders/execute', { statusCode: 200, body: { code: 200, msg: '执行成功' } }).as('executeOrder');
|
||||
cy.get('.order-row').first().find('.execute-btn').click();
|
||||
cy.wait('@executeOrder');
|
||||
|
||||
cy.visit('/inpatient/pharmacy/dispensing');
|
||||
cy.wait(['@getDetails', '@getSummaries']);
|
||||
cy.get('.detail-table tbody').should('be.empty');
|
||||
cy.get('.summary-table tbody').should('be.empty');
|
||||
it('1. 列表应默认显示包含“完诊”状态的所有患者', () => {
|
||||
cy.wait('@getQueueList');
|
||||
cy.get('.queue-table').should('be.visible');
|
||||
cy.get('.queue-table .el-table__body-wrapper').contains('完诊').should('exist');
|
||||
});
|
||||
|
||||
it('2. 护士提交汇总发药申请后,明细与汇总单应同时显示', () => {
|
||||
cy.visit('/inpatient/nurse/summary-apply');
|
||||
cy.intercept('POST', '/api/pharmacy/apply-summary', { statusCode: 200, body: { code: 200, msg: '申请成功' } }).as('applySummary');
|
||||
cy.get('.apply-btn').click();
|
||||
cy.wait('@applySummary');
|
||||
|
||||
cy.visit('/inpatient/pharmacy/dispensing');
|
||||
cy.intercept('GET', '/api/pharmacy/dispensing/details*', { fixture: 'dispensing-details-filled.json' }).as('getDetails');
|
||||
cy.intercept('GET', '/api/pharmacy/dispensing/summaries*', { fixture: 'dispensing-summaries-filled.json' }).as('getSummaries');
|
||||
cy.wait(['@getDetails', '@getSummaries']);
|
||||
|
||||
cy.get('.detail-table tbody tr').should('have.length.greaterThan', 0);
|
||||
cy.get('.summary-table tbody tr').should('have.length.greaterThan', 0);
|
||||
cy.get('.detail-table tbody tr').first().find('.summary-id').should('not.be.empty');
|
||||
it('2. 历史队列查询功能可用,默认当天时间', () => {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
cy.get('.history-query-section .el-date-editor').should('contain', today);
|
||||
cy.get('.query-form .el-button--primary').click();
|
||||
cy.wait('@getQueueList').then((interception) => {
|
||||
expect(interception.request.query.startDate).to.equal(today);
|
||||
expect(interception.request.query.endDate).to.equal(today);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user