fix: 运营监控页中环状图优化、暂无数据icon添加、多个页面中的首台率显示bug处理等

main
weiyin 10 months ago
parent 69614ca454
commit 21737e13f7

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 80 KiB

@ -14,9 +14,9 @@
v-if="getDataList.length"
:getDataList="getDataList"
></Histogram>
<div v-else class="flex w-[100%] h-[100%] items-center justify-center">
<!-- 暂无数据 -->
<div v-else class="flex flex-col w-[100%] h-[100%] items-center justify-center">
<img src="@/assets/svg/noData.svg" />
<span>暂无数据</span>
</div>
</div>
<div

@ -58,6 +58,10 @@ export default {
formatter: "{b}{c}",
color: "inherit",
},
padAngle: 5,
itemStyle: {
borderRadius: 10,
},
},
],
},
@ -78,6 +82,10 @@ export default {
formatter: "{b}{c}",
color: "inherit",
},
padAngle: 5,
itemStyle: {
borderRadius: 10,
},
},
],
},

@ -17,8 +17,9 @@
v-if="getDataList.length"
:getDataList="getDataList"
></Histogram>
<div v-else class="flex w-[100%] h-[100%] items-center justify-center">
暂无数据
<div v-else class="flex flex-col w-[100%] h-[100%] items-center justify-center">
<img src="@/assets/svg/noData.svg" />
<span>暂无数据</span>
</div>
</div>
<div

