版本更新

This commit is contained in:
Zhang.WH
2025-09-03 15:54:41 +08:00
parent 0b93d16b64
commit 8f82322d10
3290 changed files with 154339 additions and 23829 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
<template>
<div @keyup="handleKeyDown" tabindex="0" ref="tableWrapper">
<el-table
ref="adviceBaseRef"
height="400"
:data="adviceBaseList"
highlight-current-row
@current-change="handleCurrentChange"
row-key="patientId"
@cell-click="clickRow"
>
<el-table-column label="名称" align="center" prop="adviceName" />
<el-table-column label="类型" align="center" prop="activityType_enumText" />
<el-table-column label="包装单位" align="center" prop="unitCode_dictText" />
<el-table-column label="最小单位" align="center" prop="minUnitCode_dictText" />
<!-- <el-table-column label="规格" align="center" prop="volume" /> -->
<!-- <el-table-column label="用法" align="center" prop="methodCode_dictText" /> -->
<el-table-column label="库存数量" align="center">
<template #default="scope">{{ handleQuantity(scope.row) }}</template>
</el-table-column>
<el-table-column label="频次" align="center" prop="rateCode_dictText" />
<!-- <el-table-column label="单次剂量" align="center" prop="dose" /> -->
<!-- <el-table-column label="剂量单位" align="center" prop="doseUnitCode_dictText" /> -->
<!-- <el-table-column label="注射药品" align="center" prop="injectFlag_enumText" /> -->
<!-- <el-table-column label="皮试" align="center" prop="skinTestFlag_enumText" /> -->
</el-table>
</div>
</template>
<script setup>
import { nextTick } from 'vue';
import { getTcmMedicine } from '@/views/doctorstation/components/api';
import { throttle } from 'lodash-es';
const props = defineProps({
adviceQueryParams: {
type: Object,
default: '',
},
patientInfo: {
type: Object,
required: true,
},
});
const emit = defineEmits(['selectAdviceBase']);
const total = ref(0);
const adviceBaseRef = ref();
const tableWrapper = ref();
const currentIndex = ref(0); // 当前选中行索引
const currentSelectRow = ref({});
const queryParams = ref({
pageSize: 100,
pageNum: 1,
});
const adviceBaseList = ref([]);
// 节流函数
const throttledGetList = throttle(
() => {
getList();
},
300,
{ leading: true, trailing: true }
);
watch(
() => props.adviceQueryParams,
(newValue) => {
queryParams.value.searchKey = newValue.searchKey;
queryParams.value.adviceType = newValue.adviceType;
throttledGetList();
},
{ deep: true }
);
getList();
function getList() {
queryParams.value.organizationId = props.patientInfo.orgId;
getTcmMedicine(queryParams.value).then((res) => {
adviceBaseList.value = res.data.records;
total.value = res.data.total;
nextTick(() => {
currentIndex.value = 0;
if (adviceBaseList.value.length > 0) {
adviceBaseRef.value.setCurrentRow(adviceBaseList.value[0]);
}
});
});
}
// 处理键盘事件
const handleKeyDown = (event) => {
const key = event.key;
const data = adviceBaseList.value;
switch (key) {
case 'ArrowUp': // 上箭头
event.preventDefault(); // 阻止默认滚动行为
if (currentIndex.value > 0) {
currentIndex.value--;
setCurrentRow(data[currentIndex.value]);
}
break;
case 'ArrowDown': // 下箭头`
event.preventDefault();
if (currentIndex.value < data.length - 1) {
currentIndex.value++;
setCurrentRow(data[currentIndex.value]);
}
break;
case 'Enter': // 回车键
// const currentRow = adviceBaseRef.value.getSelectionRows();
event.preventDefault();
if (currentSelectRow.value) {
// 这里可以触发自定义逻辑,如弹窗、跳转等
emit('selectAdviceBase', currentSelectRow.value);
}
break;
}
};
function handleQuantity(row) {
if (row.inventoryList) {
const totalQuantity = row.inventoryList.reduce((sum, item) => sum + (item.quantity || 0), 0);
return totalQuantity.toString() + row.minUnitCode_dictText;
}
return 0;
}
// 设置选中行(带滚动)
const setCurrentRow = (row) => {
adviceBaseRef.value.setCurrentRow(row);
// 滚动到选中行
const tableBody = adviceBaseRef.value.$el.querySelector('.el-table__body-wrapper');
const currentRowEl = adviceBaseRef.value.$el.querySelector('.current-row');
if (tableBody && currentRowEl) {
currentRowEl.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
};
// 当前行变化时更新索引
const handleCurrentChange = (currentRow) => {
currentIndex.value = adviceBaseList.value.findIndex((item) => item === currentRow);
currentSelectRow.value = currentRow;
};
function clickRow(row) {
emit('selectAdviceBase', row);
}
defineExpose({
handleKeyDown,
});
</script>
<style scoped>
.popover-table-wrapper:focus {
outline: 2px solid #409eff; /* 聚焦时的高亮效果 */
}
</style>

View File

@@ -0,0 +1,383 @@
<template>
<el-dialog
title="中医诊断"
v-model="openDiagnosis"
width="500px"
append-to-body
destroy-on-close
@close="close"
@open="open"
>
<div class="diagnosis-container">
<div class="select-group">
<span class="select-label">中医诊断</span>
<el-select
v-model="condition"
placeholder="请选择中医诊断"
filterable
clearable
style="width: 300px"
>
<el-option
v-for="item in conditionOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="select-group">
<span class="select-label">中医证候</span>
<el-select
v-model="syndrome"
placeholder="请选择中医证候"
filterable
clearable
style="width: 300px"
>
<el-option
v-for="item in syndromeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submit"> </el-button>
<el-button @click="close"> </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref } from 'vue';
import { getTcmCondition, getTcmSyndrome, saveTcmDiagnosis } from '@/views/doctorstation/components/api';
const condition = ref('');
const syndrome = ref('');
const conditionOptions = ref([]);
const syndromeOptions = ref([]);
const diagnosisList = ref([]);
const openDiagnosis = ref(false);
const emit = defineEmits(['flush']);
const { proxy } = getCurrentInstance();
const props = defineProps({
patientInfo: {
type: Object,
required: true,
},
});
function open() {}
function submit() {
// 提交逻辑
if (!condition.value || !syndrome.value) {
proxy.$modal.msgWarning('请选择诊断和证候');
return; // 确保选择了诊断和证候
}
// 构建诊断对象
const diagnosis = {
id: Date.now(), // 使用时间戳作为唯一ID
condition: conditionOptions.value.find((item) => item.value === condition.value)?.label || '',
conditionCode: condition.value,
syndrome: syndromeOptions.value.find((item) => item.value === syndrome.value)?.label || '',
syndromeCode: syndrome.value,
};
const data = localStorage.getItem(`tcmDiagnosisList_${props.patientInfo.encounterId}`);
diagnosisList.value = JSON.parse(data);
// 添加到列表
diagnosisList.value.push(diagnosis);
localStorage.removeItem(`tcmDiagnosisList_${props.patientInfo.encounterId}`);
// 保存到本地缓存
localStorage.setItem(
`tcmDiagnosisList_${props.patientInfo.encounterId}`,
JSON.stringify(diagnosisList.value)
);
console.log('当前诊断列表:', diagnosisList.value);
emit('flush')
close();
}
function openDialog() {
openDiagnosis.value = true;
// 获取中医诊断选项
getTcmCondition().then((res) => {
conditionOptions.value = res.data.records.map((item) => ({
value: item.ybNo,
label: item.name,
}));
});
// 获取中医证候选项
getTcmSyndrome().then((res) => {
syndromeOptions.value = res.data.records.map((item) => ({
value: item.ybNo,
label: item.name,
}));
});
}
function close() {
// 关闭逻辑
condition.value = '';
syndrome.value = '';
openDiagnosis.value = false;
}
defineExpose({ openDialog });
</script>
<style scoped>
.diagnosis-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
padding: 20px 0;
}
.select-group {
display: flex;
align-items: center;
width: 100%;
justify-content: center;
}
.select-label {
width: 100px;
text-align: right;
margin-right: 10px;
font-size: 14px;
}
:deep(.pagination-container .el-pagination) {
right: 20px !important;
}
.app-container {
max-width: 1400px;
margin: 20px auto;
padding: 20px;
background: white;
border-radius: 12px;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.08);
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 15px;
border-bottom: 1px solid var(--el-border-color);
margin-bottom: 20px;
}
.header h1 {
color: var(--el-color-primary);
font-size: 24px;
font-weight: 600;
}
.patient-info {
background: var(--el-color-primary-light-9);
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
.patient-info .info-row {
display: flex;
margin-bottom: 8px;
}
.patient-info .info-label {
width: 100px;
color: var(--el-text-color-secondary);
font-weight: 500;
}
.main-content {
display: grid;
grid-template-columns: 1fr 1fr 1.2fr;
gap: 20px;
margin-bottom: 25px;
}
.disease-section, .syndrome-section, .diagnosis-section {
border: 1px solid var(--el-border-color);
border-radius: 8px;
padding: 20px;
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.section-title {
font-size: 18px;
font-weight: 600;
color: var(--el-color-primary);
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid var(--el-border-color);
}
.disease-list {
max-height: 400px;
overflow-y: auto;
}
.disease-item {
padding: 12px 15px;
border-bottom: 1px solid var(--el-border-color-lighter);
cursor: pointer;
transition: all 0.3s;
border-radius: 4px;
}
.disease-item:hover {
background-color: var(--el-color-primary-light-9);
}
.disease-item.active {
background-color: var(--el-color-primary-light-8);
border-left: 3px solid var(--el-color-primary);
}
.disease-name {
font-weight: 500;
margin-bottom: 5px;
}
.disease-code {
font-size: 12px;
color: var(--el-text-color-secondary);
}
.search-box {
margin-bottom: 15px;
}
.disease-categories {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 15px;
}
.category-tag {
cursor: pointer;
padding: 5px 12px;
border-radius: 15px;
background: var(--el-fill-color-light);
font-size: 13px;
transition: all 0.3s;
}
.category-tag.active {
background: var(--el-color-primary);
color: white;
}
.relation-container {
text-align: center;
padding: 30px 0;
border: 2px dashed var(--el-border-color);
border-radius: 8px;
margin: 20px 0;
background: var(--el-fill-color-lighter);
}
.relation-icon {
margin-bottom: 15px;
color: var(--el-color-primary);
}
.relation-text {
font-size: 18px;
font-weight: 500;
color: var(--el-text-color-primary);
}
.syndrome-details {
padding: 15px;
background: var(--el-color-primary-light-9);
border-radius: 8px;
border: 1px solid var(--el-color-primary-light-5);
}
.detail-item {
margin-bottom: 12px;
}
.detail-label {
font-weight: 500;
color: var(--el-text-color-secondary);
margin-bottom: 3px;
}
.actions {
display: flex;
justify-content: flex-end;
gap: 15px;
padding-top: 20px;
border-top: 1px solid var(--el-border-color);
}
.empty-state {
text-align: center;
padding: 40px 0;
color: var(--el-text-color-secondary);
}
.diagnosis-history {
margin-top: 20px;
border-top: 1px solid var(--el-border-color);
padding-top: 20px;
}
.history-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 12px;
color: var(--el-text-color-primary);
}
.history-item {
padding: 12px;
border-left: 3px solid var(--el-border-color);
margin-bottom: 10px;
background: var(--el-fill-color-lighter);
border-radius: 0 4px 4px 0;
}
.history-date {
font-size: 12px;
color: var(--el-text-color-secondary);
margin-bottom: 5px;
}
.history-diagnosis {
font-size: 14px;
margin-bottom: 5px;
}
.history-note {
font-size: 13px;
color: var(--el-text-color-secondary);
padding-top: 5px;
border-top: 1px dashed var(--el-border-color);
margin-top: 5px;
}
.empty-list {
padding: 20px 0;
text-align: center;
}
</style>