Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
2026-06-22 13:37:29 +08:00
3 changed files with 128 additions and 170 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="dataSourceStorageLocal" created-in="IU-253.33514.17">
<component name="dataSourceStorageLocal" created-in="IU-253.32098.37">
<data-source name="postgresql@192.168.110.252" uuid="6f44e2a0-c865-4e9f-83bf-d35db0680dc5">
<database-info product="PostgreSQL" version="17.6" jdbc-version="4.2" driver-name="PostgreSQL JDBC Driver" driver-version="42.7.3" dbms="POSTGRES" exact-version="17.6" exact-driver-version="42.7">
<identifier-quote-string>&quot;</identifier-quote-string>

View File

@@ -0,0 +1,13 @@
-- Fix Bug #748: clinical_pathway 和 clinical_pathway_execution 缺少 HisBaseEntity 列
-- V43 和 V53 因版本号(43,53)低于已执行的迁移而被 Flyway 跳过,此处统一修复
-- clinical_pathway_variance (V58) 已包含完整列,无需处理
-- 1. clinical_pathway 表: 缺失 create_by / update_by / update_time
ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT '';
ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT '';
ALTER TABLE clinical_pathway ADD COLUMN IF NOT EXISTS update_time TIMESTAMP;
-- 2. clinical_pathway_execution 表: 缺失 create_by / update_by / update_time
ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS create_by VARCHAR(64) DEFAULT '';
ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_by VARCHAR(64) DEFAULT '';
ALTER TABLE clinical_pathway_execution ADD COLUMN IF NOT EXISTS update_time TIMESTAMP;

View File

