Files
intc-vue3/src/views/health/milkPowderStatistic/index.vue

593 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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="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">{{ milkPowder.milkPowderStatistic.todayCount }}</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">{{ milkPowder.milkPowderStatistic.todayConsumption }}</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">{{ milkPowder.milkPowderStatistic.todayPerConsumption }}</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">近7日吃奶量</div>
<div>
<span class="num">{{ milkPowder.milkPowderStatistic.sevenDayConsumption }}</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">近7日日平均吃奶量</div>
<div>
<span class="num">{{ milkPowder.milkPowderStatistic.sevenDayPerConsumption }}</span
><span class="unit">毫升</span>
</div>
</div>
</div>
</div>
<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">近1月吃奶量</div>
<div>
<span class="num">{{ milkPowder.milkPowderStatistic.oneMonthConsumption }}</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">近3月吃奶量</div>
<div>
<span class="num">{{ milkPowder.milkPowderStatistic.threeMonthConsumption }}</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">近6月吃奶量</div>
<div>
<span class="num">{{ milkPowder.milkPowderStatistic.sixMonthConsumption }}</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">近1年吃奶量</div>
<div>
<span class="num">{{ milkPowder.milkPowderStatistic.oneYearConsumption }}</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">{{ milkPowder.milkPowderStatistic.totalConsumption }}</span> <span class="unit">毫升</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="milkPowder.milkPowderTableList" 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="value" />
</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 { getMilkPowderAnalysis } from '@/api/health/statisticAnalysis'
import { listPerson } from '@/api/health/person'
import { listHealthRecord } from '@/api/health/healthRecord'
const { proxy } = getCurrentInstance()
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
},
rules: {
time: [{ validator: dateValidate, dateType: 'months', num: 23, dateRange: '月', message: '时间跨度不能大于24个月默认选择开始日期的24个月' }]
}
})
const { queryParams, rules, queryPersonParams } = toRefs(data)
/** 查询成员管理列表 */
function getPersonList() {
listPerson(queryPersonParams.value).then((response) => {
personList.value = response.rows
if (response.rows.length > 0) {
queryParams.value.id = response.rows[0].id
getList()
}
})
}
const handlePersonChange = (personId) => {
queryParams.value.id = personId
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(-30, '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(-30, '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 milkPowder = ref({})
const chartData = ref({
name: [],
value1: []
})
function getList() {
loading.value = true
chartData.value = { name: [], value1: [] }
const { type, time, id } = 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
}
getMilkPowderAnalysis(params).then((response) => {
loading.value = false
milkPowder.value = { ...response.data }
response.data.milkPowderList.map((item) => {
return {
name: item.time,
value: item.value
}
})
response.data.milkPowderList.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(-30, '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: 1, // 设置 y 轴的最小值为 0
// max: 16, // 设置 y 轴的最大值为 100
// interval: 1, //设置y轴刻度间隔
axisTick: {
show: true // 默认为true如果要隐藏则改为 false
},
axisLine: {
show: true,
lineStyle: {
width: 1,
color: '#999'
}
}
}
],
series: [
{
data: data.value1,
type: 'bar',
barWidth: 10, // 根据需求调整数值大小,单位是像素
itemStyle: {
// 此处可以是一个固定颜色值,也可以是一个回调函数根据数据动态计算颜色
color: function (params) {
// 这里可以根据需要设置不同的颜色,比如根据数据值
return '#2283cf' // 数据在50到99之间为蓝色
}
}
}
],
// 添加点击事件的处理函数
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: 1, // 设置 y 轴的最小值为 0
// max: 16, // 设置 y 轴的最大值为 100
// interval: 1, //设置y轴刻度间隔
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
width: 1,
color: '#999'
}
}
},
series: [
{
data: data.value1,
type: 'line',
lineStyle: {
color: '#4181c9'
},
itemStyle: {
// 此处可以是一个固定颜色值,也可以是一个回调函数根据数据动态计算颜色
color: function (params) {
// 这里可以根据需要设置不同的颜色,比如根据数据值
return '#2283cf' // 数据在50到99之间为蓝色
}
},
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>