初始化

This commit is contained in:
2025-07-28 15:52:07 +08:00
commit cd0e77b332
1304 changed files with 302802 additions and 0 deletions

View File

@@ -0,0 +1,385 @@
<template>
<div class="app-container">
<!-- 查询条件 -->
<el-card class="box-card">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" 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 @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-option>
</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-option>
</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>
</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>
</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 type="warning" plain icon="el-icon-download" size="mini" @click="handleExportDepartmentUsageList">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getUser"></right-toolbar>
</el-row>
<el-table :data="departmentUsageList" border>
<el-table-column prop="department" label="部门" width="180"></el-table-column>
<el-table-column prop="reservation_count" label="预约次数"></el-table-column>
<el-table-column prop="total_visitors" label="来访人数"></el-table-column>
</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 :showSearch.sync="showSearch" @queryTable="getUser"></right-toolbar>
</el-row>
<el-table :data="roomUsageList" border>
<el-table-column prop="roomName" label="功能房名" width="180"></el-table-column>
<el-table-column prop="reservation_count" label="预约次数"></el-table-column>
<el-table-column prop="total_visitors" label="来访人数"></el-table-column>
</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]
}
// 获取各部门预约功能房统计数据
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: this.queryParams.rtDepar,
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: this.queryParams.rtDepar,
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>