fix: 功能优化,体温统计代码提交。

This commit is contained in:
tianyongbao
2024-10-16 13:04:34 +08:00
parent b430b2288c
commit ffcaf485f5
2 changed files with 611 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
import request from '@/utils/request'
export function getMarAnalysis(query) {
return request({
url: '/health/analysis/marAnalysis',
method: 'get',
params: query
})
}
export function getTemperatureAnalysis(query) {
return request({
url: '/health/analysis/temperatureAnalysis',
method: 'get',
params: query
})
}

View File

@@ -0,0 +1,594 @@
<template>
<div class="app-container">
<div class="search-con">
<div class="title">查询条件</div>
<el-form :model="queryParams" ref="queryRef" :inline="true" :rules="rules" label-width="100px">
<el-form-item label="人员姓名" prop="id">
<el-select v-model="queryParams.id" placeholder="请选择人员姓名" @change="handlePersonChange">
<el-option v-for="person in personList" :key="person.id" :label="person.name" :value="person.id" />
</el-select>
</el-form-item>
<el-form-item label="健康档案" prop="recordId">
<el-select v-model="queryParams.recordId" placeholder="请选择健康档案" @change="handleRecordChange">
<el-option v-for="health in healthRecordList" :key="health.id" :label="health.name" :value="health.id" />
</el-select>
</el-form-item>
<el-form-item label="测量日期" prop="time" v-if="queryParams.type === 1">
<el-date-picker
v-model="queryParams.time"
type="daterange"
range-separator="~"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD"
@calendar-change="calendarChange"
/>
</el-form-item>
<el-form-item label="" prop="time" v-if="queryParams.type === 2">
<el-date-picker
v-model="queryParams.time"
type="monthrange"
range-separator="~"
format="YYYY-MM"
start-placeholder="开始时间"
end-placeholder="结束时间"
:disabled-date="disabledDateFun"
@calendar-change="calendarChange"
/>
</el-form-item>
<el-form-item label="" prop="time" v-if="queryParams.type === 3">
<yearPicker
v-model="queryParams.time"
ref="statisticPicker"
labelText="选择年份"
:initYear="dateValue"
:showYear="showYearValue"
:maxLength="5"
sp="~"
@updateTimeRange="updateStatisticYear"
/>
</el-form-item>
</el-form>
<div class="search-btn-con">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button type="info" icon="Refresh" @click="resetQuery">重置</el-button>
</div>
</div>
<div class="main-con" style="height: calc(100% - 1.45rem)">
<div class="summary-con" style="height: 115px">
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">测量次数</div>
<div>
<span class="num">{{ temp.totalCount }}</span
><span class="unit"> </span>
</div>
</div>
</div>
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">最高体温</div>
<div>
<span class="num">{{ temp.maxTemp }}</span
><span class="unit"> </span>
</div>
</div>
</div>
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">最低体温</div>
<div>
<span class="num">{{ temp.minTemp }}</span
><span class="unit"> </span>
</div>
</div>
</div>
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">平均体温</div>
<div>
<span class="num">{{ temp.averageTemp }}</span> <span class="unit"> </span>
</div>
</div>
</div>
</div>
<div class="summary-con" v-hasPermi="['invest:posmachine:list']" style="height: 115px">
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">正常次数</div>
<div>
<span class="num">{{ temp.normalTempCount }}</span> <span class="unit">(小于36.9)</span>
</div>
</div>
</div>
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">低烧次数</div>
<div>
<span class="num">{{ temp.lowerTempCount }}</span> <span class="unit">(36.9~37.5)</span>
</div>
</div>
</div>
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">中烧次数</div>
<div>
<span class="num">{{ temp.middleTempCount }}</span> <span class="unit">(37.5~38.5)</span>
</div>
</div>
</div>
<div class="right-con">
<div class="img">
<img src="@/assets/images/average.png" alt="" />
</div>
<div class="item-wrap">
<div class="title">高烧次数</div>
<div>
<span class="num">{{ temp.higherTempCount }}</span> <span class="unit">大于38.5</span>
</div>
</div>
</div>
</div>
<div class="title-con" style="margin-top: 18px">
<div class="title">体温统计</div>
<div class="operate-btn-con">
<el-radio-group v-model="radioVal" @change="handleRadioChange">
<el-radio-button label="柱状图" />
<el-radio-button label="折线图" />
<el-radio-button label="表格" />
</el-radio-group>
</div>
</div>
<div class="content-con">
<div v-show="radioVal === '柱状图'" class="chart" id="chartBar" style="height: calc(100% - 225px); margin-top: -10px"></div>
<div v-show="radioVal === '折线图'" class="chart" id="chartLine" style="height: calc(100% - 225px); margin-top: -10px"></div>
<el-table v-show="radioVal === '表格'" v-loading="loading" :data="temp.tableList" height="calc(100% - 245px)">
<el-table-column label="序号" width="50" type="index" align="center">
<template #default="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column label="测量日期" align="center" prop="time" />
<el-table-column label="测量次数" align="center" prop="count" />
<el-table-column label="最高体温(℃)" align="center" prop="max" />
<el-table-column label="最低体温(℃)" align="center" prop="min" />
<el-table-column label="平均体温(℃" align="center" prop="average" />
<el-table-column prop="detail" label="测量明细" v-if="queryParams.type === 1">
<template #default="scope">
<span v-html="formatMultiLineData(scope.row.detail)"></span>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script setup name="CreditAnalysis">
import dayjs from 'dayjs'
import * as echarts from 'echarts'
import { ElMessage } from 'element-plus'
import yearPicker from '@/components/YearPicker/index.vue'
import { getTemperatureAnalysis } from '@/api/health/statisticAnalysis'
import { listPerson, getPerson } from '@/api/health/person'
import { listHealthRecord } from '@/api/health/healthRecord'
const { proxy } = getCurrentInstance()
const { deal_type, account_type, deal_category } = proxy.useDict('deal_type', 'account_type', 'deal_category')
const personList = ref([])
const healthRecordList = ref([])
const dateValue = ref({ startYear: 2000, endYear: new Date().getFullYear() })
const showYearValue = ref({ startShowYear: '', endShowYear: '' })
const updateStatisticYear = (startYear, endYear) => {
queryParams.value.time = [new Date(startYear, 0, 1), new Date(endYear, 0, 1)]
if (endYear - startYear > 5) {
ElMessage.warning('时间跨度不能大于5年默认选择开始日期的5年')
queryParams.value.time = [new Date(startYear, 0, 1), new Date(startYear + 5, 0, 1)]
}
}
const dates = [{ value: 1, label: '日' }]
const accountsList = ref([])
const loading = ref(true)
const total = ref(0)
const radioVal = ref('柱状图')
const dateValidate = (rules, value, callback) => {
const dateType = rules.dateType || 'days'
const num = rules.num || 31
const dateString = rules.dateString || '天'
const message = rules.message || `时间跨度不能超过${num}${dateString}`
if (value && value.length === 2) {
const start = value[0]
const end = value[1]
if (dayjs(end).diff(dayjs(start), dateType) > num) {
queryParams.value.time = [start, dayjs(start).add(23, 'months')]
ElMessage.warning(message)
}
}
}
const data = reactive({
queryParams: {
type: 1,
time: null,
id: null,
dataType: '1',
dealType: null,
dealCategory: null
},
queryPersonParams: {
pageNum: 1,
pageSize: 1000
},
queryHealthRecordParams: {
pageNum: 1,
personId: null,
state: '1',
pageSize: 1000
},
rules: {
time: [{ validator: dateValidate, dateType: 'months', num: 23, dateRange: '月', message: '时间跨度不能大于24个月默认选择开始日期的24个月' }]
}
})
const { queryParams, rules, queryPersonParams, queryHealthRecordParams } = toRefs(data)
const handleRecordChange = (recordId) => {
queryParams.value.recordId = recordId
getList()
}
const handlePersonChange = (personId) => {
queryHealthRecordParams.personId = personId
listHealthRecord(queryHealthRecordParams).then((response) => {
healthRecordList.value = response.rows
if (response.rows.length > 0) {
queryParams.value.recordId = response.rows[0].id
getList()
}
})
}
/** 查询成员管理列表 */
function getPersonList() {
listPerson(queryPersonParams.value).then((response) => {
personList.value = response.rows
if (response.rows.length > 0) {
queryParams.value.id = response.rows[0].id
queryHealthRecordParams.personId = response.rows[0].id
listHealthRecord(queryHealthRecordParams).then((res) => {
healthRecordList.value = res.rows
if (res.rows.length > 0) {
queryParams.value.recordId = res.rows[0].id
getList()
}
})
}
})
}
const today = new Date()
const end = today.getFullYear() + '-' + ('0' + (today.getMonth() + 1)).slice(-2) + '-' + ('0' + today.getDate()).slice(-2)
const start = dayjs(end).add(-60, 'day')
queryParams.value.time = [start, end]
const handleTimeChange = (type) => {
queryParams.value.time = null
if (type === 1) {
const today = new Date()
const end = today.getFullYear() + '-' + ('0' + (today.getMonth() + 1)).slice(-2) + '-' + ('0' + today.getDate()).slice(-2)
const start = dayjs(end).add(-60, 'day')
queryParams.value.time = [start, end]
} else if (type === 2) {
const today = new Date()
const end = today.getFullYear() + '-' + ('0' + (today.getMonth() + 1)).slice(-2)
const start = dayjs(end).add(-11, 'months')
queryParams.value.time = [start, end]
} else if (type === 3) {
const today = new Date()
const endYear = today.getFullYear()
queryParams.value.time = [new Date(endYear - 2, 0, 1), new Date(endYear, 0, 1)]
showYearValue.value = { startShowYear: endYear - 2, endShowYear: endYear }
}
getList()
}
function formatMultiLineData(data) {
if (data != null) {
return data.replace(/<br\/>/g, '<br/>')
}
}
const disabledDateFun = (time) => {
const arr = [0, 30, 365, 365 * 5]
const days = arr[queryParams.value.type]
if (firstChooseDate.value) {
const one = days * 24 * 3600 * 1000
const minTime = firstChooseDate.value - one
const maxTime = firstChooseDate.value + one
const startTime = minTime
const endTime = maxTime > Date.now() - 8.64e7 ? Date.now() - 8.64e7 : maxTime
return time.getTime() > endTime || time.getTime() < startTime
} else {
return time.getTime() > Date.now() - 8.64e7
}
}
const firstChooseDate = ref('')
const calendarChange = (val) => {
firstChooseDate.value = val[0].getTime()
if (val[1]) firstChooseDate.value = ''
}
const temp = ref({})
const chartData = ref({
name: [],
value1: []
})
function getList() {
loading.value = true
chartData.value = { name: [], value1: [] }
const { type, time, id, recordId } = queryParams.value
let formatValue = 'YYYY-MM-DD'
if (type === 1) {
formatValue = 'YYYY-MM-DD'
} else if (type === 2) {
formatValue = 'YYYY-MM'
} else {
formatValue = 'YYYY'
}
const params = {
type,
startTime: time && time.length > 0 ? dayjs(time[0]).format(formatValue) : '',
endTime: time && time.length > 0 ? dayjs(time[1]).format(formatValue) : '',
id,
recordId
}
getTemperatureAnalysis(params).then((response) => {
loading.value = false
temp.value = { ...response.data }
temp.value.temperatureList.map((item) => {
return {
name: item.time,
value: item.value
}
})
response.data.temperatureList.map((item) => {
chartData.value.name.push(item.time)
chartData.value.value1.push(item.value)
})
handleRadioChange(currentType.value)
})
}
function handleQuery() {
getList()
}
function resetQuery() {
proxy.resetForm('queryRef')
queryParams.value.id = null
const today = new Date()
const end = today.getFullYear() + '-' + ('0' + (today.getMonth() + 1)).slice(-2) + '-' + ('0' + today.getDate()).slice(-2)
const start = dayjs(end).add(-60, 'day')
queryParams.value.time = [start, end]
total.value = 0
getPersonList()
}
const drawBar = (data) => {
if (document.getElementById('chartBar') === null) {
return
}
echarts.dispose(document.getElementById('chartBar'))
const myChart = echarts.init(document.getElementById('chartBar'))
const option = {
legend: {
// 图示例样式
show: true,
top: 50,
right: 50,
itemGap: 20
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
return params[0].name + '<br>' + '体温:' + params[0].value + '℃'
}
},
grid: {
left: '5%',
right: '5%',
bottom: '5%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: data.name,
axisTick: {
alignWithLabel: true // 刻度线是否与标签对齐默认false
},
// 设置 X 轴线条粗细
axisLine: {
lineStyle: {
width: 1, // 根据需求调整数值大小,单位是像素
color: '#999'
}
}
}
],
yAxis: [
{
type: 'value',
min: 35.5, // 设置 y 轴的最小值为 0
max: 40.5, // 设置 y 轴的最大值为 100
interval: 0.5, //设置y轴刻度间隔
axisTick: {
show: true // 默认为true如果要隐藏则改为 false
},
axisLine: {
show: true,
lineStyle: {
width: 1,
color: '#999'
}
}
}
],
series: [
{
data: data.value1,
type: 'bar',
barWidth: 10, // 根据需求调整数值大小,单位是像素
itemStyle: {
color: '#2283cf'
}
}
],
// 添加点击事件的处理函数
emphasis: {
itemStyle: {
color: '#2283cf',
barWidth: 20 // 根据需求调整数值大小,单位是像素
},
barWidth: 24 // 根据需求调整数值大小,单位是像素
}
}
myChart.setOption(option)
}
const drawLine = (data) => {
if (document.getElementById('chartLine') === null) {
return
}
echarts.dispose(document.getElementById('chartLine'))
const myChart = echarts.init(document.getElementById('chartLine'))
const option = {
grid: {
left: '5%',
right: '5%',
bottom: '5%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
return params[0].name + '<br>' + '体温:' + params[0].value + '℃'
}
},
xAxis: {
type: 'category',
data: data.name,
axisTick: {
alignWithLabel: true
},
axisLine: {
lineStyle: {
width: 1,
color: '#999'
}
}
},
yAxis: {
type: 'value',
min: 35.5, // 设置 y 轴的最小值为 0
max: 40.5, // 设置 y 轴的最大值为 100
interval: 0.5, //设置y轴刻度间隔
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
width: 1,
color: '#999'
}
}
},
series: [
{
data: data.value1,
type: 'line',
lineStyle: {
color: '#4181c9'
},
itemStyle: {
color: '#4181c9'
},
smooth: true,
symbol: 'emptyCircle',
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(65,129,201, 0.70)'
},
{
offset: 1,
color: 'rgba(65,129,201, 0.10)'
}
],
false
),
shadowColor: 'rgba(65,129,201, 0.10)',
shadowBlur: 10
}
}
]
}
myChart.setOption(option)
}
const currentType = ref('柱状图')
const handleRadioChange = (type) => {
currentType.value = type
switch (type) {
case '柱状图':
drawBar(chartData.value)
break
case '折线图':
drawLine(chartData.value)
break
default:
break
}
}
getPersonList()
</script>