@ -113,13 +113,18 @@ export default {
if (!res.data) {
return;
}
this.overviewData[0]["itemVal"] = res["data"][
"firstPunctualityRate"
].slice(0, -1);
this.overviewData[1]["itemVal"] = res["data"]["roomUserRate"].slice(
0,
-1
);
let fisrtRate = res["data"]["firstPunctualityRate"];
if (fisrtRate.includes("%")) {
this.overviewData[0]["itemVal"] = fisrtRate.slice(0, -1);
} else {
this.overviewData[0]["itemVal"] = Number(fisrtRate);
}
let roomUserRate = res["data"]["roomUserRate"];
if (roomUserRate.includes("%")) {
this.overviewData[1]["itemVal"] = roomUserRate.slice(0, -1);
} else {
this.overviewData[1]["itemVal"] = Number(roomUserRate);
}
this.overviewData[2]["itemVal"] = res["data"]["patEmergencyCount"];
this.totalPopulation = res["data"]["patCount"];
this.peopleData[0]["itemVal"] = res["data"]["patOperationing"];

@ -159,9 +159,17 @@ export default {
this.isLoading = false;
return;
}
this.chartOptions["series"][0]["data"][0]["value"] = res["data"][
"firstPunctualityRate"
].slice(0, -1);
let fisrtRate = res["data"]["firstPunctualityRate"];
if (fisrtRate.includes("%")) {
this.chartOptions["series"][0]["data"][0]["value"] = fisrtRate.slice(
0,
-1
);
} else {
this.chartOptions["series"][0]["data"][0]["value"] =
Number(fisrtRate);
}
this.peopleData[0]["itemVal"] = res["data"]["patOperationing"];
this.peopleData[1]["itemVal"] = res["data"]["patWating"];
this.totalPopulation = res["data"]["patCount"];

@ -3,34 +3,93 @@
<div class="w-[112.96vh] h-[77.03vh] mx-auto mt-[2.96vh]">
<div class="h-[4.44vh] leading-[4.44vh] text-center bg-[#322369]">
<div class="inline-block">
<div class="inline-block w-[11.11vh] text-[#AAAAAA] text-[1.48vh]">手术间</div>
<div class="inline-block w-[16.51vh] text-[#AAAAAA] text-[1.48vh]">手术名称</div>
<div class="inline-block w-[13.11vh] text-[#AAAAAA] text-[1.48vh]">申请类型</div>
<div class="inline-block w-[16.66vh] text-[#AAAAAA] text-[1.48vh]">入手术室时间</div>
<div class="inline-block w-[16.66vh] text-[#AAAAAA] text-[1.48vh]">麻醉开始时间</div>
<div class="inline-block w-[16.66vh] text-[#AAAAAA] text-[1.48vh]">手术开始时间</div>
<div class="inline-block w-[11.11vh] text-[#AAAAAA] text-[1.48vh]">是否准点</div>
<div class="inline-block w-[5.11vh] text-[#AAAAAA] text-[1.48vh]">
手术间
</div>
<div class="inline-block w-[11.11vh] text-[#AAAAAA] text-[1.48vh]">
人员
</div>
<div class="inline-block w-[16.51vh] text-[#AAAAAA] text-[1.48vh]">
手术名称
</div>
<div class="inline-block w-[13.11vh] text-[#AAAAAA] text-[1.48vh]">
申请类型
</div>
<div class="inline-block w-[16.66vh] text-[#AAAAAA] text-[1.48vh]">
入手术室时间
</div>
<div class="inline-block w-[16.66vh] text-[#AAAAAA] text-[1.48vh]">
麻醉开始时间
</div>
<div class="inline-block w-[16.66vh] text-[#AAAAAA] text-[1.48vh]">
手术开始时间
</div>
<div class="inline-block w-[11.11vh] text-[#AAAAAA] text-[1.48vh]">
是否准点
</div>
</div>
</div>
<div class="h-[72.58vh]">
<el-carousel direction="vertical" :autoplay="true" :interval="15000" indicatorPosition="none">
<el-carousel
direction="vertical"
:autoplay="true"
:interval="15000"
indicatorPosition="none"
>
<el-carousel-item v-for="(item, index) in scheduList" :key="index">
<template v-for="(subItem, index) in item">
<div class="h-[4.44vh] leading-[4.44vh] mt-[0.74vh] text-center itemStyle" :key="index">
<div
class="h-[4.44vh] leading-[4.44vh] mt-[0.74vh] text-center itemStyle"
:key="index"
>
<div class="inline-block">
<div class="inline-block align-top w-[11.11vh] text-[1.48vh] panmen">{{ subItem['roomName'] }}</div>
<div class="inline-block align-top w-[16.51vh] text-[1.48vh] px-1">
<marquee scrollamount="2">{{ subItem['operationName'] }}</marquee>
<div
class="inline-block align-top w-[5.11vh] text-[1.48vh] panmen"
>
{{ subItem["roomName"] }}
</div>
<div class="inline-block align-top w-[11.11vh] text-[1.48vh]">
{{ subItem["patientName"] }}
</div>
<div
class="inline-block align-top w-[16.51vh] text-[1.48vh] px-1"
>
<marquee scrollamount="2">{{
subItem["operationName"]
}}</marquee>
</div>
<div
class="inline-block align-middle w-[13.11vh] text-[1.48vh]"
>
<img
class="mx-auto"
src="@/assets/svg/Operation/RightMid/Emergency.svg"
v-if="subItem['OperationType']"
/>
<img
class="mx-auto"
src="@/assets/svg/Operation/RightMid/Other.svg"
v-else
/>
</div>
<div class="inline-block align-middle w-[13.11vh] text-[1.48vh]">
<img class="mx-auto" src="@/assets/svg/Operation/RightMid/Emergency.svg" v-if="subItem['OperationType']" />
<img class="mx-auto" src="@/assets/svg/Operation/RightMid/Other.svg" v-else />
<div class="inline-block align-top w-[16.66vh] text-[1.48vh]">
{{ formatData(subItem["inDateTime"]) }}
</div>
<div class="inline-block align-top w-[16.66vh] text-[1.48vh]">{{ formatData(subItem['InDateTime']) }}</div>
<div class="inline-block align-top w-[16.66vh] text-[1.48vh]">{{ formatData(subItem['AnesStartTime']) }}</div>
<div class="inline-block align-top w-[16.66vh] text-[1.48vh]">{{ formatData(subItem['OperStartTime']) }}</div>
<div class="inline-block align-top w-[11.11vh] text-[1.48vh]" :class="subItem['IsFirstOnTime'] ? 'text-[#349AFC]' : 'text-[#A53FAF]'">
{{ subItem['IsFirstOnTime'] ? '准点' : '不准点' }}
<div class="inline-block align-top w-[16.66vh] text-[1.48vh]">
{{ formatData(subItem["anesStartTime"]) }}
</div>
<div class="inline-block align-top w-[16.66vh] text-[1.48vh]">
{{ formatData(subItem["operStartTime"]) }}
</div>
<div
class="inline-block align-top w-[11.11vh] text-[1.48vh]"
:class="
subItem['IsFirstOnTime']
? 'text-[#349AFC]'
: 'text-[#A53FAF]'
"
>
{{ subItem["IsFirstOnTime"] ? "准点" : "不准点" }}
</div>
</div>
</div>
@ -43,9 +102,9 @@
</template>
<script>
import { Carousel, CarouselItem } from 'element-ui';
import { GetMonitorOperationCount } from '@/api/operation';
import dayjs from 'dayjs';
import { Carousel, CarouselItem } from "element-ui";
import { GetMonitorOperationCount } from "@/api/operation";
import dayjs from "dayjs";
export default {
data() {
return {
@ -55,41 +114,45 @@ export default {
},
methods: {
onGetPageData() {
let nowDay = dayjs().format('YYYY-MM-DD');
let nowDay = dayjs().format("YYYY-MM-DD");
if (this.$store.getters.isMock) {
nowDay = '2024-06-06';
nowDay = "2024-06-06";
}
GetMonitorOperationCount(nowDay).then(res => {
GetMonitorOperationCount(nowDay).then((res) => {
this.scheduList = [];
let group = 0;
for (let i = 0; i < res['data']['length']; i++) {
for (let i = 0; i < res["data"]["length"]; i++) {
group = parseInt(i / 14);
if (this.scheduList[group]) {
this.scheduList[group].push(res['data'][i]);
this.scheduList[group].push(res["data"][i]);
} else {
this.scheduList[group] = [res['data'][i]];
this.scheduList[group] = [res["data"][i]];
}
}
this.isLoading = false;
});
},
formatData(date) {
return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
let txt = "";
if (date) {
txt = dayjs(date).format("YYYY-MM-DD HH:mm:ss");
}
return txt;
},
},
mounted() {
this.onGetPageData();
},
components: {
'el-carousel': Carousel,
'el-carousel-item': CarouselItem,
"el-carousel": Carousel,
"el-carousel-item": CarouselItem,
},
};
</script>
<style lang="scss" scoped>
.bgRightMidBox {
background-image: url('@/assets/svg/Operation/RightMid/Box.svg');
background-image: url("@/assets/svg/Operation/RightMid/Box.svg");
background-size: contain;
background-position: center;
background-repeat: no-repeat;

@ -120,9 +120,16 @@ export default {
if (!res.data) {
return;
}
this.chartOptions["series"][0]["data"][0]["value"] = res["data"][
"firstPunctualityRate"
].slice(0, -1);
let fisrtRate = res["data"]["firstPunctualityRate"];
if (fisrtRate.includes("%")) {
this.chartOptions["series"][0]["data"][0]["value"] = fisrtRate.slice(
0,
-1
);
} else {
this.chartOptions["series"][0]["data"][0]["value"] =
Number(fisrtRate);
}
this.opTotal = res["data"]["roomCount"];
chart.setOption(this.chartOptions);
this.isLoading = false;

@ -5,10 +5,10 @@
</template>
<script>
import * as echarts from 'echarts';
import dayjs from 'dayjs';
import { GetRoomList, GetMonitorRoomUsageRate } from '@/api/room';
import { statusToTxt, textToColor } from '@/utils/common';
import * as echarts from "echarts";
import dayjs from "dayjs";
import { GetRoomList, GetMonitorRoomUsageRate } from "@/api/room";
import { statusToTxt, textToColor } from "@/utils/common";
let chart = null;
export default {
data() {
@ -16,27 +16,27 @@ export default {
isLoding: false,
chartOptions: {
grid: {
width: '86%',
height: '80%',
top: '14%',
width: "86%",
height: "80%",
top: "14%",
},
legend: {
data: [],
selectedMode: 'none',
top: '6%',
right: '4%',
selectedMode: "none",
top: "6%",
right: "4%",
textStyle: {
color: '#fff',
color: "#fff",
fontSize: 14,
fontFamily: 'DIN-Bold,Microsoft YaHei',
fontFamily: "DIN-Bold,Microsoft YaHei",
},
},
xAxis: {
type: 'time',
position: 'top',
type: "time",
position: "top",
splitNumber: 24,
axisLabel: {
color: '#B7BDBF',
color: "#B7BDBF",
fontSize: 12,
margin: 16,
formatter: function (value) {
@ -44,26 +44,32 @@ export default {
var hours = date.getHours();
var minutes = date.getMinutes();
if (hours === 0 && minutes === 0) {
return '00:00';
return "00:00";
} else {
return (hours < 10 ? '0' : '') + hours + ':' + (minutes < 10 ? '0' : '') + minutes;
return (
(hours < 10 ? "0" : "") +
hours +
":" +
(minutes < 10 ? "0" : "") +
minutes
);
}
},
},
},
yAxis: {
type: 'category',
type: "category",
data: [],
axisLabel: {
color: '#B7BDBF',
color: "#B7BDBF",
fontSize: 12,
margin: 16,
fontFamily: 'DIN-Bold,Microsoft YaHei',
fontFamily: "DIN-Bold,Microsoft YaHei",
},
},
series: [],
},
legendDataList: ['入手术间', '手术开始', '手术结束', '出手术间'],
legendDataList: ["入手术间", "手术开始", "手术结束", "出手术间"],
yAxisArr: [],
showPageIndex: -1,
allPageIndex: 0,
@ -77,19 +83,23 @@ export default {
methods: {
initMockData() {
//
const currentDate = dayjs().format('YYYY-MM-DD');
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');
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`;
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')}`);
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) {
@ -97,9 +107,12 @@ export default {
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${isUseArr[j]}:00:00`,
yValue: index - 1,
color: textToColor('出手术间'),
diff: dayjs(`${currentDate} ${isUseArr[j]}:00:00`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '出手术间',
color: textToColor("出手术间"),
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) {
@ -107,18 +120,24 @@ export default {
startTime: `${currentDate} ${isUseArr[j - 1]}:00:00`,
endTime: `${currentDate} ${detailMin}`,
yValue: index - 1,
color: textToColor('手术开始'),
diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '手术开始',
color: textToColor("手术开始"),
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: textToColor('手术结束'),
diff: dayjs(`${currentDate} ${detailMin}`).diff(dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`), 'minute'),
name: '手术结束',
color: textToColor("手术结束"),
diff: dayjs(`${currentDate} ${detailMin}`).diff(
dayjs(`${currentDate} ${isUseArr[j - 1]}:00:00`),
"minute"
),
name: "手术结束",
});
}
} else if (isUseArr[j] > hours && isUseArr[j - 1] == hours) {
@ -126,9 +145,9 @@ export default {
startTime: `${currentDate} ${sevenMinutesAgo}`,
endTime: `${currentDate} ${detailMin}`,
yValue: index - 1,
color: textToColor('入手术间'),
diff: '7',
name: '入手术间',
color: textToColor("入手术间"),
diff: "7",
name: "入手术间",
});
}
}
@ -139,20 +158,22 @@ export default {
chart.setOption(this.chartOptions);
},
onGetPageData() {
let today = dayjs().format('YYYY-MM-DD');
let today = dayjs().format("YYYY-MM-DD");
// today = '2024-06-06';
// today = '2024-08-07';
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.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) {
const res = data.map(function (item) {
return {
type: 'custom',
type: "custom",
name: item.name,
renderItem: function (params, api) {
var xStart = api.coord([item.startTime, item.yValue]);
@ -160,10 +181,10 @@ export default {
var textX = (xStart[0] + xEnd[0]) / 2;
var textY = xStart[1] - 20;
return {
type: 'group',
type: "group",
children: [
{
type: 'line',
type: "line",
shape: {
x1: xStart[0],
y1: xStart[1],
@ -176,13 +197,13 @@ export default {
},
},
{
type: 'text',
type: "text",
position: [textX, textY],
style: {
text: `${item.diff} min`,
fill: '#B7BDBF',
textSize: '12px',
textAlign: 'center',
fill: "#B7BDBF",
textSize: "12px",
textAlign: "center",
},
},
],
@ -204,17 +225,21 @@ export default {
}
const numValues = Math.floor(Math.random() * 3) + 8;
const randomValues = getRandomUniqueValues(8, 24, numValues % 2 ? numValues + 1 : numValues);
const randomValues = getRandomUniqueValues(
8,
24,
numValues % 2 ? numValues + 1 : numValues
);
return randomValues.sort((a, b) => {
return a - b;
});
},
formatLegendData() {
if (this.legendDataList.length) {
this.legendDataList.forEach(item => {
this.legendDataList.forEach((item) => {
this.chartOptions.legend.data.push({
name: item,
icon: 'rect',
icon: "rect",
itemStyle: {
color: textToColor(item),
},
@ -229,23 +254,32 @@ export default {
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();
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']));
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']),
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"]),
});
}
});
@ -260,16 +294,16 @@ export default {
},
},
mounted() {
GetRoomList().then(res => {
res['Data']['Data'].forEach(item => {
if (item['RoomTypeCode'] == 0) {
this.allRoomList.push(item['RoomName']);
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) {
if (this.$store.getters.isMock) {
this.initMockData();
} else {
this.onGetPageData();
@ -281,7 +315,7 @@ export default {
<style>
.bgRightMidBox {
background-image: url('@/assets/svg/Room/RightMid/Box.svg');
background-image: url("@/assets/svg/Room/RightMid/Box.svg");
background-size: contain;
background-position: center;
background-repeat: no-repeat;

Loading…
Cancel
Save