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

392 lines
14 KiB
Vue
Raw Normal View History

2025-07-28 15:52:07 +08:00
<template>
<div class="app-container">
<!-- 查询条件 -->
<el-card class="box-card">
2025-10-18 17:13:04 +08:00
<el-form v-show="showSearch" ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="120px">
2025-07-28 15:52:07 +08:00
<!-- <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">
2025-07-28 15:52:07 +08:00
<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">
2025-10-18 17:13:04 +08:00
<el-option v-for="dict in dict.type.routine_rtfureservation_rt_role" :key="dict.value" :label="dict.label" :value="dict.value" />
2025-07-28 15:52:07 +08:00
</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">
2025-10-18 17:13:04 +08:00
<el-option v-for="item in optionsAudit" :key="item.value" :label="item.label" :value="item.value" />
2025-07-28 15:52:07 +08:00
</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">
2025-10-18 17:13:04 +08:00
<div ref="departmentChart" style="height: 400px" />
2025-07-28 15:52:07 +08:00
</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">
2025-10-18 17:13:04 +08:00
<div ref="roomChart" style="height: 400px" />
2025-07-28 15:52:07 +08:00
</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>
2025-07-28 15:52:07 +08:00
</el-col>
2025-10-18 17:13:04 +08:00
<right-toolbar :show-search.sync="showSearch" @queryTable="getUser" />
2025-07-28 15:52:07 +08:00
</el-row>
<el-table :data="departmentUsageList" border>
2025-10-18 17:13:04 +08:00
<el-table-column prop="department" label="部门" width="180" />
<el-table-column prop="reservation_count" label="预约次数" />
<el-table-column prop="total_visitors" label="来访人数" />
2025-07-28 15:52:07 +08:00
</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>
2025-10-18 17:13:04 +08:00
<right-toolbar :show-search.sync="showSearch" @queryTable="getUser" />
2025-07-28 15:52:07 +08:00
</el-row>
<el-table :data="roomUsageList" border>
2025-10-18 17:13:04 +08:00
<el-table-column prop="roomName" label="功能房名" width="180" />
<el-table-column prop="reservation_count" label="预约次数" />
<el-table-column prop="total_visitors" label="来访人数" />
2025-07-28 15:52:07 +08:00
</el-table>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
2025-10-18 17:13:04 +08:00
import { getDepartmentReservationCount, getRoomReservationCount } from '@/api/staff/OneStopRegistrationRecord'
import { getXZJGDept } from '@/api/system/dept'
import * as echarts from 'echarts'
2025-07-28 15:52:07 +08:00
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() {
2025-10-18 17:13:04 +08:00
return this.departmentUsageList.reduce((sum, item) => sum + (item.reservation_count || 0), 0)
2025-07-28 15:52:07 +08:00
},
departmentTotalVisitors() {
2025-10-18 17:13:04 +08:00
return this.departmentUsageList.reduce((sum, item) => sum + (item.total_visitors || 0), 0)
2025-07-28 15:52:07 +08:00
},
roomTotalReservations() {
2025-10-18 17:13:04 +08:00
return this.roomUsageList.reduce((sum, item) => sum + (item.reservation_count || 0), 0)
2025-07-28 15:52:07 +08:00
},
roomTotalVisitors() {
2025-10-18 17:13:04 +08:00
return this.roomUsageList.reduce((sum, item) => sum + (item.total_visitors || 0), 0)
2025-07-28 15:52:07 +08:00
}
},
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(',');
}
2025-07-28 15:52:07 +08:00
// 获取各部门预约功能房统计数据
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, // 使用转换后的逗号分隔字符串
2025-07-28 15:52:07 +08:00
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, // 使用转换后的逗号分隔字符串
2025-07-28 15:52:07 +08:00
eventPromoter: this.queryParams.eventPromoter,
userName: this.queryParams.userName,
})
// 等待图表初始化完成后再渲染数据
this.$nextTick(() => {
if (this.departmentChart && this.roomChart) {
// 添加数据检查
2025-10-18 17:13:04 +08:00
const departmentData = departmentRes.data || []
const roomData = roomRes.data || []
2025-07-28 15:52:07 +08:00
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)) {
2025-10-18 17:13:04 +08:00
console.warn('数据格式不正确或为空:', data)
data = [] // 设置为空数组,避免报错
2025-07-28 15:52:07 +08:00
}
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) {
2025-10-18 17:13:04 +08:00
option.title.subtext = '暂无数据'
2025-07-28 15:52:07 +08:00
}
2025-10-18 17:13:04 +08:00
chart.setOption(option)
2025-07-28 15:52:07 +08:00
},
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>