269 lines
8.8 KiB
Vue
269 lines
8.8 KiB
Vue
<template>
|
||
<div class="others-box">
|
||
<el-row :gutter="5">
|
||
<el-col :span="8">
|
||
<el-table ref="tableRef" :data="tableData" style="width: 100%" @row-click="handleRowClick" highlight-current-row
|
||
border height="82vh" show-overflow-tooltip>
|
||
<el-table-column prop="yqmc" label="仪器名称" align="center" width="120" />
|
||
<el-table-column prop="gjmc" label="医疗机构" align="center" width="150" />
|
||
<el-table-column prop="jyrqName" label="检验日期" align="center" width="100" />
|
||
</el-table>
|
||
</el-col>
|
||
<el-col :span="16">
|
||
<CustomTable ref="tableDetailRef" :columns="columns" :data="tableDataDetail" :config="config"
|
||
@row-click="handleRowClick" :enable-column-drag="true" @column-drag-end="handleColumnDragEnd">
|
||
<template #firstCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'first')"></div>
|
||
</template>
|
||
<template #oneCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'one')"></div>
|
||
</template>
|
||
<template #twoCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'two')"></div>
|
||
</template>
|
||
<template #threeCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'three')"></div>
|
||
</template>
|
||
<template #fourCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'four')"></div>
|
||
</template>
|
||
<template #fiveCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'five')"></div>
|
||
</template>
|
||
<template #sixCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'six')"></div>
|
||
</template>
|
||
<template #sevenCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'seven')"></div>
|
||
</template>
|
||
<template #eightCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'eight')"></div>
|
||
</template>
|
||
<template #nineCsjg="{ column }">
|
||
<div v-html="formatHeader(column, 'nine')"></div>
|
||
</template>
|
||
</CustomTable>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import type { PropType } from 'vue';
|
||
import { ref, watch, computed, reactive, toRefs, onMounted, nextTick } from 'vue';
|
||
import { otherinstr, otherInstrDetail } from '@/api/liswork/work/LisWork';
|
||
import CustomTable from '@/components/elTable/index.vue'
|
||
import dayjs from 'dayjs';
|
||
const baseUrl = import.meta.env.VITE_APP_BASE_API
|
||
|
||
const props = defineProps({
|
||
// 主键
|
||
queryParams: {
|
||
type: Object,
|
||
default: {}
|
||
},
|
||
dictData: {
|
||
type: Object,
|
||
default: () => { }
|
||
},
|
||
instrOptions: {
|
||
type: Array as PropType<Array<{ yq: string; yqmc: string }>>,
|
||
default: () => []
|
||
}
|
||
})
|
||
|
||
// 解构 props
|
||
const { queryParams, dictData, instrOptions } = toRefs(props);
|
||
const tableData = ref([]);
|
||
const tableDataDetail: any = ref([]);
|
||
const tableRef = ref();
|
||
const tableDetailRef = ref();
|
||
|
||
const columns = ref([
|
||
{ label: '项目', prop: 'xmmc', width: 140, align: 'center', visible: true, },
|
||
{ label: '本次', prop: 'firstCsjg', width: 100, align: 'center', visible: true, headerSlot: 'firstCsjg' },
|
||
{ label: '上一次', prop: 'oneCsjg', width: 150, align: 'center', visible: true, headerSlot: 'oneCsjg' },
|
||
{ label: '上二次', prop: 'twoCsjg', width: 150, align: 'center', visible: true, headerSlot: 'twoCsjg' },
|
||
{ label: '上三次', prop: 'threeCsjg', width: 150, align: 'center', visible: true, headerSlot: 'threeCsjg' },
|
||
{ label: '上四次', prop: 'fourCsjg', width: 150, align: 'center', visible: true, headerSlot: 'fourCsjg' },
|
||
{ label: '上五次', prop: 'fiveCsjg', width: 150, align: 'center', visible: true, headerSlot: 'fiveCsjg' },
|
||
{ label: '上六次', prop: 'sixCsjg', width: 150, align: 'center', visible: true, headerSlot: 'sixCsjg' },
|
||
{ label: '上七次', prop: 'sevenCsjg', width: 150, align: 'center', visible: true, headerSlot: 'sevenCsjg' },
|
||
{ label: '上八次', prop: 'eightCsjg', width: 150, align: 'center', visible: true, headerSlot: 'eightCsjg' },
|
||
{ label: '上九次', prop: 'nineCsjg', width: 150, align: 'center', visible: true, headerSlot: 'nineCsjg' },
|
||
])
|
||
|
||
// 定义样式
|
||
const styleMap: any = {
|
||
H: { background: '#ffc0c0 !important', color: '#606266' },
|
||
L: { background: '#8080ff !important', color: '#fff' },
|
||
P: { background: '#ffc0c0 !important', color: '#606266' },
|
||
Q: { background: '#ffff80 !important', color: '#FFF' }
|
||
};
|
||
|
||
// 定义列标签与标志位字段的映射关系
|
||
const labelFlagMap: any = {
|
||
'本次': 'firstResultFlag',
|
||
'上一次': 'oneResultFlag',
|
||
'上二次': 'twoResultFlag',
|
||
'上三次': 'threeResultFlag',
|
||
'上四次': 'fourResultFlag',
|
||
'上五次': 'fiveResultFlag',
|
||
'上六次': 'sixResultFlag',
|
||
'上七次': 'sevenResultFlag',
|
||
'上八次': 'eightResultFlag',
|
||
'上九次': 'nineResultFlag',
|
||
};
|
||
|
||
const cellStyle = ({ column, row }: any) => {
|
||
const flagField = labelFlagMap[column.label];
|
||
if (!flagField) return {}; // 非目标列直接返回默认样式
|
||
|
||
// 获取当前行的标志位值
|
||
const flag = row[flagField];
|
||
// 返回对应的样式(默认返回空对象)
|
||
return styleMap[flag] || {};
|
||
};
|
||
|
||
const config = {
|
||
border: true,
|
||
// maxHeight: '350px',
|
||
height: '82vh',
|
||
highlightCurrentRow: true,
|
||
cellStyle: cellStyle
|
||
}
|
||
|
||
const handleColumnDragEnd = (data: any) => {
|
||
columns.value = data.columns
|
||
}
|
||
|
||
const formatHeader = (column: any, prefix: string) => {
|
||
const index = tableDataDetail.value.findIndex((item: any) => item[`${prefix}Csjg`] !== undefined);
|
||
if (index !== -1) {
|
||
const dateKey = `${prefix}Date`;
|
||
const ybhKey = `${prefix}ybh`;
|
||
const yqdlKey = `${prefix}yqdl`;
|
||
const yqKey = `${prefix}yq`;
|
||
const brxbKey = `${prefix}brxb`;
|
||
const nlKey = `${prefix}nl`;
|
||
const item = tableDataDetail.value[index];
|
||
return ` ${item[dateKey]} <br /> (${item[ybhKey]}) <br /> ${item[yqdlKey]} <br />${item[brxbKey]},${item[nlKey]}`;
|
||
}
|
||
return column.label;
|
||
};
|
||
// 获取其他结果信息
|
||
const getOthersInfo = () => {
|
||
otherinstr(queryParams.value).then((res: any) => {
|
||
tableData.value = res.data.map((item: any) => {
|
||
return {
|
||
...item,
|
||
jyrqName: dayjs(item.jyrq).format('YYYY/MM/DD'),
|
||
}
|
||
})
|
||
if (res.data.length > 0) {
|
||
nextTick(() => {
|
||
tableRef.value.setCurrentRow(tableData.value[0])
|
||
handleRowClick(tableData.value[0])
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
watch(() => props.queryParams, (newValue) => {
|
||
getOthersInfo()
|
||
}, { immediate: true })
|
||
|
||
// 获取明细
|
||
const handleRowClick = (row: any) => {
|
||
const data = {
|
||
brdh: row.brdh,
|
||
yq: row.yq,
|
||
jyrq: row.jyrq,
|
||
ybh: row.ybh
|
||
}
|
||
otherInstrDetail(data).then((res: any) => {
|
||
const periods = ['first', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
|
||
const dataMaps = new Map();
|
||
|
||
periods.forEach(period => {
|
||
const data = res.data[period] || [];
|
||
const map = new Map();
|
||
data.forEach((item: any) => {
|
||
// 使用xmdh作为唯一标识
|
||
map.set(item.xmdh, {
|
||
csjg: item.csjg,
|
||
jyrq: dayjs(item.jyrq).format('YY/MM/DD'),
|
||
yqdl: item.yqdl,
|
||
yq: item.yq,
|
||
ybh: item.ybh,
|
||
yljg: item.yljg,
|
||
result_flag: item.result_flag,
|
||
xmmc: item.xmmc,
|
||
cksx: item.cksx,
|
||
ckxx: item.ckxx,
|
||
brxb: item.brxb,
|
||
nl: item.nl
|
||
});
|
||
});
|
||
dataMaps.set(period, map);
|
||
});
|
||
|
||
|
||
const allXmdhSet = new Set<string>();
|
||
periods.forEach(period => {
|
||
const data = res.data[period] || [];
|
||
data.forEach((item: any) => {
|
||
allXmdhSet.add(item.xmdh);
|
||
});
|
||
});
|
||
|
||
tableDataDetail.value = Array.from(allXmdhSet).map((xmdh) => {
|
||
const row: any = {};
|
||
|
||
periods.forEach(period => {
|
||
const item = dataMaps.get(period).get(xmdh);
|
||
if (item) {
|
||
row[`${period}Csjg`] = item.csjg;
|
||
row[`${period}Date`] = item.jyrq;
|
||
row[`${period}yqdl`] = item.yqdl;
|
||
row[`${period}yq`] = item.yq;
|
||
row[`${period}ybh`] = item.ybh;
|
||
row[`${period}yljg`] = item.yljg;
|
||
row[`${period}ResultFlag`] = item.result_flag;
|
||
row[`${period}brxb`] = item.brxb;
|
||
row[`${period}nl`] = item.nl;
|
||
|
||
if (!row.xmmc) {
|
||
row.xmmc = item.xmmc;
|
||
row.cksx = item.cksx;
|
||
row.ckxx = item.ckxx;
|
||
}
|
||
}
|
||
});
|
||
|
||
return row;
|
||
});
|
||
})
|
||
}
|
||
|
||
|
||
const formatDict = (v: string, dictType: string) => {
|
||
return dictData.value[dictType]?.find((item: any) => item.value == v)?.label || v;
|
||
}
|
||
|
||
const formatyq = (v: string) => {
|
||
return instrOptions.value.find((item: any) => item.yq == v.trim())?.yqmc || v;
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.others-box {
|
||
height: 82vh;
|
||
overflow-y: auto;
|
||
overflow-x: hidden;
|
||
|
||
:deep(.el-table__cell) {
|
||
padding: 0 !important;
|
||
}
|
||
}
|
||
</style> |