477 lines
12 KiB
Vue
477 lines
12 KiB
Vue
<template>
|
||
<div class="container">
|
||
<div class="filter-section" style="margin:0 0 20px 0">
|
||
<el-date-picker v-model="dateRange" value-format="YYYY-MM-DD" type="daterange" range-separator="-"
|
||
start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
|
||
<el-button type="primary" @click="handleSearch" style="margin:0 0 0 10px">搜索</el-button>
|
||
<el-button @click="handleReset">重置</el-button>
|
||
</div>
|
||
<div class="top">
|
||
<div class="top-box box1" @click="handlecountMedicine">
|
||
<div class="icon icon1"><img src="../../../../assets/icons/svg/storeroom.png"></div>
|
||
<span class="top-box-count"> {{ countMedicines }} </span>
|
||
<span class="top-box-text"> 库房药品统计</span>
|
||
</div>
|
||
<div class="top-box box2" @click="countAmount">
|
||
<div class="icon icon2"><img src="../../../../assets/icons/svg/drug.png"></div>
|
||
<span class="top-box-count"> {{ countAmounts }} </span>
|
||
<span class="top-box-text"> 药品金额统计</span>
|
||
</div>
|
||
<div class="top-box box3" @click="navigateToDrugFiling('adevnt')">
|
||
<div class="icon icon3"><img src="../../../../assets/icons/svg/advent.png"></div>
|
||
<span class="top-box-count"> {{ countAdvents }} </span>
|
||
<span class="top-box-text"> 临期药品统计 </span>
|
||
</div>
|
||
<div class="top-box box4" @click="navigateToDrugFiling('alerts')">
|
||
<div class="icon icon4"><img src="../../../../assets/icons/svg/warning.png"></div>
|
||
<span class="top-box-count"> {{ countAlertss }} </span>
|
||
<span class="top-box-text"> 库存预警统计 </span>
|
||
</div>
|
||
</div>
|
||
<div class="bottom">
|
||
<!-- 接诊统计 Reception statistics -->
|
||
<div class="bottom-left reception_div"></div>
|
||
<!-- 接诊统计 Reception Rotundity -->
|
||
<div class="bottom-right reception_rotundity"></div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup name="medicalChar">
|
||
import { ref, reactive, toRefs, onMounted, onBeforeMount } from "vue";
|
||
import { getCountMedicine } from "@/api/healthcare/charMedicine/charMedicine.js";
|
||
import route from "@/router";
|
||
|
||
const data = reactive({
|
||
queryParams: {},
|
||
});
|
||
|
||
const { queryParams } = toRefs(data);
|
||
const dateRange = ref([]);
|
||
|
||
onMounted(() => {
|
||
countMedicine();
|
||
});
|
||
|
||
function handleSearch() {
|
||
countMedicine();
|
||
}
|
||
|
||
// 重置 方法
|
||
function handleReset() {
|
||
dateRange.value = [];
|
||
queryParams.value.startDate = null;
|
||
queryParams.value.endDate = null;
|
||
countMedicine();
|
||
}
|
||
|
||
const countMedicines = ref(0); // 库房药品统计
|
||
const countAmounts = ref(0); // 药品金额统计
|
||
const countAdvents = ref(0); // 临期药品统计
|
||
const countAlertss = ref(0); // 库存预警统计
|
||
|
||
function countMedicine() {
|
||
if (dateRange.value && dateRange.value.length === 2) {
|
||
queryParams.value.startDate = dateRange.value[0];
|
||
queryParams.value.endDate = dateRange.value[1];
|
||
//
|
||
const paramsTime = {};
|
||
paramsTime.params = {};
|
||
// 赋值 startTime 和 endTime 为 Date 对象
|
||
paramsTime.params["startTime"] = dateRange.value[0];
|
||
paramsTime.params["endTime"] = dateRange.value[1];
|
||
// 使用
|
||
tackleData(paramsTime);
|
||
}
|
||
|
||
getCountMedicine(queryParams.value)
|
||
.then((response) => {
|
||
countMedicines.value = response.data.countMedicine; // 库房药品统计
|
||
countAmounts.value = response.data.countAmount; // 药品金额统计
|
||
countAdvents.value = response.data.countAdvent; // 临期药品统计
|
||
countAlertss.value = response.data.countAlerts; // 库存预警统计
|
||
})
|
||
.catch((error) => {
|
||
console.error("获取药品数量统计失败", error);
|
||
});
|
||
}
|
||
|
||
function handlecountMedicine() {
|
||
console.log("库房药品统计总和");
|
||
route.push({ name: "DrugFiling" });
|
||
}
|
||
|
||
const params = ref({});
|
||
import { useRouter } from "vue-router";
|
||
const router = useRouter();
|
||
function navigateToDrugFiling(type) {
|
||
router.push(`inventory/DrugFiling?type=${type}`);
|
||
}
|
||
|
||
//
|
||
import * as echarts from "echarts/core";
|
||
import {
|
||
DatasetComponent,
|
||
TitleComponent,
|
||
TooltipComponent,
|
||
GridComponent,
|
||
LegendComponent,
|
||
} from "echarts/components";
|
||
import { BarChart } from "echarts/charts";
|
||
import { CanvasRenderer } from "echarts/renderers";
|
||
import { PieChart } from "echarts/charts";
|
||
import { LabelLayout } from "echarts/features";
|
||
|
||
echarts.use([
|
||
DatasetComponent,
|
||
TitleComponent,
|
||
TooltipComponent,
|
||
GridComponent,
|
||
LegendComponent,
|
||
BarChart,
|
||
CanvasRenderer,
|
||
PieChart,
|
||
LabelLayout,
|
||
]);
|
||
|
||
const receptionRef = ref(null);
|
||
|
||
//
|
||
import {
|
||
gainPatientDiagnosisListXml,
|
||
obtainSymptomStatisticsNumber,
|
||
obtainSymptomStatisticsNumberMonth,
|
||
} from "@/api/healthcare/outpatientService/patientDiagnosis";
|
||
|
||
// 钩子
|
||
onBeforeMount(() => {
|
||
//
|
||
console.log("组件即将挂载到 DOM");
|
||
//
|
||
// 获取当前时间
|
||
let currentDate = new Date();
|
||
|
||
// 格式化当前日期
|
||
const year = currentDate.getFullYear();
|
||
const month = `0${currentDate.getMonth() + 1}`.slice(-2); // 月份从0开始,需要加1
|
||
const day = `0${currentDate.getDate()}`.slice(-2);
|
||
|
||
// 创建一年前的日期
|
||
let oneYearAgo = new Date(currentDate);
|
||
oneYearAgo.setFullYear(currentDate.getFullYear() - 1);
|
||
|
||
// 打印一年前的日期(ISO 格式)
|
||
console.log("一年前的日期:", oneYearAgo.toISOString());
|
||
|
||
// 打印当前日期和格式化后的日期
|
||
console.log("时间:", currentDate, `${year}-${month}-${day}`);
|
||
console.log("一年前的日期", oneYearAgo, "现在", currentDate);
|
||
|
||
// 格式化一年前的日期
|
||
const formattedOneYearAgo = `${oneYearAgo.getFullYear()}-${`0${oneYearAgo.getMonth() + 1
|
||
}`.slice(-2)}-${`0${oneYearAgo.getDate()}`.slice(-2)}`;
|
||
|
||
// 格式化当前日期
|
||
const formattedCurrentDate = `${year}-${month}-${day}`;
|
||
|
||
// 初始化查询参数对象
|
||
const paramsTime = {};
|
||
paramsTime.params = {};
|
||
|
||
// 赋值 startTime 和 endTime 为 Date 对象
|
||
paramsTime.params["startTime"] = formattedOneYearAgo;
|
||
paramsTime.params["endTime"] = formattedCurrentDate;
|
||
// 使用
|
||
tackleData(paramsTime);
|
||
});
|
||
|
||
// 数据更新后
|
||
onUpdated(() => {
|
||
console.log("数据已更新");
|
||
//
|
||
});
|
||
|
||
// 进行 数据 处理 tackle
|
||
function tackleData(queryParamsData) {
|
||
//
|
||
// 获取 对象 类型
|
||
obtainSymptomStatisticsNumber(queryParamsData).then((response) => {
|
||
console.log("获取 患者 诊断 列表", response);
|
||
// 处理数据
|
||
const symptomNameList = ref([]);
|
||
for (let i = 0; i < response.rows.length; i++) {
|
||
symptomNameList.value.push({
|
||
//
|
||
name: response.rows[i].symptomName,
|
||
//
|
||
value: response.rows[i].number,
|
||
});
|
||
//
|
||
}
|
||
//
|
||
myChart_div_rotundity.value.setOption({
|
||
legend: {
|
||
data: symptomNameList.value,
|
||
},
|
||
series: [
|
||
{
|
||
data: symptomNameList.value,
|
||
},
|
||
],
|
||
});
|
||
});
|
||
// let symptomList = ref([]);
|
||
obtainSymptomStatisticsNumberMonth(queryParamsData).then((response) => {
|
||
console.log("获取 患者 诊断 列表", response);
|
||
let symptomList = ref([]);
|
||
let seriesList = ref([]);
|
||
symptomList.value.push(["类型"]);
|
||
//
|
||
for (let h = 0; h < response.rows[0].length; h++) {
|
||
symptomList.value[0].push(response.rows[0][h].symptomName);
|
||
seriesList.value.push({ type: "bar" });
|
||
}
|
||
for (let i = 0; i < response.rows.length; i++) {
|
||
//
|
||
symptomList.value.push([`${response.rows[i][0].month}月`]);
|
||
// 添加 统计 的 名字
|
||
for (let j = 0; j < response.rows[i].length; j++) {
|
||
symptomList.value[i + 1].push(response.rows[i][j].number);
|
||
}
|
||
}
|
||
//
|
||
console.log("统计 的 名字 数据:", symptomList.value, seriesList.value);
|
||
//
|
||
myChart_div.value.setOption({
|
||
dataset: {
|
||
source: symptomList.value,
|
||
},
|
||
series: seriesList.value,
|
||
});
|
||
});
|
||
}
|
||
|
||
//
|
||
let myChart_div_rotundity = ref(null);
|
||
//
|
||
let myChart_div = ref(null);
|
||
|
||
// 组件挂载
|
||
onMounted(() => {
|
||
//
|
||
// 此时 DOM 元素已渲染,可以安全地访问 myDiv.value
|
||
console.log("组件已挂载,DOM 元素已渲染", receptionRef.value);
|
||
var div_01 = document.getElementsByClassName("reception_div");
|
||
let myChart01 = document.querySelector(".reception_div");
|
||
myChart_div.value = echarts.init(document.querySelector(".reception_div"));
|
||
console.log("ECharts入门示例:", div_01, receptionRef.value, myChart01, myChart_div);
|
||
// var myChart = echarts.init(receptionRef.value);
|
||
// 指定图表的配置项和数据
|
||
let option = {
|
||
legend: {},
|
||
tooltip: {},
|
||
dataset: {
|
||
source: [],
|
||
},
|
||
xAxis: { type: "category" },
|
||
yAxis: {},
|
||
series: [],
|
||
};
|
||
//
|
||
myChart_div.value.setOption(option);
|
||
|
||
// 接诊统计 圆形
|
||
myChart_div_rotundity.value = echarts.init(
|
||
document.querySelector(".reception_rotundity")
|
||
);
|
||
//
|
||
let option_rotundity = {
|
||
title: {
|
||
text: "接诊统计",
|
||
left: "center",
|
||
},
|
||
tooltip: {
|
||
trigger: "item",
|
||
formatter: "{a} <br/>{b} : {c} ({d}%)",
|
||
},
|
||
legend: {
|
||
type: "scroll",
|
||
orient: "vertical",
|
||
right: 10,
|
||
top: 20,
|
||
bottom: 20,
|
||
data: [],
|
||
},
|
||
series: [
|
||
{
|
||
name: "姓名",
|
||
type: "pie",
|
||
radius: "55%",
|
||
center: ["40%", "50%"],
|
||
data: [],
|
||
emphasis: {
|
||
itemStyle: {
|
||
shadowBlur: 10,
|
||
shadowOffsetX: 0,
|
||
shadowColor: "rgba(0, 0, 0, 0.5)",
|
||
},
|
||
},
|
||
},
|
||
],
|
||
};
|
||
|
||
//
|
||
myChart_div_rotundity.value.setOption(option_rotundity);
|
||
});
|
||
</script>
|
||
|
||
<style scoped>
|
||
.chart {
|
||
width: 100%;
|
||
height: 400px;
|
||
}
|
||
|
||
.container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 90vh;
|
||
padding: 20px;
|
||
/* 添加内边距以确保顶部和底部区域之间的间距 */
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.top {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 15px;
|
||
/* 盒子之间的间距 */
|
||
width: 100%;
|
||
height: 150px;
|
||
margin-bottom: 30px;
|
||
/* 顶部和底部区域之间的间距 */
|
||
|
||
.top-box {
|
||
width: calc(25% - 11.25px);
|
||
/* 25% - (3 * 15px / 4) */
|
||
height: 100%;
|
||
box-shadow: 0 4px 8px rgba(0.3, 0.3, 0.3, 0.3);
|
||
/* 添加阴影 */
|
||
border-radius: 10px;
|
||
/* 圆角 5px */
|
||
display: flex;
|
||
color: rgb(255, 255, 255);
|
||
/* 文字颜色 */
|
||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||
/* 平滑过渡效果 */
|
||
cursor: pointer;
|
||
/* 鼠标指针变为手指形状 */
|
||
background-color: white;
|
||
position: relative;
|
||
}
|
||
|
||
.top-box:hover {
|
||
transform: scale(1.01);
|
||
/* 鼠标悬停时向外突出 5% */
|
||
box-shadow: 0 6px 12px rgba(0.3, 0.3, 0.3, 0.5);
|
||
/* 加强阴影效果 */
|
||
}
|
||
|
||
/* 4小个盒子 */
|
||
.box1 {
|
||
background-color: #FF9A00;
|
||
}
|
||
|
||
.box2 {
|
||
background-color: #4DB4FF;
|
||
}
|
||
|
||
.box3 {
|
||
background-color: #F96464;
|
||
}
|
||
|
||
.box4 {
|
||
background-color: #965AFF;
|
||
}
|
||
|
||
/* 图标 */
|
||
.icon {
|
||
width: 170px;
|
||
height: 150px;
|
||
border-radius: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 6px 12px rgba(0.1, 0.1, 0.1, 0.1);
|
||
}
|
||
|
||
.icon1 {
|
||
background: linear-gradient(90deg, #FF9900, #FFAE00);
|
||
}
|
||
|
||
.icon2 {
|
||
background: linear-gradient(90deg, #0195FF, #53BFFD);
|
||
}
|
||
|
||
.icon3 {
|
||
background: linear-gradient(90deg, #F66B6D, #F68080);
|
||
}
|
||
|
||
.icon4 {
|
||
background: linear-gradient(90deg, #673FFF, #A25DFF);
|
||
}
|
||
|
||
.top-box-text {
|
||
position: absolute;
|
||
height: 70px;
|
||
bottom: 0;
|
||
left: 180px;
|
||
font-size: 30px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.top-box-count {
|
||
position: absolute;
|
||
height: 130px;
|
||
bottom: 0;
|
||
left: 180px;
|
||
font-size: 50px;
|
||
}
|
||
}
|
||
|
||
.bottom {
|
||
display: flex;
|
||
flex: 1;
|
||
gap: 30px;
|
||
/* 两个底部区域之间的间距 */
|
||
}
|
||
|
||
.bottom-left {
|
||
width: 65%;
|
||
height: 100%;
|
||
background-color: white;
|
||
box-shadow: 0 4px 8px rgba(0.3, 0.3, 0.3, 0.3);
|
||
/* 添加阴影 */
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: black;
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.bottom-right {
|
||
width: 35%;
|
||
/* 调整为 35% 以确保总宽度为 100% */
|
||
height: 100%;
|
||
background-color: white;
|
||
box-shadow: 0 4px 8px rgba(0.3, 0.3, 0.3, 0.3);
|
||
/* 添加阴影 */
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: black;
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
}
|
||
</style>
|