Files
his/openhis-ui-vue3/src/components/PendingPatientList/index.vue
chenqi abc0674531 ```
docs(release-notes): 添加住院护士站划价功能说明和发版记录

- 新增住院护士站划价服务流程说明文档,详细描述了从参数预处理到结果响应的五大阶段流程
- 包含耗材类医嘱和诊疗活动类医嘱的差异化处理逻辑
- 添加完整的发版内容记录,涵盖新增菜单功能和各模块优化点
- 记录了住院相关功能的新增和门诊业务流程的修复
```
2025-12-25 14:13:14 +08:00

319 lines
7.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="pending-patient-list">
<div class="patient-cards" v-loading="loading">
<template v-if="list && list.length > 0">
<el-scrollbar class="patient-cards-scrollbar">
<div
class="patient-card"
v-for="(item, index) in list"
:key="item[idKey] ?? index"
:class="{ actived: !!item.active || activeId === item[idKey] }"
draggable="true"
@click="emit('item-click', item, index)"
@dblclick="emit('item-dblclick', item)"
@dragstart="(e) => emit('dragstart', e, item)"
@dragend="(e) => emit('dragend', e)"
>
<div class="patient-card-header">
<div class="header-top">
<div class="bed-container">
<div class="bed">
<el-text truncated tclass="bed-font" width="auto">
{{ item.bedName || '-' }}
</el-text>
</div>
</div>
<div class="header-tags">
<el-tag v-if="item.contractName" size="small" class="payer-tag" effect="light">
{{ item.contractName }}
</el-tag>
<el-tag
v-if="item.encounterStatus_enumText"
size="small"
class="status-tag"
effect="light"
:class="getStatusClass(item)"
>
{{ item.encounterStatus_enumText }}
</el-tag>
</div>
</div>
<div class="header-bottom">
<span class="bus-no">住院号{{ item.busNo || '-' }}</span>
</div>
<div class="meta">
<div class="meta-row">
<span class="meta-label">入院时间</span>
<span class="meta-value">{{
item.startTime ? formatDate(item.startTime) : '-'
}}</span>
</div>
<div class="meta-row">
<span class="meta-label">入科时间</span>
<span class="meta-value">{{
item.admissionTime ? formatDate(item.admissionTime) : '-'
}}</span>
</div>
</div>
</div>
<div class="doctor-parent-line" />
<div class="patient-card-body">
<div class="personal-info-container">
<div class="name-container">
<div class="name">
<el-text :text="item.patientName" tclass="name" width="auto">
{{ item.patientName || '-' }}
</el-text>
</div>
<div class="age">
<el-tag
size="small"
class="age-tag"
effect="plain"
:class="{
'age-tag-female': item.genderEnum_enumText === '女性',
'age-tag-male': item.genderEnum_enumText === '男性',
}"
>
{{ item.genderEnum_enumText || '-' }}
<span v-if="item.age"> · {{ item.age }}</span>
<span v-if="item.priorityEnum_enumText">
· {{ item.priorityEnum_enumText }}</span
>
</el-tag>
</div>
</div>
</div>
<div class="meta"></div>
</div>
</div>
</el-scrollbar>
</template>
<el-empty v-else description="暂无数据" />
</div>
</div>
</template>
<script setup lang="ts">
import { formatDate } from '@/utils/index';
withDefaults(
defineProps<{
list: any[];
activeId?: string | number;
idKey?: string;
loading?: boolean;
}>(),
{
list: () => [],
activeId: '',
idKey: 'id',
loading: false,
}
);
const emit = defineEmits<{
(e: 'item-click', item: any, index: number): void;
(e: 'item-dblclick', item: any): void;
(e: 'dragstart', event: DragEvent, item: any): void;
(e: 'dragend', event: DragEvent): void;
}>();
const getStatusClass = (item: any) => {
if (item?.encounterStatus == 2) return 'status-tag--blue';
if (item?.encounterStatus == 5) return 'status-tag--green';
return '';
};
</script>
<style scoped lang="scss" name="PendingPatientList">
.pending-patient-list {
height: 100%;
display: flex;
flex-direction: column;
min-height: 0;
min-width: 240px;
width: 240px;
}
.patient-cards {
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
:deep(.patient-cards-scrollbar) {
width: 100%;
height: 100%;
.el-scrollbar__bar {
width: 0;
}
}
}
.patient-card {
width: 100%;
overflow: hidden;
background-color: #fff;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.04);
box-shadow: 0 2px 6px 0 rgba(15, 35, 52, 0.12);
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
&:hover {
box-shadow: 0 4px 12px rgba(15, 35, 52, 0.18);
transform: translateY(-1px);
}
&.actived {
background-color: rgba(7, 155, 140, 0.06);
border-color: var(--el-color-primary);
box-shadow: 0 0 0 1px rgba(7, 155, 140, 0.3), 0 4px 14px rgba(7, 155, 140, 0.25);
}
}
.patient-card-header {
display: flex;
flex-direction: column;
padding: 10px 12px 4px;
.header-top {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.bed-container {
display: flex;
flex: 1;
align-items: center;
min-width: 0;
.bed {
flex-grow: 0;
flex-shrink: 1;
min-width: 0;
:deep(.bed-font) {
color: #1f2933;
font-weight: 600;
font-size: 16px;
}
}
}
.payer-tag {
max-width: 120px;
font-size: 12px;
border-radius: 999px;
}
.header-tags {
flex-shrink: 0;
display: flex;
align-items: flex-end;
justify-content: flex-end;
gap: 6px;
}
}
.header-bottom {
margin-top: 4px;
width: 100%;
display: flex;
justify-content: flex-start;
color: #6b7280;
font-size: 12px;
.bus-no {
white-space: nowrap;
}
}
}
.doctor-parent-line {
margin: 6px 12px 0;
border-bottom: 1px dashed #e5e7eb;
}
.patient-card-body {
padding: 8px 12px 10px;
}
.personal-info-container {
display: block;
.name-container {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
width: 100%;
.name {
color: #111827;
font-weight: 600;
font-size: 14px;
}
.age {
flex-shrink: 0;
}
}
}
.age-tag {
border-radius: 999px;
padding: 0 8px;
}
.age-tag-female {
border-color: rgb(255, 55, 158);
color: rgb(255, 126, 184);
}
.age-tag-male {
border-color: #91d5ff;
color: #1677ff;
}
.status-tag {
border-radius: 999px;
padding: 0 8px;
flex-shrink: 0;
font-weight: 600;
}
.status-tag--blue {
border-color: #91d5ff;
background-color: #1677ff;
color: white;
}
.status-tag--green {
border-color: #b7eb8f;
background-color: #389e0d;
color: white;
}
.meta {
margin-top: 6px;
color: #6b7280;
font-size: 12px;
line-height: 18px;
}
.meta-row {
display: flex;
}
.meta-label {
flex-shrink: 0;
}
</style>