feat:对接手术间接口

main
@0Melon0 11 months ago
parent cf96e155b6
commit d36d903a53

@ -0,0 +1,37 @@
import _axios from '@/utils/_axios';
/**
* 获取手术接台平均时长(左下角)
*/
export const GetMonitorAverageReceptionTime = date => {
return _axios({
url: '/api/QualityMicroservice/Monitor/GetMonitorAverageReceptionTime',
params: {
date,
},
});
};
/**
* 获取手术时长列表(右边)
*/
export const GetMonitorRoomUsageRate = date => {
return _axios({
url: '/api/QualityMicroservice/Monitor/GetMonitorRoomUsageRate',
params: {
date,
},
});
};
/**
* 获取手术室列表
*/
export const GetRoomList = () => {
return _axios({
url: '/api/ScheduleMicroservice/dict_operationroom/querylist',
params: {
pageSize: 999,
},
});
};

@ -1,5 +1,5 @@
<template> <template>
<div class="h-[32.31vh] mt-[2.77vh] pt-[4vh] bgLeftBottomBox"> <div class="h-[32.31vh] mt-[2.77vh] pt-[4vh] bgLeftBottomBox" v-loading="isLoading">
<div class="h-[20vh]" ref="echartsContainer"></div> <div class="h-[20vh]" ref="echartsContainer"></div>
<section class="w-[37.96vh] h-[5.18vh] leading-[5.18vh] text-center border border-[#2D126F] mx-auto"> <section class="w-[37.96vh] h-[5.18vh] leading-[5.18vh] text-center border border-[#2D126F] mx-auto">
<span class="text-[1.85vh] youshe">平均接台时间</span> <span class="text-[1.85vh] youshe">平均接台时间</span>
@ -9,6 +9,9 @@
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { GetMonitorAverageReceptionTime } from '@/api/room';
import dayjs from 'dayjs';
let chart = null;
export default { export default {
data() { data() {
return { return {
@ -59,18 +62,18 @@ export default {
value: 45, value: 45,
title: { show: false }, title: { show: false },
detail: { detail: {
offsetCenter: [0, '20%'], offsetCenter: [0, '4%'],
formatter: function (value) { formatter: function (value) {
return '{a|' + value + '}{b|min}'; return '{a|' + value + '}{b|min}';
}, },
rich: { rich: {
a: { a: {
fontSize: 40, fontSize: 32,
color: '#4AC9FF', color: '#4AC9FF',
fontFamily: 'DIN-Bold,Microsoft YaHei', fontFamily: 'DIN-Bold,Microsoft YaHei',
}, },
b: { b: {
fontSize: 20, fontSize: 16,
color: '#4AC9FF', color: '#4AC9FF',
fontFamily: 'DIN-Bold,Microsoft YaHei', fontFamily: 'DIN-Bold,Microsoft YaHei',
verticalAlign: 'bottom', verticalAlign: 'bottom',
@ -82,12 +85,25 @@ export default {
}, },
], ],
}, },
isLoading: true,
}; };
}, },
mounted() { methods: {
const chartContainer = this.$refs.echartsContainer; onGetPageData() {
const chart = echarts.init(chartContainer); let nowDay = dayjs().format('YYYY-MM-DD');
if (this.$store.getters.isMock) {
nowDay = '2024-06-06';
}
GetMonitorAverageReceptionTime(nowDay).then(res => {
this.chartOptions['series'][0]['data'][0]['value'] = res['data']['averageReceptionTime'] > 999 ? 999 : res['data']['averageReceptionTime'];
chart.setOption(this.chartOptions); chart.setOption(this.chartOptions);
this.isLoading = false;
});
},
},
mounted() {
chart = echarts.init(this.$refs.echartsContainer);
this.onGetPageData();
}, },
}; };
</script> </script>

@ -1,18 +1,21 @@
<template> <template>
<div class="h-[48.79vh] bgLeftTopBox p-[1.85vh]"> <div class="h-[48.79vh] bgLeftTopBox p-[1.85vh]" v-loading="isLoading">
<div class="w-[22vh] h-[22vh] mx-auto mt-[4.6vh]" ref="echartsContainer"></div> <div class="w-[22vh] h-[22vh] mx-auto mt-[4.6vh]" ref="echartsContainer"></div>
<div class="w-[37.96vh] h-[6.29vh] mx-auto mt-[8.6vh] px-[4.96vh] flex justify-between items-center bgTopLeftItemBox"> <div class="w-[37.96vh] h-[6.29vh] mx-auto mt-[8.6vh] px-[4.96vh] flex justify-between items-center bgTopLeftItemBox">
<div class="flex"> <div class="flex">
<img src="@/assets/svg/Room/LeftTop/TrianglePurple.svg" /> <img src="@/assets/svg/Room/LeftTop/TrianglePurple.svg" />
<span class="text-[1.85vh] youshe ml-[1.4vh]">手术间数</span> <span class="text-[1.85vh] youshe ml-[1.4vh]">手术间数</span>
</div> </div>
<p class="text-[2.96vh] text-[#733FF3] youshe">100</p> <p class="text-[2.96vh] text-[#733FF3] youshe">{{ opTotal }}</p>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { GetMonitorOperationCount } from '@/api/monitor';
import dayjs from 'dayjs';
let chart = null;
export default { export default {
data() { data() {
return { return {
@ -98,22 +101,27 @@ export default {
}, },
], ],
}, },
peopleData: [ opTotal: 100,
{ isLoading: true,
itemName: '进行中', };
itemVal: '50',
}, },
{ methods: {
itemName: '待进行', onGetPageData() {
itemVal: '300', let nowDay = dayjs().format('YYYY-MM-DD');
if (this.$store.getters.isMock) {
nowDay = '2024-06-06';
}
GetMonitorOperationCount(nowDay).then(res => {
this.chartOptions['series'][0]['data'][0]['value'] = res['data']['firstPunctualityRate'].slice(0, -1);
this.opTotal = res['data']['roomCount'];
chart.setOption(this.chartOptions);
this.isLoading = false;
});
}, },
],
};
}, },
mounted() { mounted() {
const chartContainer = this.$refs.echartsContainer; chart = echarts.init(this.$refs.echartsContainer);
const chart = echarts.init(chartContainer); this.onGetPageData();
chart.setOption(this.chartOptions);
}, },
}; };
</script> </script>

