mirror of
https://gitee.com/xiongmao1988/rax-medical.git
synced 2025-08-24 13:04:57 +08:00
手术信息
This commit is contained in:
parent
0747c8a344
commit
b7d1036664
|
@ -16,3 +16,59 @@ export const getDeptData = () => {
|
||||||
depts.push({ label: '心脏内科', value: '心脏内科' })
|
depts.push({ label: '心脏内科', value: '心脏内科' })
|
||||||
return depts
|
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
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import * as XLSX from "xlsx"
|
import * as XLSX from "xlsx"
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { dateFormater } from '@/utils/date-util'
|
||||||
|
|
||||||
export const tableRemoveRow = (params: any, callback: (res: boolean) => void) => {
|
export const tableRemoveRow = (params: any, callback: (res: boolean) => void) => {
|
||||||
if (!params.data) params.data = []
|
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>) => {
|
export const exportData = (fileName: string, data: Array<any>) => {
|
||||||
|
if(data.length < 1) return
|
||||||
const wb = XLSX.utils.book_new();
|
const wb = XLSX.utils.book_new();
|
||||||
XLSX.utils.book_append_sheet(
|
XLSX.utils.book_append_sheet(
|
||||||
wb,
|
wb,
|
||||||
XLSX.utils.json_to_sheet(data)
|
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
|
XLSX.writeFile(wb, fileName + '.xls'); // 导出Excel
|
||||||
}
|
}
|
|
@ -57,12 +57,16 @@
|
||||||
<script lang='ts' setup>
|
<script lang='ts' setup>
|
||||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { tableRemoveRow, exportData } from '@/utils/table-util'
|
import { tableRemoveRow, exportData } from '@/utils/table-util'
|
||||||
import CommonPagination from '@/components/common-pagination.vue'
|
import CommonPagination from '@/components/common-pagination.vue'
|
||||||
import PatientsForm from './form/patients-form.vue'
|
import PatientsForm from './form/patients-form.vue'
|
||||||
import ImportDialog from '@/components/import-dialog.vue'
|
import ImportDialog from '@/components/import-dialog.vue'
|
||||||
import { getDeptData } from '@/static-data/core'
|
import { getDeptData } from '@/static-data/core'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const patientsFormRef = ref()
|
const patientsFormRef = ref()
|
||||||
const importDialogRef = ref()
|
const importDialogRef = ref()
|
||||||
|
@ -121,7 +125,10 @@ const viewUserInfo = (e: any) => {
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
const viewSurgeryInfo = (e: any) => {
|
const viewSurgeryInfo = (e: any) => {
|
||||||
|
router.push({
|
||||||
|
path: '/patients-manage/surgery-info',
|
||||||
|
query: e
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const tableRowClick = (row: any) => {
|
const tableRowClick = (row: any) => {
|
||||||
tableRef.value.toggleRowSelection(row)
|
tableRef.value.toggleRowSelection(row)
|
||||||
|
|
|
@ -3,7 +3,73 @@
|
||||||
<div class="header-box">
|
<div class="header-box">
|
||||||
<h3 class="f18">电子病史</h3>
|
<h3 class="f18">电子病史</h3>
|
||||||
<div class="btn-box">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,16 +77,77 @@
|
||||||
|
|
||||||
<script lang='ts' setup>
|
<script lang='ts' setup>
|
||||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
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 router = useRouter()
|
||||||
const route = useRoute()
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang='scss' scoped>
|
<style lang='scss' scoped>
|
||||||
.surgery-info-page {
|
.surgery-info-page {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.header-box {
|
.header-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
@ -29,12 +156,177 @@ const route = useRoute()
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
color: $main-color;
|
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>
|
||||||
|
<style>
|
||||||
|
/* .custom-patients-option {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
* {
|
||||||
|
content-visibility: auto;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
</style>
|
|
@ -16,7 +16,7 @@
|
||||||
<div class="btn-box">
|
<div class="btn-box">
|
||||||
<el-button class="f18" type="primary" @click="confirmRemote">确定连接</el-button>
|
<el-button class="f18" type="primary" @click="confirmRemote">确定连接</el-button>
|
||||||
<!-- <el-button class="f18" @click="breakRemote">断开连接</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>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
@ -116,7 +116,7 @@ const breakRemote = () => {
|
||||||
}
|
}
|
||||||
.btn-box {
|
.btn-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
.el-button {
|
.el-button {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user