手术信息

This commit is contained in:
gaofy 2023-12-21 11:58:50 +08:00
parent 0747c8a344
commit b7d1036664
5 changed files with 383 additions and 6 deletions

View File

@ -15,4 +15,60 @@ export const getDeptData = () => {
depts.push({ label: '神经外科', value: '神经外科' })
depts.push({ label: '心脏内科', value: '心脏内科' })
return depts
}
export const getPatients = () => {
const patients = []
while (patients.length < 10000) {
patients.push({ name: '张' + patients.length, code: 'BH' + patients.length })
}
return patients
}
export const getNarcotismWay = () => {
const narcotismWay = []
while (narcotismWay.length < 10) {
const str: string = '麻醉方式' + (narcotismWay.length + 1)
narcotismWay.push({label: str, value: str})
}
return narcotismWay
}
export const getFormTypes = () => {
const types = [
{name: '生命体征表单'},
{name: 'AI给药记录'},
{name: '医生给药记录'},
{name: '给药命令反馈'},
{name: '输药泵定时间反馈'},
{name: '术后信息表单'},
{name: '1生命体征表单'},
{name: '1AI给药记录'},
{name: '1医生给药记录'},
{name: '1给药命令反馈'},
{name: '1输药泵定时间反馈'},
{name: '1术后信息表单'},
{name: '2生命体征表单'},
{name: '2AI给药记录'},
{name: '2医生给药记录'},
{name: '2给药命令反馈'},
{name: '2输药泵定时间反馈'},
{name: '2术后信息表单'},
]
return types
}
export const getDataAlarmState = (value: number, key: string) => {
const alarms: any = {
BIS: { min: 40, max: 60 },
HR: { min: 50, max: 80 },
SBP: { min: 90, max: 120 },
DBP: { min: 60, max: 90 },
ST: { min: -0.2, max: 0.2 },
EtCO2: { min: 30, max: 45 }
}
const obj = alarms[key]
let res: 'min' | 'max' | '' = ''
if(obj) {
if(value < obj.min) res = 'min'
else if(value > obj.max) res = 'max'
}
return res
}

View File

@ -1,5 +1,6 @@
import * as XLSX from "xlsx"
import { ElMessage, ElMessageBox } from 'element-plus'
import { dateFormater } from '@/utils/date-util'
export const tableRemoveRow = (params: any, callback: (res: boolean) => void) => {
if (!params.data) params.data = []
@ -41,10 +42,31 @@ export const tableRemoveRow = (params: any, callback: (res: boolean) => void) =>
}
export const exportData = (fileName: string, data: Array<any>) => {
if(data.length < 1) return
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(
wb,
XLSX.utils.json_to_sheet(data)
);
)
XLSX.writeFile(wb, fileName + '.xls'); // 导出Excel
}
/**
*
* @param fileName
* @param data
* @param sheetNameKey data中的键名
* @param sheetDataKey data中的键名
*/
export const exportMultiData = (fileName: string, data: Array<any>, sheetNameKey: string, sheetDataKey: string) => {
if(data.length < 1) return
const wb = XLSX.utils.book_new();
data.forEach(item => {
XLSX.utils.book_append_sheet(
wb,
XLSX.utils.json_to_sheet(item[sheetDataKey]),
item[sheetNameKey] instanceof Date ? dateFormater('yyyy-MM-dd HH:mm:ss', item[sheetNameKey]) : item[sheetNameKey]
)
})
XLSX.writeFile(wb, fileName + '.xls'); // 导出Excel
}

View File