@ -0,0 +1,234 @@
<template>
<div class="w-[116.94vh] h-[85.51vh] bgRightMidBox">
<section class="h-full" ref="echartsContainer"></section>
</div>
</template>
<script>
import * as echarts from 'echarts';
import dayjs from 'dayjs';
export default {
data() {
return {
isLoding: false,
chartOptions: {
grid: {
width: '86%',
height: '80%',
top: '14%',
},
legend: {
data: [
{
name: '入手术室',
icon: 'rect',
itemStyle: {
color: '#92CC76',
},
},
{
name: '开始手术',
icon: 'rect',
itemStyle: {
color: '#EF6666',
},
},
{
name: '手术结束',
icon: 'rect',
itemStyle: {
color: '#FAC858',
},
},
{
name: '出手术室',
icon: 'rect',
itemStyle: {
color: '#5470C6',
},
},
],
selectedMode: 'none',
top: "6%",
right: "4%",
textStyle: {
color: '#fff',
fontSize: 14,
fontFamily: 'DIN-Bold,Microsoft YaHei',
},
},
xAxis: {
type: 'time',
position: 'top',
splitNumber: 24,
axisLabel: {
color: '#B7BDBF',
fontSize: 12,
margin: 16,
formatter: function (value) {
var date = new Date(value);
var hours = date.getHours();
var minutes = date.getMinutes();
if (hours === 0 && minutes === 0) {
return '00:00';
} else {
return (hours < 10 ? '0' : '') + hours + ':' + (minutes < 10 ? '0' : '') + minutes;
}
},
},
},
yAxis: {
type: 'category',
data: [],
axisLabel: {
color: '#B7BDBF',
fontSize: 12,
margin: 16,
fontFamily: 'DIN-Bold,Microsoft YaHei',
},
},
series: [],
},
};
},
methods: {
initData() {
//
const currentDate = dayjs().format('YYYY-MM-DD');
const hours = new Date().getHours();
const detailMin = dayjs().subtract(1, 'minute').format('HH:mm:00');
const sevenMinutesAgo = dayjs().subtract(8, 'minute').format('HH:mm:00');
this.chartOptions.xAxis.min = `${currentDate} 08:00:00`;
this.chartOptions.xAxis.max = `${dayjs().add(1, 'day').format('YYYY-MM-DD')} 07:00:00`;
//
const num = 20;
//
const timeArr = [];
//
for (let index = num; index >= 1; index--) {
this.chartOptions.yAxis.data.push(`手术间${String(index).padStart(3, '0')}`);
const isUseArr = this.getUseTime();
for (let j = 1; j < isUseArr.length; j += 2) {
if (isUseArr[j] <= hours) {
timeArr.push({
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${isUseArr[j]}:00:00`,
yValue: index - 1,
color: '#5470C6',
diff: dayjs(`${currentDate} ${isUseArr[j]}:00:00`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '出手术室',
});
} else if (isUseArr[j] > hours && isUseArr[j - 1] < hours) {
if (Math.random() > 0.5) {
timeArr.push({
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${detailMin}`,
yValue: index - 1,
color: '#EF6666',
diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '开始手术',
});
} else {
timeArr.push({
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${detailMin}`,
yValue: index - 1,
color: '#FAC858',
diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '手术结束',
});
}
} else if (isUseArr[j] > hours && isUseArr[j - 1] == hours) {
timeArr.push({
startTime: `${currentDate} ${sevenMinutesAgo}`,
endTime: `${currentDate} ${detailMin}`,
yValue: index - 1,
color: '#92CC76',
diff: '7',
name: '入手术室',
});
}
}
}
// series
console.log(timeArr);
this.chartOptions.series = this.seriesData(timeArr);
},
seriesData(data) {
const res = data.map(function (item) {
return {
type: 'custom',
name: item.name,
renderItem: function (params, api) {
var xStart = api.coord([item.startTime, item.yValue]);
var xEnd = api.coord([item.endTime, item.yValue]);
var textX = (xStart[0] + xEnd[0]) / 2;
var textY = xStart[1] - 20;
return {
type: 'group',
children: [
{
type: 'line',
shape: {
x1: xStart[0],
y1: xStart[1],
x2: xEnd[0],
y2: xEnd[1],
},
style: {
stroke: item.color,
lineWidth: 8,
},
},
{
type: 'text',
position: [textX, textY],
style: {
text: `${item.diff} min`,
fill: '#B7BDBF',
textSize: '12px',
textAlign: 'center',
},
},
],
};
},
data: [item],
};
});
return res;
},
getUseTime() {
// 使
function getRandomUniqueValues(min, max, count) {
const values = new Set();
while (values.size < count) {
values.add(Math.floor(Math.random() * (max - min + 1)) + min);
}
return Array.from(values);
}
const numValues = Math.floor(Math.random() * 3) + 8;
const randomValues = getRandomUniqueValues(8, 24, numValues % 2 ? numValues + 1 : numValues);
return randomValues.sort((a, b) => {
return a - b;
});
},
},
mounted() {
const chartContainer = this.$refs.echartsContainer;
const chart = echarts.init(chartContainer);
this.initData();
chart.setOption(this.chartOptions);
},
};
</script>
<style>
.bgRightMidBox {
background-image: url('@/assets/svg/Room/RightMid/Box.svg');
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
</style>

@ -7,6 +7,9 @@
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { GetRoomList, GetMonitorRoomUsageRate } from '@/api/room';
import { statusToTxt, textToColor } from '@/utils/common';
let chart = null;
export default { export default {
data() { data() {
return { return {
@ -18,39 +21,10 @@ export default {
top: '14%', top: '14%',
}, },
legend: { legend: {
data: [ data: [],
{
name: '入手术室',
icon: 'rect',
itemStyle: {
color: '#92CC76',
},
},
{
name: '开始手术',
icon: 'rect',
itemStyle: {
color: '#EF6666',
},
},
{
name: '手术结束',
icon: 'rect',
itemStyle: {
color: '#FAC858',
},
},
{
name: '出手术室',
icon: 'rect',
itemStyle: {
color: '#5470C6',
},
},
],
selectedMode: 'none', selectedMode: 'none',
top: "6%", top: '6%',
right: "4%", right: '4%',
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontSize: 14, fontSize: 14,
@ -89,10 +63,19 @@ export default {
}, },
series: [], series: [],
}, },
legendDataList: ['入手术间', '手术开始', '手术结束', '出手术间'],
yAxisArr: [],
showPageIndex: -1,
allPageIndex: 0,
allPageNum: 0,
pageNum: 20,
allRoomList: [],
originData: [],
renderTimer: null,
}; };
}, },
methods: { methods: {
initData() { initMockData() {
// //
const currentDate = dayjs().format('YYYY-MM-DD'); const currentDate = dayjs().format('YYYY-MM-DD');
const hours = new Date().getHours(); const hours = new Date().getHours();
@ -114,9 +97,9 @@ export default {
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`, startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${isUseArr[j]}:00:00`, endTime: `${currentDate} ${isUseArr[j]}:00:00`,
yValue: index - 1, yValue: index - 1,
color: '#5470C6', color: textToColor('出手术间'),
diff: dayjs(`${currentDate} ${isUseArr[j]}:00:00`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'), diff: dayjs(`${currentDate} ${isUseArr[j]}:00:00`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '出手术', name: '出手术',
}); });
} else if (isUseArr[j] > hours && isUseArr[j - 1] < hours) { } else if (isUseArr[j] > hours && isUseArr[j - 1] < hours) {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
@ -124,16 +107,16 @@ export default {
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`, startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${detailMin}`, endTime: `${currentDate} ${detailMin}`,
yValue: index - 1, yValue: index - 1,
color: '#EF6666', color: textToColor('手术开始'),
diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'), diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '开始手术', name: '手术开始',
}); });
} else { } else {
timeArr.push({ timeArr.push({
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`, startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${detailMin}`, endTime: `${currentDate} ${detailMin}`,
yValue: index - 1, yValue: index - 1,
color: '#FAC858', color: textToColor('手术结束'),
diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'), diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '手术结束', name: '手术结束',
}); });
@ -143,20 +126,30 @@ export default {
startTime: `${currentDate} ${sevenMinutesAgo}`, startTime: `${currentDate} ${sevenMinutesAgo}`,
endTime: `${currentDate} ${detailMin}`, endTime: `${currentDate} ${detailMin}`,
yValue: index - 1, yValue: index - 1,
color: '#92CC76', color: textToColor('入手术间'),
diff: '7', diff: '7',
name: '入手术', name: '入手术',
}); });
} }
} }
} }
this.formatLegendData();
// series // series
this.chartOptions.series = this.seriesData(timeArr); this.chartOptions.series = this.seriesData(timeArr);
chart.setOption(this.chartOptions);
},
onGetPageData() {
let today = dayjs().format('YYYY-MM-DD');
today = '2024-06-06';
this.chartOptions.xAxis.min = `${today} 08:00:00`;
this.chartOptions.xAxis.max = `${dayjs(today).add(1, 'day').format('YYYY-MM-DD')} 07:00:00`;
GetMonitorRoomUsageRate(today).then(res => {
this.originData = res['data'];
this.formatPageList();
});
}, },
seriesData(data) { seriesData(data) {
// const obj = {};
const res = data.map(function (item) { const res = data.map(function (item) {
// obj[item.name] = item.color;
return { return {
type: 'custom', type: 'custom',
name: item.name, name: item.name,
@ -197,8 +190,6 @@ export default {
data: [item], data: [item],
}; };
}); });
// console.log(obj);
// console.log(JSON.stringify(res));
return res; return res;
}, },
getUseTime() { getUseTime() {
@ -217,12 +208,72 @@ export default {
return a - b; return a - b;
}); });
}, },
formatLegendData() {
if (this.legendDataList.length) {
this.legendDataList.forEach(item => {
this.chartOptions.legend.data.push({
name: item,
icon: 'rect',
itemStyle: {
color: textToColor(item),
}, },
mounted() { });
const chartContainer = this.$refs.echartsContainer; });
const chart = echarts.init(chartContainer); } else {
this.initData(); this.chartOptions.legend.data = [];
}
},
formatPageList() {
// X
const timeArr = [];
// ,Y
++this.showPageIndex >= this.allPageNum && (this.showPageIndex = 0);
this.yAxisArr = this.allRoomList.slice(this.pageNum * this.showPageIndex, this.pageNum * (this.showPageIndex + 1)).reverse();
console.log(this.yAxisArr);
this.chartOptions.yAxis.data = this.yAxisArr;
this.legendDataList = [];
//
this.originData.forEach(item => {
if (this.yAxisArr.includes(item['roomName'])) {
if (!this.legendDataList.includes(statusToTxt(item['procStatus']))) {
this.legendDataList.push(statusToTxt(item['procStatus']));
}
timeArr.push({
startTime: dayjs(item['inRoomDateTime']).format('YYYY-MM-DD HH:mm:ss'),
endTime: dayjs(item['inRoomDateTime']).add(item['surgicalDuration'], 'minute').format('YYYY-MM-DD HH:mm:ss'),
yValue: this.yAxisArr.findIndex(text => text == item['roomName']),
color: textToColor(statusToTxt(item['procStatus'])),
diff: item['surgicalDuration'],
name: statusToTxt(item['procStatus']),
});
}
});
this.formatLegendData();
console.log(timeArr);
// series
this.chartOptions.series = this.seriesData(timeArr);
chart.setOption(this.chartOptions); chart.setOption(this.chartOptions);
this.renderTimer = setTimeout(() => {
this.formatPageList();
}, 5000);
},
},
mounted() {
GetRoomList().then(res => {
res['Data']['Data'].forEach(item => {
if (item['RoomTypeCode'] == 0) {
this.allRoomList.push(item['RoomName']);
this.allPageIndex++;
}
});
this.allPageNum = Math.ceil(this.allPageIndex / this.pageNum);
chart = echarts.init(this.$refs.echartsContainer);
if (!this.$store.getters.isMock) {
this.initMockData();
} else {
this.onGetPageData();
}
});
}, },
}; };
</script> </script>

Loading…
Cancel
Save