@@ -1,152 +1,75 @@
<template>
<div class="app-container">
<el-row
:gutter="20"
class="mb8"
>
<el-col :span="6">
<el-card shadow="hover">
<el-statistic
title="路径总数"
:value="stats.totalPathways || 0"
/>
<el-row :gutter="20" class="mb8">
<el-col :xs="12" :sm="6">
<el-card shadow="hover" class="stat-card">
<el-statistic title="路径总数" :value="stats.totalPathways || 0" />
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover">
<el-statistic
title="入径数"
:value="stats.enteredCount || 0"
/>
<el-col :xs="12" :sm="6">
<el-card shadow="hover" class="stat-card">
<el-statistic title="入径数" :value="stats.enteredCount || 0" />
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover">
<el-statistic
title="完成数"
:value="stats.completedCount || 0"
/>
<el-col :xs="12" :sm="6">
<el-card shadow="hover" class="stat-card">
<el-statistic title="完成数" :value="stats.completedCount || 0" />
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover">
<el-statistic
title="变异数"
:value="stats.variedCount || 0"
/>
<el-col :xs="12" :sm="6">
<el-card shadow="hover" class="stat-card">
<el-statistic title="变异数" :value="stats.variedCount || 0" />
</el-card>
</el-col>
</el-row>
<el-card>
<template #header>
<div style="display:flex;justify-content:space-between;align-items:center">
<div class="card-header">
<span>临床路径管理</span>
<el-button
type="primary"
icon="Plus"
@click="handleAdd"
>
新增路径
</el-button>
<el-button type="primary" icon="Plus" @click="handleAdd">新增路径</el-button>
</div>
</template>
<el-form
:model="queryParams"
:inline="true"
class="mb8"
>
<el-form :model="queryParams" :inline="true" class="query-form">
<el-form-item label="疾病编码">
<el-input
v-model="queryParams.diseaseCode"
placeholder="疾病编码"
clearable
/>
<el-input v-model="queryParams.diseaseCode" placeholder="请输入疾病编码" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="疾病名称">
<el-input v-model="queryParams.diseaseName" placeholder="请输入疾病名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="handleQuery"
>
搜索
</el-button>
<el-button @click="queryParams.diseaseCode='';handleQuery()">
重置
</el-button>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="dataList"
>
<el-table-column
label="疾病编码"
prop="diseaseCode"
width="120"
/>
<el-table-column
label="疾病名称"
prop="diseaseName"
width="150"
/>
<el-table-column
label="路径名称"
prop="pathwayName"
width="200"
show-overflow-tooltip
/>
<el-table-column
label="标准住院日"
prop="standardLos"
width="100"
align="center"
/>
<el-table-column
label="版本"
prop="version"
width="70"
align="center"
/>
<el-table-column
label="状态"
prop="status"
width="90"
>
<template #default="s">
<el-tag :type="s.row.status==='ACTIVE'?'success':'info'">
{{ s.row.status === 'ACTIVE' ? '启用' : '停用' }}
<el-table v-loading="loading" :data="dataList" border stripe style="width: 100%">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="diseaseCode" label="疾病编码" width="120" show-overflow-tooltip />
<el-table-column prop="diseaseName" label="疾病名称" width="150" show-overflow-tooltip />
<el-table-column prop="pathwayName" label="路径名称" min-width="180" show-overflow-tooltip />
<el-table-column prop="standardLos" label="标准住院日" width="110" align="center" />
<el-table-column prop="version" label="版本" width="70" align="center" />
<el-table-column prop="status" label="状态" width="90" align="center">
<template #default="{ row }">
<el-tag :type="row.status === 'ACTIVE' ? 'success' : 'info'" size="small">
{{ row.status === 'ACTIVE' ? '启用' : '停用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column
label="操作"
width="200"
fixed="right"
>
<template #default="s">
<el-button
link
type="primary"
@click="handleEnter(s.row)"
>
入径
</el-button>
<el-button
link
type="success"
@click="handleComplete(s.row)"
>
完成
</el-button>
<el-button
link
type="warning"
@click="handleVary(s.row)"
>
变异
</el-button>
<el-table-column label="操作" width="220" align="center" fixed="right">
<template #default="{ row }">
<el-button link type="primary" icon="Upload" @click="handleEnter(row)">入径</el-button>
<el-button link type="success" icon="Check" @click="handleComplete(row)">完成</el-button>
<el-button link type="warning" icon="Warning" @click="handleVary(row)">变异</el-button>
</template>
</el-table-column>
<template #empty>
<el-empty description="暂无临床路径数据" :image-size="80" />
</template>
</el-table>
<pagination
v-show="total > 0"
v-model:page="queryParams.pageNo"
@@ -156,60 +79,39 @@
/>
</el-card>
<el-dialog
v-model="dialogVisible"
title="新增临床路径"
width="600px"
>
<el-form
:model="formData"
label-width="110px"
>
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑临床路径' : '新增临床路径'" width="600px" destroy-on-close :close-on-click-modal="false">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="110px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="疾病编码">
<el-input v-model="formData.diseaseCode" />
<el-form-item label="疾病编码" prop="diseaseCode">
<el-input v-model="formData.diseaseCode" placeholder="请输入疾病编码" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="疾病名称">
<el-input v-model="formData.diseaseName" />
<el-form-item label="疾病名称" prop="diseaseName">
<el-input v-model="formData.diseaseName" placeholder="请输入疾病名称" maxlength="100" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="路径名称">
<el-input v-model="formData.pathwayName" />
<el-form-item label="路径名称" prop="pathwayName">
<el-input v-model="formData.pathwayName" placeholder="请输入路径名称" maxlength="200" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标准住院日">
<el-input-number
v-model="formData.standardLos"
:min="1"
/>
<el-form-item label="标准住院日" prop="standardLos">
<el-input-number v-model="formData.standardLos" :min="1" :max="365" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="路径内容">
<el-input
v-model="formData.pathwayContent"
type="textarea"
:rows="4"
/>
<el-input v-model="formData.pathwayContent" type="textarea" :rows="4" placeholder="请输入路径内容" maxlength="2000" show-word-limit />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">
取消
</el-button>
<el-button
type="primary"
@click="submitForm"
>
确定
</el-button>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="submitForm">确定</el-button>
</template>
</el-dialog>
</div>
@@ -220,27 +122,70 @@ import { ref, reactive, onMounted } from 'vue'
import { getWorkflowPage, addWorkflow, enterPathway, completePathway, varyPathway, getStats } from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'
const loading = ref(false); const dataList = ref([]); const total = ref(0); const stats = ref({})
const loading = ref(false)
const submitLoading = ref(false)
const dataList = ref([])
const total = ref(0)
const stats = ref({})
const dialogVisible = ref(false)
const queryParams = reactive({ diseaseCode: '', pageNo: 1, pageSize: 20 })
const formData = ref({})
const isEdit = ref(false)
const formRef = ref(null)
const getList = async () => { loading.value = true; const res = await getWorkflowPage(queryParams); dataList.value = res.data?.records || []; total.value = res.data?.total || 0; loading.value = false }
const loadStats = async () => { const res = await getStats(); stats.value = res.data || {} }
const queryParams = reactive({ diseaseCode: '', diseaseName: '', pageNo: 1, pageSize: 20 })
const formData = reactive({ diseaseCode: '', diseaseName: '', pathwayName: '', standardLos: 7, pathwayContent: '' })
const formRules = {
diseaseCode: [{ required: true, message: '请输入疾病编码', trigger: 'blur' }],
diseaseName: [{ required: true, message: '请输入疾病名称', trigger: 'blur' }],
pathwayName: [{ required: true, message: '请输入路径名称', trigger: 'blur' }],
standardLos: [{ required: true, message: '请输入标准住院日', trigger: 'blur' }]
}
const getList = async () => {
loading.value = true
try {
const params = { diseaseCode: queryParams.diseaseCode || undefined, diseaseName: queryParams.diseaseName || undefined, pageNo: queryParams.pageNo, pageSize: queryParams.pageSize }
const res = await getWorkflowPage(params)
dataList.value = res.data?.records || []
total.value = res.data?.total || 0
} catch {} finally { loading.value = false }
}
const loadStats = async () => { try { const res = await getStats(); stats.value = res.data || {} } catch {} }
const handleQuery = () => { queryParams.pageNo = 1; getList() }
const handleAdd = () => { formData.value = {}; dialogVisible.value = true }
const submitForm = async () => { await addWorkflow(formData.value); ElMessage.success('创建成功'); dialogVisible.value = false; getList(); loadStats() }
const resetQuery = () => { queryParams.diseaseCode = ''; queryParams.diseaseName = ''; handleQuery() }
const handleAdd = () => { isEdit.value = false; Object.assign(formData, { diseaseCode: '', diseaseName: '', pathwayName: '', standardLos: 7, pathwayContent: '' }); dialogVisible.value = true }
const submitForm = async () => {
try { await formRef.value?.validate() } catch { return }
submitLoading.value = true
try {
await addWorkflow({ ...formData })
ElMessage.success(isEdit.value ? '修改成功' : '创建成功')
dialogVisible.value = false; getList(); loadStats()
} catch {} finally { submitLoading.value = false }
}
const handleEnter = async (row) => {
await ElMessageBox.confirm(`确认将患者入径「${row.pathwayName}」?`, '入径确认', { type: 'info' })
await enterPathway({ pathwayId: row.id, diseaseCode: row.diseaseCode, diseaseName: row.diseaseName }); ElMessage.success('入径成功'); loadStats()
try {
await ElMessageBox.confirm(`确认将患者入径「${row.pathwayName}」?`, '入径确认', { type: 'info' })
await enterPathway({ pathwayId: row.id, diseaseCode: row.diseaseCode, diseaseName: row.diseaseName })
ElMessage.success('入径成功'); loadStats()
} catch {}
}
const handleComplete = async (row) => {
await ElMessageBox.confirm('确认完成此路径?', '完成确认', { type: 'success' })
await completePathway(row.id); ElMessage.success('已完成'); getList(); loadStats()
try {
await ElMessageBox.confirm('确认完成此路径?', '完成确认', { type: 'success' })
await completePathway(row.id); ElMessage.success('已完成'); getList(); loadStats()
} catch {}
}
const handleVary = async (row) => {
await ElMessageBox.prompt('请输入变异原因', '变异登记', { type: 'warning' })
.then(async ({ value }) => { await varyPathway(row.id, value || '未填写原因'); ElMessage.success('变异登记'); getList(); loadStats() })
try {
const { value } = await ElMessageBox.prompt('请输入变异原因', '变异登记', { type: 'warning' })
await varyPathway(row.id, value || '未填写原因'); ElMessage.success('变异已登记'); getList(); loadStats()
} catch {}
}
onMounted(() => { getList(); loadStats() })
</script>
<style scoped>
.card-header { display: flex; justify-content: space-between; align-items: center; }
.query-form { margin-bottom: 0; }
.stat-card { text-align: center; }
</style>