Files
zhxg_pc/src/views/staff/oneStop/room/roomDetailedStatistics.vue

392 lines
14 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">
<!-- 查询条件 -->
<el-card class="box-card">
<el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="120px">
<!-- <el-form-item label="功能房名" prop="roomName">
<el-input v-model="queryParams.roomName" placeholder="请输入功能房名" clearable @keyup.enter.native="handleQuery" />
</el-form-item> -->
<el-form-item label="部门" prop="rtDepar">
<el-select v-model="queryParams.rtDepar" placeholder="请选择部门" filterable clearable multiple @change="handleQuery">
<el-option v-for="item in departmentList" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="预约时间段" prop="rtTime">
<el-date-picker v-model="queryParams.rtTimeRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" @change="handleQuery" />
</el-form-item>
<el-form-item label="参与人员类型" prop="rtRole">
<el-select v-model="queryParams.rtRole" placeholder="请选择参与人员类型" style="width: 100%" @change="handleQuery">
<el-option v-for="dict in dict.type.routine_rtfureservation_rt_role" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="申请人" prop="rtCreatRole">
<el-input v-model="queryParams.rtCreatRole" placeholder="请输入申请人" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="审核状态" prop="auditStatus">
<el-select v-model="queryParams.auditStatus" placeholder="请选择审核状态" @change="handleQuery">
<el-option v-for="item in optionsAudit" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="活动发起人" prop="eventPromoter">
<el-input
v-model="queryParams.eventPromoter"
placeholder="请输入活动发起人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="发起人学工号" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入发起人学号/工号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="fetchData">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 图表和表格 -->
<el-row :gutter="20" class="mt20">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>部门预约统计图</span>
</div>
<div class="chart-container">
<div ref="departmentChart" style="height: 400px" />
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>功能房预约统计图</span>
</div>
<div class="chart-container">
<div ref="roomChart" style="height: 400px" />
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" class="mt20">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>部门预约统计表-预约总次数{{ departmentTotalReservations }}来访总人数{{ departmentTotalVisitors }}</span>
</div>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button v-hasPermi="['staff:room:export']" type="warning" plain icon="el-icon-download" size="mini" @click="handleExportDepartmentUsageList">导出</el-button>
</el-col>
<right-toolbar :show-search.sync="showSearch" @queryTable="getUser" />
</el-row>
<el-table :data="departmentUsageList" border>
<el-table-column prop="department" label="部门" width="180" />
<el-table-column prop="reservation_count" label="预约次数" />
<el-table-column prop="total_visitors" label="来访人数" />
</el-table>
</el-card>
</el-col>
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>功能房预约统计表-预约总次数{{ roomTotalReservations }}来访总人数{{ roomTotalVisitors }}</span>
</div>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExportRoomUsageList">导出</el-button>
</el-col>
<right-toolbar :show-search.sync="showSearch" @queryTable="getUser" />
</el-row>
<el-table :data="roomUsageList" border>
<el-table-column prop="roomName" label="功能房名" width="180" />
<el-table-column prop="reservation_count" label="预约次数" />
<el-table-column prop="total_visitors" label="来访人数" />
</el-table>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { getDepartmentReservationCount, getRoomReservationCount } from '@/api/staff/OneStopRegistrationRecord'
import { getXZJGDept } from '@/api/system/dept'
import * as echarts from 'echarts'
export default {
dicts: ['routine_rtfureservation_rt_role'],
data() {
return {
queryParams: {
auditStatus: null,
startTime: null,
endTime: null,
role: null,
borrower: null,
rtTimeRange: null,
rtDepar: null,
rtRole: null,
rtCreatRole: null,
eventPromoter: null,
userName: null,
},
departmentUsageList: [],
roomUsageList: [],
departmentChart: null,
roomChart: null,
departmentList: [], // 部门名称列表
optionsAudit: [
// 下拉选项数组
{ value: null, label: '全部' },
{ value: 0, label: '待审核' },
{ value: 1, label: '同意' },
{ value: 2, label: '不同意' },
],
// 显示搜索条件
showSearch: true,
}
},
computed: {
departmentTotalReservations() {
return this.departmentUsageList.reduce((sum, item) => sum + (item.reservation_count || 0), 0)
},
departmentTotalVisitors() {
return this.departmentUsageList.reduce((sum, item) => sum + (item.total_visitors || 0), 0)
},
roomTotalReservations() {
return this.roomUsageList.reduce((sum, item) => sum + (item.reservation_count || 0), 0)
},
roomTotalVisitors() {
return this.roomUsageList.reduce((sum, item) => sum + (item.total_visitors || 0), 0)
}
},
created() {
this.fetchDepartments()
this.fetchData()
},
mounted() {
// 移到 mounted 中初始化图表
this.$nextTick(() => {
this.initCharts()
})
},
methods: {
/** 重置按钮操作 */
resetQuery() {
this.queryParams = {
auditStatus: null,
startTime: null,
endTime: null,
role: null,
borrower: null,
rtTimeRange: null,
rtDepar: null,
rtRole: null,
rtCreatRole: null,
eventPromoter: null,
userName: null,
}
this.fetchData()
},
/** 搜索按钮操作 */
handleQuery() {
console.log(this.queryParams)
if (this.queryParams.rtTimeRange && this.queryParams.rtTimeRange.length === 2) {
this.queryParams.startTime = this.queryParams.rtTimeRange[0]
this.queryParams.endTime = this.queryParams.rtTimeRange[1]
} else {
this.queryParams.startTime = null
this.queryParams.startTime = null
}
this.fetchData()
},
// 获取部门名称列表
async fetchDepartments() {
try {
const response = await getXZJGDept()
this.departmentList = response.data || []
} catch (error) {
this.$message.error('获取部门列表失败')
}
},
// 初始化 ECharts
initCharts() {
if (this.$refs.departmentChart && this.$refs.roomChart) {
this.departmentChart = echarts.init(this.$refs.departmentChart)
this.roomChart = echarts.init(this.$refs.roomChart)
}
},
// 获取数据
async fetchData() {
try {
// 处理查询参数
if (this.queryParams.rtTimeRange && this.queryParams.rtTimeRange.length === 2) {
this.queryParams.startTime = this.queryParams.rtTimeRange[0]
this.queryParams.endTime = this.queryParams.rtTimeRange[1]
}
// 将多选的部门数组转换为逗号分隔的字符串
let rtDeparParam = this.queryParams.rtDepar;
if (Array.isArray(this.queryParams.rtDepar) && this.queryParams.rtDepar.length > 0) {
rtDeparParam = this.queryParams.rtDepar.join(',');
}
// 获取各部门预约功能房统计数据
const departmentRes = await getDepartmentReservationCount({
startTime: this.queryParams.startTime,
endTime: this.queryParams.endTime,
role: this.queryParams.rtRole,
borrower: this.queryParams.rtCreatRole,
auditStatus: this.queryParams.auditStatus,
rtDepar: rtDeparParam, // 使用转换后的逗号分隔字符串
eventPromoter: this.queryParams.eventPromoter,
userName: this.queryParams.userName,
})
// 获取各个功能房预约统计数据
const roomRes = await getRoomReservationCount({
startTime: this.queryParams.startTime,
endTime: this.queryParams.endTime,
role: this.queryParams.rtRole,
borrower: this.queryParams.rtCreatRole,
auditStatus: this.queryParams.auditStatus,
rtDepar: rtDeparParam, // 使用转换后的逗号分隔字符串
eventPromoter: this.queryParams.eventPromoter,
userName: this.queryParams.userName,
})
// 等待图表初始化完成后再渲染数据
this.$nextTick(() => {
if (this.departmentChart && this.roomChart) {
// 添加数据检查
const departmentData = departmentRes.data || []
const roomData = roomRes.data || []
this.renderPieChart(this.departmentChart, '各部门预约功能房数量', departmentData)
this.renderPieChart(this.roomChart, '各功能房预约数量', roomData)
}
})
// 更新表格数据
this.departmentUsageList = departmentRes.data || []
this.roomUsageList = roomRes.data || []
} catch (error) {
console.error('获取数据失败:', error)
this.$message.error('获取数据失败')
}
},
// 渲染饼图
renderPieChart(chart, title, data) {
// 添加数据检查
if (!data || !Array.isArray(data)) {
console.warn('数据格式不正确或为空:', data)
data = [] // 设置为空数组,避免报错
}
const option = {
title: {
text: title,
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
},
series: [
{
name: '预约数量',
type: 'pie',
radius: '50%',
center: ['70%', '50%'],
data: data.map(item => ({
name: item.department || item.roomName || '未知',
value: item.reservation_count || 0
})),
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}
// 如果数据为空,显示暂无数据
if (data.length === 0) {
option.title.subtext = '暂无数据'
}
chart.setOption(option)
},
handleExportDepartmentUsageList() {
// 调用下载函数传入选中的ID
this.download('staff/OneStopRegistrationRecord/exportDepartmentReservationCount', {
startTime: this.queryParams.startTime,
endTime: this.queryParams.endTime,
role: this.queryParams.rtRole,
borrower: this.queryParams.rtCreatRole,
auditStatus: this.queryParams.auditStatus,
rtDepar: this.queryParams.rtDepar,
eventPromoter: this.queryParams.eventPromoter,
userName: this.queryParams.userName,}, `各部门预约功能房数量导出表_${new Date().getTime()}.xlsx`)
},
handleExportRoomUsageList() {
// 调用下载函数传入选中的ID
this.download('staff/OneStopRegistrationRecord/exportRoomReservationCount', {
startTime: this.queryParams.startTime,
endTime: this.queryParams.endTime,
role: this.queryParams.rtRole,
borrower: this.queryParams.rtCreatRole,
auditStatus: this.queryParams.auditStatus,
rtDepar: this.queryParams.rtDepar,
eventPromoter: this.queryParams.eventPromoter,
userName: this.queryParams.userName,}, `社区建设数据导出表_${new Date().getTime()}.xlsx`)
},
},
}
</script>
<style scoped>
.chart-container {
background: #fff;
padding: 10px;
border-radius: 5px;
}
.mt20 {
margin-top: 20px;
}
.box-card {
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.clearfix:before,
.clearfix:after {
display: table;
content: '';
}
.clearfix:after {
clear: both;
}
</style>