feat(V42): 手术安全核查 — 完整前端+DB修复+2/2 API通过
前端: - SurgerySafetyCheck: 完整CRUD页面(搜索/新增/编辑/删除) - 三阶段核查: PRE_OP/INTRA_OP/POST_OP - 三方核查人员: 主刀医生/麻醉医师/巡回护士 数据库修复: - surgery_safety_check: 添加update_by/update_time/delete_flag/tenant_id - 放宽encounter_id/patient_id/check_items NOT NULL约束 测试: 2/2 API通过(新增/分页查询)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import request from '@/utils/request'
|
||||
export function getPage(p){return request({url:'/surgery-safety-check/page',method:'get',params:p})}
|
||||
export function getList(p){return request({url:'/surgery-safety-check/list',method:'get',params:p})}
|
||||
export function getById(id){return request({url:'/surgery-safety-check/'+id,method:'get'})}
|
||||
export function add(d){return request({url:'/surgery-safety-check/add',method:'post',data:d})}
|
||||
export function update(d){return request({url:'/surgery-safety-check/update',method:'put',data:d})}
|
||||
export function del(id){return request({url:'/surgery-safety-check/delete/'+id,method:'delete'})}
|
||||
export function getPage(p) { return request({ url: '/surgery-safety-check/page', method: 'get', params: p }) }
|
||||
export function getList(encounterId) { return request({ url: '/surgery-safety-check/list', method: 'get', params: { encounterId } }) }
|
||||
export function getById(id) { return request({ url: '/surgery-safety-check/' + id, method: 'get' }) }
|
||||
export function addCheck(d) { return request({ url: '/surgery-safety-check/add', method: 'post', data: d }) }
|
||||
export function updateCheck(d) { return request({ url: '/surgery-safety-check/update', method: 'put', data: d }) }
|
||||
export function deleteCheck(id) { return request({ url: '/surgery-safety-check/delete/' + id, method: 'delete' }) }
|
||||
|
||||
@@ -1,93 +1,94 @@
|
||||
<template>
|
||||
<div style="padding:16px">
|
||||
<div style="margin-bottom:16px"><span style="font-size:18px;font-weight:bold">术前安全核查</span></div>
|
||||
<div style="margin-bottom:12px;display:flex;gap:8px;flex-wrap:wrap">
|
||||
<el-input v-model="q.patientName" placeholder="患者姓名" clearable style="width:140px"/>
|
||||
<el-select v-model="q.checkPhase" placeholder="核查阶段" clearable style="width:140px">
|
||||
<el-option label="麻醉前" value="ANESTHESIA_BEFORE"/>
|
||||
<el-option label="手术前" value="SURGERY_BEFORE"/>
|
||||
<el-option label="离室前" value="EXIT"/>
|
||||
</el-select>
|
||||
<el-button type="primary" @click="loadData">查询</el-button>
|
||||
<el-button type="success" @click="openAdd">新增核查</el-button>
|
||||
</div>
|
||||
<el-table :data="tableData" border stripe>
|
||||
<el-table-column prop="patientName" label="患者" width="100"/>
|
||||
<el-table-column prop="surgeryName" label="手术名称" width="160"/>
|
||||
<el-table-column prop="checkPhase" label="阶段" width="90">
|
||||
<template #default="{row}">
|
||||
<el-tag v-if="row.checkPhase==='ANESTHESIA_BEFORE'" type="warning" size="small">麻醉前</el-tag>
|
||||
<el-tag v-else-if="row.checkPhase==='SURGERY_BEFORE'" type="primary" size="small">手术前</el-tag>
|
||||
<el-tag v-else type="success" size="small">离室前</el-tag>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" :inline="true" v-show="showSearch">
|
||||
<el-form-item label="患者"><el-input v-model="queryParams.patientName" placeholder="患者姓名" clearable /></el-form-item>
|
||||
<el-form-item label="核查阶段">
|
||||
<el-select v-model="queryParams.checkPhase" placeholder="全部" clearable>
|
||||
<el-option label="术前" value="PRE_OP" /><el-option label="术中" value="INTRA_OP" /><el-option label="术后" value="POST_OP" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="dataList">
|
||||
<el-table-column label="患者" prop="patientName" width="100" />
|
||||
<el-table-column label="手术名称" prop="surgeryName" width="150" show-overflow-tooltip />
|
||||
<el-table-column label="核查阶段" prop="checkPhase" width="90">
|
||||
<template #default="s">
|
||||
<el-tag>{{ {PRE_OP:'术前',INTRA_OP:'术中',POST_OP:'术后'}[s.row.checkPhase] || s.row.checkPhase }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="checkTime" label="核查时间" width="170"/>
|
||||
<el-table-column prop="surgeonName" label="主刀" width="80"/>
|
||||
<el-table-column prop="anesthesiologistName" label="麻醉" width="80"/>
|
||||
<el-table-column prop="nurseName" label="护士" width="80"/>
|
||||
<el-table-column label="核查项" width="200">
|
||||
<template #default="{row}">
|
||||
<el-tag v-if="row.patientIdConfirmed" type="success" size="small">身份✓</el-tag>
|
||||
<el-tag v-if="row.surgerySiteConfirmed" type="success" size="small">术野✓</el-tag>
|
||||
<el-tag v-if="row.procedureTypeConfirmed" type="success" size="small">术式✓</el-tag>
|
||||
<el-tag v-if="row.allergyConfirmed" type="success" size="small">过敏✓</el-tag>
|
||||
<el-table-column label="主刀医生" prop="surgeonName" width="100" />
|
||||
<el-table-column label="麻醉医师" prop="anesthesiologistName" width="100" />
|
||||
<el-table-column label="巡回护士" prop="circulatingNurseName" width="100" />
|
||||
<el-table-column label="核查时间" prop="checkTime" width="170" />
|
||||
<el-table-column label="状态" prop="status" width="90">
|
||||
<template #default="s">
|
||||
<el-tag :type="s.row.status==='COMPLETED'?'success':s.row.status==='PENDING'?'danger':'warning'">
|
||||
{{ {PENDING:'待核查',IN_PROGRESS:'核查中',COMPLETED:'已完成'}[s.row.status] || s.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140">
|
||||
<template #default="{row}">
|
||||
<el-button type="primary" link size="small" @click="openEdit(row)">编辑</el-button>
|
||||
<el-popconfirm title="确定删除?" @confirm="delItem(row.id)">
|
||||
<template #reference><el-button type="danger" link size="small">删除</el-button></template>
|
||||
</el-popconfirm>
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="s">
|
||||
<el-button link type="primary" @click="handleEdit(s.row)">编辑</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(s.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination style="margin-top:12px;justify-content:flex-end" v-model:current-page="q.pageNo" v-model:page-size="q.pageSize" :total="total" layout="total,prev,pager,next" @current-change="loadData"/>
|
||||
<el-dialog v-model="dlgVisible" :title="isEdit?'编辑核查':'新增核查'" width="650px">
|
||||
<el-form :model="form" label-width="90px">
|
||||
<el-form-item label="患者ID"><el-input v-model.number="form.patientId"/></el-form-item>
|
||||
<el-form-item label="就诊ID"><el-input v-model.number="form.encounterId"/></el-form-item>
|
||||
<el-form-item label="患者姓名"><el-input v-model="form.patientName"/></el-form-item>
|
||||
<el-form-item label="手术名称"><el-input v-model="form.surgeryName"/></el-form-item>
|
||||
<el-form-item label="核查阶段">
|
||||
<el-select v-model="form.checkPhase">
|
||||
<el-option label="麻醉前" value="ANESTHESIA_BEFORE"/>
|
||||
<el-option label="手术前" value="SURGERY_BEFORE"/>
|
||||
<el-option label="离室前" value="EXIT"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="核查时间"><el-date-picker v-model="form.checkTime" type="datetime"/></el-form-item>
|
||||
<el-form-item label="身份确认"><el-switch v-model="form.patientIdConfirmed"/></el-form-item>
|
||||
<el-form-item label="术野确认"><el-switch v-model="form.surgerySiteConfirmed"/></el-form-item>
|
||||
<el-form-item label="术式确认"><el-switch v-model="form.procedureTypeConfirmed"/></el-form-item>
|
||||
<el-form-item label="过敏确认"><el-switch v-model="form.allergyConfirmed"/></el-form-item>
|
||||
<el-form-item label="生命体征"><el-switch v-model="form.vitalSignsBaseline"/></el-form-item>
|
||||
<el-form-item label="危急值"><el-switch v-model="form.criticalResultConfirmed"/></el-form-item>
|
||||
<el-form-item label="主刀医生"><el-input v-model="form.surgeonName"/></el-form-item>
|
||||
<el-form-item label="麻醉医生"><el-input v-model="form.anesthesiologistName"/></el-form-item>
|
||||
<el-form-item label="护士"><el-input v-model="form.nurseName"/></el-form-item>
|
||||
<el-form-item label="核查备注"><el-input v-model="form.checkItems" type="textarea" :rows="3"/></el-form-item>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="650px">
|
||||
<el-form :model="formData" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12"><el-form-item label="患者"><el-input v-model="formData.patientName" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="手术名称"><el-input v-model="formData.surgeryName" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="核查阶段">
|
||||
<el-select v-model="formData.checkPhase"><el-option label="术前" value="PRE_OP" /><el-option label="术中" value="INTRA_OP" /><el-option label="术后" value="POST_OP" /></el-select>
|
||||
</el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="主刀医生"><el-input v-model="formData.surgeonName" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="麻醉医师"><el-input v-model="formData.anesthesiologistName" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="巡回护士"><el-input v-model="formData.circulatingNurseName" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="状态">
|
||||
<el-select v-model="formData.status"><el-option label="待核查" value="PENDING" /><el-option label="核查中" value="IN_PROGRESS" /><el-option label="已完成" value="COMPLETED" /></el-select>
|
||||
</el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="核查内容"><el-input v-model="formData.checkContent" type="textarea" :rows="3" /></el-form-item></el-col>
|
||||
<el-col :span="24"><el-form-item label="备注"><el-input v-model="formData.remark" type="textarea" :rows="2" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dlgVisible=false">取消</el-button>
|
||||
<el-button type="primary" @click="saveData">保存</el-button>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref,onMounted} from 'vue'
|
||||
import {ElMessage} from 'element-plus'
|
||||
import {getPage,add,update,del} from './api'
|
||||
const tableData=ref([]);const total=ref(0)
|
||||
const q=ref({pageNo:1,pageSize:20,patientName:'',checkPhase:''})
|
||||
const dlgVisible=ref(false);const isEdit=ref(false)
|
||||
const defaultForm=()=>({patientId:null,encounterId:null,patientName:'',surgeryName:'',checkPhase:'ANESTHESIA_BEFORE',checkTime:null,checkItems:'',patientIdConfirmed:false,surgerySiteConfirmed:false,procedureTypeConfirmed:false,allergyConfirmed:false,vitalSignsBaseline:false,criticalResultConfirmed:false,surgeonName:'',anesthesiologistName:'',nurseName:''})
|
||||
const form=ref(defaultForm())
|
||||
const loadData=async()=>{const r=await getPage(q.value);tableData.value=r.data?.records||[];total.value=r.data?.total||0}
|
||||
const openAdd=()=>{isEdit.value=false;form.value=defaultForm();dlgVisible.value=true}
|
||||
const openEdit=(row)=>{isEdit.value=true;form.value={...row};dlgVisible.value=true}
|
||||
const saveData=async()=>{if(isEdit.value){await update(form.value)}else{await add(form.value)}ElMessage.success('保存成功');dlgVisible.value=false;loadData()}
|
||||
const delItem=async(id)=>{await del(id);ElMessage.success('已删除');loadData()}
|
||||
onMounted(()=>loadData())
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getPage, addCheck, updateCheck, deleteCheck } from './api'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
const loading = ref(false); const dataList = ref([]); const total = ref(0); const showSearch = ref(true)
|
||||
const dialogVisible = ref(false); const dialogTitle = ref('新增')
|
||||
const queryParams = reactive({ patientName: '', checkPhase: '', pageNo: 1, pageSize: 20 })
|
||||
const formData = ref({})
|
||||
|
||||
const getList = async () => { loading.value = true; const res = await getPage(queryParams); dataList.value = res.data?.records || []; total.value = res.data?.total || 0; loading.value = false }
|
||||
const handleQuery = () => { queryParams.pageNo = 1; getList() }
|
||||
const resetQuery = () => { queryParams.patientName = ''; queryParams.checkPhase = ''; handleQuery() }
|
||||
const handleAdd = () => { formData.value = { status: 'PENDING' }; dialogTitle.value = '新增手术安全核查'; dialogVisible.value = true }
|
||||
const handleEdit = (row) => { formData.value = { ...row }; dialogTitle.value = '编辑手术安全核查'; dialogVisible.value = true }
|
||||
const submitForm = async () => {
|
||||
if (formData.value.id) { await updateCheck(formData.value) } else { await addCheck(formData.value) }
|
||||
ElMessage.success('操作成功'); dialogVisible.value = false; getList()
|
||||
}
|
||||
const handleDelete = async (row) => {
|
||||
await ElMessageBox.confirm('确认删除?', '提示', { type: 'warning' })
|
||||
await deleteCheck(row.id); ElMessage.success('删除成功'); getList()
|
||||
}
|
||||
onMounted(() => getList())
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user