feat(mrhomepage): 死亡病例讨论记录
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.mrhomepage.appservice;
|
||||
|
||||
import com.healthlink.his.mrhomepage.domain.MrDeathDiscussion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IDeathDiscussionAppService {
|
||||
|
||||
MrDeathDiscussion saveDiscussion(MrDeathDiscussion discussion);
|
||||
|
||||
List<MrDeathDiscussion> getDiscussions(Long homepageId);
|
||||
|
||||
List<MrDeathDiscussion> checkDeadline();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.healthlink.his.web.mrhomepage.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.healthlink.his.mrhomepage.domain.MrDeathDiscussion;
|
||||
import com.healthlink.his.mrhomepage.service.IMrDeathDiscussionService;
|
||||
import com.healthlink.his.web.mrhomepage.appservice.IDeathDiscussionAppService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class DeathDiscussionAppServiceImpl implements IDeathDiscussionAppService {
|
||||
|
||||
@Resource
|
||||
private IMrDeathDiscussionService mrDeathDiscussionService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public MrDeathDiscussion saveDiscussion(MrDeathDiscussion discussion) {
|
||||
if (discussion.getId() == null) {
|
||||
if (discussion.getDeathDate() != null) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(discussion.getDeathDate());
|
||||
cal.add(Calendar.DAY_OF_MONTH, 7);
|
||||
discussion.setDeadlineDate(cal.getTime());
|
||||
}
|
||||
discussion.setIsOverdue(false);
|
||||
discussion.setStatus(0);
|
||||
}
|
||||
mrDeathDiscussionService.saveOrUpdate(discussion);
|
||||
return discussion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MrDeathDiscussion> getDiscussions(Long homepageId) {
|
||||
return mrDeathDiscussionService.list(
|
||||
new LambdaQueryWrapper<MrDeathDiscussion>()
|
||||
.eq(MrDeathDiscussion::getEncounterId, homepageId)
|
||||
.orderByDesc(MrDeathDiscussion::getDiscussionDate)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MrDeathDiscussion> checkDeadline() {
|
||||
Date now = new Date();
|
||||
List<MrDeathDiscussion> overdue = mrDeathDiscussionService.list(
|
||||
new LambdaQueryWrapper<MrDeathDiscussion>()
|
||||
.le(MrDeathDiscussion::getDeadlineDate, now)
|
||||
.eq(MrDeathDiscussion::getIsOverdue, false)
|
||||
.eq(MrDeathDiscussion::getStatus, 0)
|
||||
);
|
||||
for (MrDeathDiscussion d : overdue) {
|
||||
d.setIsOverdue(true);
|
||||
}
|
||||
if (!overdue.isEmpty()) {
|
||||
mrDeathDiscussionService.updateBatchById(overdue);
|
||||
}
|
||||
return overdue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.healthlink.his.web.mrhomepage.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.mrhomepage.domain.MrDeathDiscussion;
|
||||
import com.healthlink.his.web.mrhomepage.appservice.IDeathDiscussionAppService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/mr-homepage/death-discussion")
|
||||
@Tag(name = "死亡病例讨论记录")
|
||||
public class DeathDiscussionController {
|
||||
|
||||
@Resource
|
||||
private IDeathDiscussionAppService deathDiscussionAppService;
|
||||
|
||||
@PostMapping("/save")
|
||||
@PreAuthorize("hasAuthority('inpatient:mrhomepage:edit')")
|
||||
@Operation(summary = "保存死亡病例讨论记录")
|
||||
public R<MrDeathDiscussion> saveDiscussion(@RequestBody MrDeathDiscussion discussion) {
|
||||
return R.ok(deathDiscussionAppService.saveDiscussion(discussion));
|
||||
}
|
||||
|
||||
@GetMapping("/list/{homepageId}")
|
||||
@PreAuthorize("hasAuthority('inpatient:mrhomepage:list')")
|
||||
@Operation(summary = "查询死亡病例讨论记录列表")
|
||||
public R<List<MrDeathDiscussion>> getDiscussions(@PathVariable Long homepageId) {
|
||||
return R.ok(deathDiscussionAppService.getDiscussions(homepageId));
|
||||
}
|
||||
|
||||
@GetMapping("/pending-deadline")
|
||||
@PreAuthorize("hasAuthority('inpatient:mrhomepage:list')")
|
||||
@Operation(summary = "查询7日到期未讨论记录")
|
||||
public R<List<MrDeathDiscussion>> checkDeadline() {
|
||||
return R.ok(deathDiscussionAppService.checkDeadline());
|
||||
}
|
||||
}
|
||||
@@ -11,3 +11,6 @@ export function getQualityResults(homepageId) { return request({ url: '/api/v1/m
|
||||
export function submitHqmsReport(homepageId, reportType) { return request({ url: '/api/v1/mr-homepage/hqms/report', method: 'post', params: { homepageId, reportType } }) }
|
||||
export function getHqmsReportStatus(homepageId) { return request({ url: '/api/v1/mr-homepage/hqms/status/' + homepageId, method: 'get' }) }
|
||||
export function listHqmsReports(homepageId) { return request({ url: '/api/v1/mr-homepage/hqms/list/' + homepageId, method: 'get' }) }
|
||||
export function saveDeathDiscussion(data) { return request({ url: '/api/v1/mr-homepage/death-discussion/save', method: 'post', data }) }
|
||||
export function listDeathDiscussions(homepageId) { return request({ url: '/api/v1/mr-homepage/death-discussion/list/' + homepageId, method: 'get' }) }
|
||||
export function getPendingDeadline() { return request({ url: '/api/v1/mr-homepage/death-discussion/pending-deadline', method: 'get' }) }
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>死亡病例讨论记录</span>
|
||||
<div>
|
||||
<el-input
|
||||
v-model="homepageId"
|
||||
placeholder="请输入病案首页ID"
|
||||
style="width: 220px; margin-right: 12px"
|
||||
@keyup.enter="loadDiscussions"
|
||||
/>
|
||||
<el-button type="primary" :loading="loading" @click="loadDiscussions">
|
||||
查询
|
||||
</el-button>
|
||||
<el-button type="warning" :loading="deadlineLoading" @click="checkDeadline" style="margin-left: 8px">
|
||||
到期检查
|
||||
</el-button>
|
||||
<el-button type="success" @click="showAddDialog" style="margin-left: 8px">
|
||||
新增讨论
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-alert
|
||||
v-if="pendingDeadline.length > 0"
|
||||
:title="'有 ' + pendingDeadline.length + ' 条死亡病例已超过7日期限未讨论'"
|
||||
type="warning"
|
||||
show-icon
|
||||
:closable="false"
|
||||
style="margin-bottom: 16px"
|
||||
>
|
||||
<template #default>
|
||||
<div v-for="item in pendingDeadline" :key="item.id" style="margin-top: 4px; font-size: 13px">
|
||||
患者:{{ item.patientName }} | 死亡日期:{{ item.deathDate }} | 截止日期:{{ item.deadlineDate }}
|
||||
</div>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
||||
<el-table :data="discussions" stripe border style="width: 100%">
|
||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||
<el-table-column prop="deathDate" label="死亡日期" width="170" />
|
||||
<el-table-column prop="discussionDate" label="讨论日期" width="170" />
|
||||
<el-table-column prop="deadlineDate" label="讨论截止" width="170">
|
||||
<template #default="scope">
|
||||
<span :style="{ color: scope.row.isOverdue ? '#f56c6c' : '' }">
|
||||
{{ scope.row.deadlineDate }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="hostDoctorName" label="主持人" width="120" />
|
||||
<el-table-column prop="participants" label="参加人员" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="discussionConclusion" label="讨论结论" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === 1 ? 'success' : (scope.row.isOverdue ? 'danger' : 'warning')" size="small">
|
||||
{{ scope.row.status === 1 ? '已完成' : (scope.row.isOverdue ? '已逾期' : '待讨论') }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-if="scope.row.status === 0"
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="showEditDialog(scope.row)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑讨论记录' : '新增讨论记录'" width="700px">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
|
||||
<el-form-item label="病案首页ID" prop="encounterId">
|
||||
<el-input-number v-model="form.encounterId" :min="1" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="患者姓名" prop="patientName">
|
||||
<el-input v-model="form.patientName" placeholder="请输入患者姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="患者ID" prop="patientId">
|
||||
<el-input-number v-model="form.patientId" :min="1" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="死亡日期" prop="deathDate">
|
||||
<el-date-picker
|
||||
v-model="form.deathDate"
|
||||
type="datetime"
|
||||
placeholder="选择死亡日期"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论日期" prop="discussionDate">
|
||||
<el-date-picker
|
||||
v-model="form.discussionDate"
|
||||
type="datetime"
|
||||
placeholder="选择讨论日期"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="主持人" prop="hostDoctorName">
|
||||
<el-input v-model="form.hostDoctorName" placeholder="请输入主持人姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="主持人职称">
|
||||
<el-input v-model="form.hostTitle" placeholder="请输入主持人职称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参加人员">
|
||||
<el-input v-model="form.participants" placeholder="请输入参加人员(逗号分隔)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="讨论结论">
|
||||
<el-input v-model="form.discussionConclusion" type="textarea" :rows="3" placeholder="请输入讨论结论" />
|
||||
</el-form-item>
|
||||
<el-form-item label="改进措施">
|
||||
<el-input v-model="form.improvementMeasures" type="textarea" :rows="3" placeholder="请输入改进措施" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">
|
||||
保存
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { saveDeathDiscussion, listDeathDiscussions, getPendingDeadline } from '@/api/mrhomepage'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const homepageId = ref('')
|
||||
const loading = ref(false)
|
||||
const deadlineLoading = ref(false)
|
||||
const discussions = ref([])
|
||||
const pendingDeadline = ref([])
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const isEdit = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref(null)
|
||||
|
||||
const form = reactive({
|
||||
id: null,
|
||||
encounterId: null,
|
||||
patientId: null,
|
||||
patientName: '',
|
||||
deathDate: null,
|
||||
discussionDate: null,
|
||||
hostDoctorName: '',
|
||||
hostTitle: '',
|
||||
participants: '',
|
||||
discussionConclusion: '',
|
||||
improvementMeasures: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
encounterId: [{ required: true, message: '请输入病案首页ID', trigger: 'blur' }],
|
||||
patientName: [{ required: true, message: '请输入患者姓名', trigger: 'blur' }],
|
||||
patientId: [{ required: true, message: '请输入患者ID', trigger: 'blur' }],
|
||||
deathDate: [{ required: true, message: '请选择死亡日期', trigger: 'change' }],
|
||||
discussionDate: [{ required: true, message: '请选择讨论日期', trigger: 'change' }],
|
||||
hostDoctorName: [{ required: true, message: '请输入主持人', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
form.id = null
|
||||
form.encounterId = homepageId.value ? Number(homepageId.value) : null
|
||||
form.patientId = null
|
||||
form.patientName = ''
|
||||
form.deathDate = null
|
||||
form.discussionDate = null
|
||||
form.hostDoctorName = ''
|
||||
form.hostTitle = ''
|
||||
form.participants = ''
|
||||
form.discussionConclusion = ''
|
||||
form.improvementMeasures = ''
|
||||
}
|
||||
|
||||
const showAddDialog = () => {
|
||||
isEdit.value = false
|
||||
resetForm()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const showEditDialog = (row) => {
|
||||
isEdit.value = true
|
||||
Object.assign(form, {
|
||||
id: row.id,
|
||||
encounterId: row.encounterId,
|
||||
patientId: row.patientId,
|
||||
patientName: row.patientName,
|
||||
deathDate: row.deathDate,
|
||||
discussionDate: row.discussionDate,
|
||||
hostDoctorName: row.hostDoctorName,
|
||||
hostTitle: row.hostTitle,
|
||||
participants: row.participants,
|
||||
discussionConclusion: row.discussionConclusion,
|
||||
improvementMeasures: row.improvementMeasures
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const loadDiscussions = async () => {
|
||||
if (!homepageId.value) {
|
||||
ElMessage.warning('请输入病案首页ID')
|
||||
return
|
||||
}
|
||||
loading.value = true
|
||||
try {
|
||||
discussions.value = await listDeathDiscussions(homepageId.value)
|
||||
} catch (e) {
|
||||
ElMessage.error('查询失败: ' + (e.message || '未知错误'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const checkDeadline = async () => {
|
||||
deadlineLoading.value = true
|
||||
try {
|
||||
pendingDeadline.value = await getPendingDeadline()
|
||||
if (pendingDeadline.value.length === 0) {
|
||||
ElMessage.success('暂无到期记录')
|
||||
} else {
|
||||
ElMessage.warning('发现 ' + pendingDeadline.value.length + ' 条到期记录')
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error('检查失败: ' + (e.message || '未知错误'))
|
||||
} finally {
|
||||
deadlineLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
await formRef.value.validate()
|
||||
submitLoading.value = true
|
||||
try {
|
||||
await saveDeathDiscussion({ ...form })
|
||||
ElMessage.success('保存成功')
|
||||
dialogVisible.value = false
|
||||
if (homepageId.value) {
|
||||
loadDiscussions()
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error('保存失败: ' + (e.message || '未知错误'))
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user