@ -57,12 +57,16 @@
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { tableRemoveRow, exportData } from '@/utils/table-util'
import CommonPagination from '@/components/common-pagination.vue'
import PatientsForm from './form/patients-form.vue'
import ImportDialog from '@/components/import-dialog.vue'
import { getDeptData } from '@/static-data/core'
const router = useRouter()
const route = useRoute()
const tableRef = ref()
const patientsFormRef = ref()
const importDialogRef = ref()
@ -121,7 +125,10 @@ const viewUserInfo = (e: any) => {
}, 0)
}
const viewSurgeryInfo = (e: any) => {
router.push({
path: '/patients-manage/surgery-info',
query: e
})
}
const tableRowClick = (row: any) => {
tableRef.value.toggleRowSelection(row)

View File

@ -3,7 +3,73 @@
<div class="header-box">
<h3 class="f18">电子病史</h3>
<div class="btn-box">
<el-button></el-button>
<el-button v-if="tableData && tableData.length > 0"
@click="exportMultiData('电子病史', tableData, 'startTime', 'data')">下载</el-button>
<!-- <el-button @click="router.back()">返回</el-button> -->
</div>
</div>
<div class="search-box">
<div class="search-cell">
<span class="label">姓名</span>
<el-select v-model="queryParams.name" popper-class="custom-patients-option" filterable placeholder="请输入选择姓名"
remote :remote-method="remoteSearchName" @change="selectNameChange">
<el-option v-for="(item, index) in patientsOption.slice(0, 999)" :key="'name-' + index"
:label="item.name" :value="item.code" />
</el-select>
</div>
<div class="search-cell">
<span class="label">住院号</span>
<el-input v-model="queryParams.code"></el-input>
</div>
<div class="search-cell">
<span class="label">性别</span>
<el-select v-model="queryParams.sex">
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</div>
<div class="search-cell">
<span class="label">手术名称</span>
<el-input v-model="queryParams.surgeryName"></el-input>
</div>
<div class="search-cell">
<span class="label">麻醉方式</span>
<el-select v-model="queryParams.narcotismWay">
<el-option v-for="item in getNarcotismWay()" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
<el-button type="primary" icon="Search" @click="queryData(queryParams)">查询</el-button>
</div>
<div class="content-box">
<div class="left-box">
<div class="title">手术时间</div>
<ul class="list-box">
<li class="list-item" v-for="(item, index) in tableData" :key="'time-' + index"
:class="{ 'active': timeActive === index }" @click="selectTime(item, index)">
<b>{{ dateFormater('yyyy.MM.dd', item.startTime) }}</b>{{ dateFormater(' HH:mm:ss', item.startTime)
}}
</li>
</ul>
</div>
<div class="right-box">
<div class="type-box">
<div class="type-item" v-for="(item, index) in getFormTypes().slice(0, 10)" :key="'type-' + index"
:class="{ 'active': item.name === queryParams.type }" @click="formTypeChange(item.name)">{{
item.name
}}</div>
<el-select v-model="queryParams.type" filterable placeholder="搜索更多表单" @change="formTypeChange">
<el-option v-for="(item, index) in getFormTypes()" :key="'type-option-' + index" :label="item.name"
:value="item.name"></el-option>
</el-select>
</div>
<div class="table-box">
<el-table class="custom-table" :data="tableData[timeActive]?.data" border height="100%"
:cell-class-name="tableCellFilter">
<el-table-column v-for="item in tableData[timeActive]?.dataKey" :key="item" :prop="item"
:label="item" align="center" />
</el-table>
</div>
</div>
</div>
</div>
@ -11,16 +77,77 @@
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { exportMultiData } from '@/utils/table-util'
import { dateFormater } from '@/utils/date-util'
import { getPatients, getNarcotismWay, getFormTypes, getDataAlarmState } from '@/static-data/core'
const router = useRouter()
const route = useRoute()
const patients = getPatients()
const queryParams = ref({} as any)
const timeActive = ref<number>(0)
const tableData = ref([] as any)
const patientsOption = ref([] as any)
queryParams.value = route.query
if (queryParams.value.code) queryData(queryParams.value)
function queryData(e: any) {
if (!e.code) {
ElMessage.warning('住院号为必填项!')
return
}
tableData.value = []
for (let i = 1; i < 11; i++) {
const obj = {
startTime: new Date(2023, 11, i, 6),
endTime: new Date(2023, 11, i, 10),
dataKey: ['ID', 'Phase', 'BIS', 'HR', 'SBP', 'DBP', 'ST', 'TEMP', 'SPO2', 'EtCo2', 'PPG', 'ABG', 'TOF', 'TIME'],
data: [] as Array<any>
}
for (let j = 1; j < 100; j++) {
const data = {} as any
for (let key of obj.dataKey) {
if (key === 'ID') data[key] = j
else if (key === 'Phase') data[key] = 2
else data[key] = Number((Math.random() * 100).toFixed(2))
}
obj.data.push(data)
}
tableData.value.push(obj)
}
}
const remoteSearchName = (e: any) => {
if (e) {
patientsOption.value = patients.filter((o: any) => o.name.indexOf(e) !== -1)
}
}
const selectNameChange = (e: string) => {
queryParams.value.code = e
}
const selectTime = (item: any, index: number) => {
timeActive.value = index
}
const formTypeChange = (e: string) => {
console.log(e)
queryParams.value.type = e
queryData(queryParams.value)
}
const tableCellFilter = ({ row, column, rowIndex, columnIndex }: any) => {
return 'alarm-' + getDataAlarmState(row[column.label], column.label)
}
</script>
<style lang='scss' scoped>
.surgery-info-page {
width: 100%;
height: 100%;
.header-box {
width: 100%;
height: 50px;
@ -29,12 +156,177 @@ const route = useRoute()
display: flex;
justify-content: space-between;
align-items: center;
h3 {
color: $main-color;
}
.btn-box {
.btn-box {}
}
.search-box {
width: 100%;
height: 40px;
display: flex;
align-items: center;
&>*~* {
margin-left: 20px;
}
.search-cell {
display: flex;
align-items: center;
.label {
flex-shrink: 0;
margin-right: 10px;
}
}
}
.content-box {
width: 100%;
height: calc(100% - 100px);
margin-top: 10px;
display: flex;
justify-content: space-between;
.left-box {
width: 220px;
height: 100%;
border: 1px solid $border-color;
border-radius: 5px;
overflow: hidden;
.title {
width: 100%;
height: 36px;
background: $main-color;
color: white;
font-size: 18px;
line-height: 36px;
text-align: center;
font-weight: 600;
}
.list-box {
width: 100%;
height: calc(100% - 40px);
margin-top: 4px;
overflow-x: hidden;
overflow-y: auto;
.list-item {
cursor: pointer;
height: 50px;
line-height: 50px;
color: $main-color;
font-size: 16px;
padding: 0 10px;
text-align: center;
&.active {
background: #f2f3f5;
}
b {
padding-right: 5px;
}
}
}
}
.right-box {
width: calc(100% - 240px);
height: 100%;
.type-box {
width: 100%;
height: 100px;
display: flex;
flex-wrap: wrap;
.type-item {
width: calc(100% / 6 - 10px);
height: 38px;
line-height: 38px;
color: white;
font-size: 16px;
font-weight: 600;
text-align: center;
background: #f8b300;
border-radius: 5px;
margin: 0 12px 10px 0;
&:nth-child(6) {
margin-right: 0;
}
&.active {
background: #c77000;
}
}
:deep(.el-select) {
flex-shrink: 1;
width: calc(100% / 3 - 10px);
.el-input {
height: 38px;
}
}
}
.table-box {
width: 100%;
height: calc(100% - 100px);
:deep(.el-table.custom-table) {
--el-table-border-color: #18b2bd;
font-size: 16px;
&.el-table--border td.el-table__cell {
border-width: 2px;
&:last-of-type {
border-right-width: 1px;
}
}
th.el-table__cell {
border-width: 0;
color: white;
background-color: $main-color;
}
.el-table__cell {
color: black;
font-family: '宋体';
font-weight: 600;
padding: 5px 0;
&.alarm-min {
background-color: #bdd7ef;
}
&.alarm-max {
background-color: #f9cbad;
}
}
}
}
}
}
}
</style>
<style>
/* .custom-patients-option {
overflow: hidden;
* {
content-visibility: auto;
}
} */
</style>

View File

@ -16,7 +16,7 @@
<div class="btn-box">
<el-button class="f18" type="primary" @click="confirmRemote">确定连接</el-button>
<!-- <el-button class="f18" @click="breakRemote">断开连接</el-button> -->
<el-button class="f18" @click="dialogVisible = false">返回</el-button>
<el-button class="f18" style="margin-left: 50px;" @click="dialogVisible = false">返回</el-button>
</div>
</el-dialog>
</template>
@ -116,7 +116,7 @@ const breakRemote = () => {
}
.btn-box {
display: flex;
justify-content: space-between;
justify-content: center;
align-items: center;
margin-top: 50px;
.el-button {