| | |
| | | <template> |
| | | <div>宣教统计</div> |
| | | <div class="education-statistics"> |
| | | <!-- 搜索区域 --> |
| | | <div class="search-container"> |
| | | <el-form |
| | | :model="queryParams" |
| | | ref="queryForm" |
| | | size="small" |
| | | :inline="true" |
| | | label-width="100px" |
| | | > |
| | | <el-form-item label="统计维度" prop="groupType"> |
| | | <el-select |
| | | v-model="queryParams.groupType" |
| | | placeholder="请选择统计维度" |
| | | @change="handleGroupTypeChange" |
| | | style="width: 180px" |
| | | > |
| | | <el-option label="按科室统计" value="1"></el-option> |
| | | <el-option label="按病区统计" value="2"></el-option> |
| | | </el-select> |
| | | <el-select |
| | | style="margin-left: 10px" |
| | | v-if="queryParams.groupType == '2'" |
| | | v-model="queryParams.hospitaldistrictcodes" |
| | | size="medium" |
| | | multiple |
| | | filterable |
| | | placeholder="请选择病区" |
| | | > |
| | | <el-option |
| | | v-for="item in flatArrayhospit" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <el-select |
| | | v-else-if="queryParams.groupType == '1'" |
| | | v-model="queryParams.deptcodes" |
| | | size="medium" |
| | | multiple |
| | | filterable |
| | | placeholder="请选择科室" |
| | | > |
| | | <el-option |
| | | v-for="item in flatArraydept" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="就诊类型" prop="hospType"> |
| | | <el-select |
| | | v-model="queryParams.hospType" |
| | | placeholder="请选择就诊类型" |
| | | clearable |
| | | style="width: 150px" |
| | | > |
| | | <el-option label="门诊" value="1"></el-option> |
| | | <el-option label="出院" value="2"></el-option> |
| | | <el-option label="专病" value="3"></el-option> |
| | | <el-option label="入院/外部导入" value="4"></el-option> |
| | | <el-option label="体检" value="5"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="入院时间" prop="dateRange"> |
| | | <el-date-picker |
| | | v-model="queryParams.dateRange" |
| | | type="daterange" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | value-format="yyyy-MM-dd" |
| | | style="width: 280px" |
| | | :picker-options="datePickerOptions" |
| | | > |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="宣教发送时间" prop="visittime"> |
| | | <el-date-picker |
| | | v-model="queryParams.visittime" |
| | | type="date" |
| | | placeholder="选择日期" |
| | | value-format="yyyy-MM-dd" |
| | | style="width: 180px" |
| | | > |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | size="medium" |
| | | @click="handleQuery" |
| | | :loading="loading" |
| | | >搜索</el-button |
| | | > |
| | | <el-button icon="el-icon-refresh" size="medium" @click="resetQuery" |
| | | >重置</el-button |
| | | > |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="medium" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:statistics:export']" |
| | | >导出</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <!-- 统计数据概览 --> |
| | | <div class="summary-cards" v-if="statisticsData.total > 0"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <div class="summary-card"> |
| | | <div class="card-title">发送总量</div> |
| | | <div class="card-value">{{ totalCount }}</div> |
| | | <div class="card-desc">总宣教发送次数</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="summary-card"> |
| | | <div class="card-title">发送成功量</div> |
| | | <div class="card-value">{{ sendSuccessCount }}</div> |
| | | <div class="card-desc">已成功发送的宣教</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="summary-card"> |
| | | <div class="card-title">已读量</div> |
| | | <div class="card-value">{{ readCount }}</div> |
| | | <div class="card-desc">患者已阅读的宣教</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="summary-card"> |
| | | <div class="card-title">平均发送成功率</div> |
| | | <div class="card-value">{{ avgSendSuccessRate }}%</div> |
| | | <div class="card-desc">整体发送成功比例</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | |
| | | <!-- 数据表格 --> |
| | | <div class="table-container"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="statisticsData.list" |
| | | :border="true" |
| | | style="width: 100%" |
| | | :default-sort="{ prop: 'totalCount', order: 'descending' }" |
| | | @sort-change="handleSortChange" |
| | | > |
| | | <el-table-column prop="groupName" label="分组名称" align="center" fixed> |
| | | <!-- <template slot-scope="scope"> |
| | | <span class="group-name" @click="handleGroupDetail(scope.row)"> |
| | | {{ scope.row.groupName }} |
| | | </span> |
| | | </template> --> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="groupCode" |
| | | label="分组编码" |
| | | align="center" |
| | | ></el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="totalCount" |
| | | label="宣教发送总量" |
| | | align="center" |
| | | sortable="custom" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span class="count-highlight">{{ scope.row.totalCount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="sendSuccessCount" |
| | | label="发送成功量" |
| | | align="center" |
| | | sortable="custom" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span class="success-count">{{ scope.row.sendSuccessCount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="readCount" |
| | | label="已读量" |
| | | align="center" |
| | | sortable="custom" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <span class="read-count">{{ scope.row.readCount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="sendSuccessRate" |
| | | label="发送成功率" |
| | | align="center" |
| | | width="200" |
| | | sortable="custom" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-progress |
| | | :percentage="scope.row.sendSuccessRate * 100" |
| | | :stroke-width="8" |
| | | :show-text="false" |
| | | style="width: 80px; margin: 0 auto" |
| | | :color="getRateColor(scope.row.sendSuccessRate)" |
| | | /> |
| | | <span class="rate-text" |
| | | >{{ (scope.row.sendSuccessRate * 100).toFixed(1) }}%</span |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | prop="readRate" |
| | | label="已读率" |
| | | align="center" |
| | | width="200" |
| | | sortable="custom" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-progress |
| | | :percentage="scope.row.readRate * 100" |
| | | :stroke-width="8" |
| | | :show-text="false" |
| | | style="width: 80px; margin: 0 auto" |
| | | :color="getRateColor(scope.row.readRate)" |
| | | /> |
| | | <span class="rate-text" |
| | | >{{ (scope.row.readRate * 100).toFixed(1) }}%</span |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <!-- <el-table-column label="操作" align="center" width="200" fixed="right"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | type="text" |
| | | size="small" |
| | | @click="handleDetail(scope.row)" |
| | | icon="el-icon-document" |
| | | v-hasPermi="['system:statistics:detail']" |
| | | >详细数据</el-button |
| | | > |
| | | <el-button |
| | | type="text" |
| | | size="small" |
| | | @click="handleExportGroup(scope.row)" |
| | | icon="el-icon-download" |
| | | v-hasPermi="['system:statistics:export']" |
| | | >导出</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> --> |
| | | </el-table> |
| | | |
| | | <!-- 分页 --> |
| | | <pagination |
| | | v-show="statisticsData.total > 0" |
| | | :total="statisticsData.total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- 分组详情弹窗 --> |
| | | <el-dialog |
| | | :title="detailTitle" |
| | | :visible.sync="detailVisible" |
| | | width="80%" |
| | | :before-close="handleCloseDetail" |
| | | > |
| | | <div v-loading="detailLoading"> |
| | | <el-row :gutter="20" class="detail-header"> |
| | | <el-col :span="6"> |
| | | <div class="detail-item"> |
| | | <label>分组名称:</label> |
| | | <span>{{ currentGroup.groupName }}</span> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="detail-item"> |
| | | <label>分组编码:</label> |
| | | <span>{{ currentGroup.groupCode }}</span> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="detail-item"> |
| | | <label>发送成功率:</label> |
| | | <span class="rate-highlight" |
| | | >{{ (currentGroup.sendSuccessRate * 100).toFixed(1) }}%</span |
| | | > |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <div class="detail-item"> |
| | | <label>已读率:</label> |
| | | <span class="rate-highlight" |
| | | >{{ (currentGroup.readRate * 100).toFixed(1) }}%</span |
| | | > |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-tabs v-model="detailActiveTab" class="detail-tabs"> |
| | | <el-tab-pane label="趋势分析" name="trend"> |
| | | <!-- 这里可以放置图表组件 --> |
| | | <div class="chart-placeholder"> |
| | | 趋势图表(可根据需求接入ECharts) |
| | | </div> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="明细数据" name="detail"> |
| | | <el-table |
| | | :data="detailList" |
| | | border |
| | | style="width: 100%; margin-top: 20px" |
| | | > |
| | | <el-table-column |
| | | prop="patientName" |
| | | label="患者姓名" |
| | | align="center" |
| | | width="120" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="patientNo" |
| | | label="患者编号" |
| | | align="center" |
| | | width="120" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="sendTime" |
| | | label="发送时间" |
| | | align="center" |
| | | width="180" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="readTime" |
| | | label="阅读时间" |
| | | align="center" |
| | | width="180" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="educationTitle" |
| | | label="宣教标题" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="status" |
| | | label="状态" |
| | | align="center" |
| | | width="100" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type=" |
| | | scope.row.status === '已读' |
| | | ? 'success' |
| | | : scope.row.status === '发送成功' |
| | | ? 'info' |
| | | : 'danger' |
| | | " |
| | | size="small" |
| | | > |
| | | {{ scope.row.status }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="detailVisible = false">关 闭</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { gethelibraryCount } from "@/api/AiCentre/index"; |
| | | |
| | | export default { |
| | | name: "EducationStatistics", |
| | | data() { |
| | | return {}; |
| | | return { |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 1000, |
| | | groupType: "1", // 1-科室,2-病区 |
| | | deptcodes: ['all'], // 科室code数组 |
| | | hospitaldistrictcodes: [], // 病区code数组 |
| | | hospType: undefined, // 就诊类型 |
| | | starttime: undefined, // 入院开始时间 |
| | | endtime: undefined, // 入院结束时间 |
| | | visittime: undefined, // 宣教发送时间 |
| | | dateRange: [], // 入院时间范围 |
| | | orderBy: "totalCount", // 排序字段 |
| | | order: "descending", // 排序方式 |
| | | }, |
| | | |
| | | // 统计数据 |
| | | statisticsData: { |
| | | total: 0, |
| | | list: [], |
| | | }, |
| | | |
| | | // 下拉选项 |
| | | flatArraydept: [], |
| | | |
| | | flatArrayhospit: [], |
| | | |
| | | // 加载状态 |
| | | loading: false, |
| | | detailLoading: false, |
| | | |
| | | // 详情弹窗 |
| | | detailVisible: false, |
| | | detailTitle: "", |
| | | detailActiveTab: "trend", |
| | | currentGroup: {}, |
| | | detailList: [], |
| | | |
| | | // 日期选择器配置 |
| | | datePickerOptions: { |
| | | disabledDate(time) { |
| | | return time.getTime() > Date.now(); |
| | | }, |
| | | shortcuts: [ |
| | | { |
| | | text: "最近一周", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | { |
| | | text: "最近一个月", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | { |
| | | text: "最近三个月", |
| | | onClick(picker) { |
| | | const end = new Date(); |
| | | const start = new Date(); |
| | | start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); |
| | | picker.$emit("pick", [start, end]); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | }; |
| | | }, |
| | | |
| | | created() {}, |
| | | computed: { |
| | | // 计算总发送量 |
| | | totalCount() { |
| | | return this.statisticsData.list.reduce( |
| | | (sum, item) => sum + item.totalCount, |
| | | 0 |
| | | ); |
| | | }, |
| | | |
| | | methods: {}, |
| | | // 计算总发送成功量 |
| | | sendSuccessCount() { |
| | | return this.statisticsData.list.reduce( |
| | | (sum, item) => sum + item.sendSuccessCount, |
| | | 0 |
| | | ); |
| | | }, |
| | | |
| | | // 计算总已读量 |
| | | readCount() { |
| | | return this.statisticsData.list.reduce( |
| | | (sum, item) => sum + item.readCount, |
| | | 0 |
| | | ); |
| | | }, |
| | | |
| | | // 计算平均发送成功率 |
| | | avgSendSuccessRate() { |
| | | if (this.statisticsData.list.length === 0) return 0; |
| | | const totalRate = this.statisticsData.list.reduce( |
| | | (sum, item) => sum + item.sendSuccessRate, |
| | | 0 |
| | | ); |
| | | return ((totalRate / this.statisticsData.list.length) * 100).toFixed(1); |
| | | }, |
| | | }, |
| | | |
| | | created() { |
| | | this.flatArrayhospit = this.$store.getters.belongWards.map((ward) => { |
| | | return { |
| | | label: ward.districtName, |
| | | value: ward.districtCode, |
| | | }; |
| | | }); |
| | | this.flatArraydept = this.$store.getters.belongDepts.map((dept) => { |
| | | return { |
| | | label: dept.deptName, |
| | | value: dept.deptCode, |
| | | }; |
| | | }); |
| | | console.log(this.flatArrayhospit,'this.flatArrayhospit'); |
| | | |
| | | this.flatArraydept.push({ label: "全部", value: "all" }); |
| | | this.flatArrayhospit.push({ label: "全部", value: "all" }); |
| | | this.getList(); |
| | | }, |
| | | |
| | | methods: { |
| | | // 获取统计数据列表 |
| | | async getList() { |
| | | this.loading = true; |
| | | try { |
| | | console.log(this.queryParams.hospitaldistrictcodes); |
| | | |
| | | // 构建请求参数 |
| | | const params = { |
| | | pageNum: this.queryParams.pageNum, |
| | | pageSize: this.queryParams.pageSize, |
| | | hospitaldistrictcodes: |
| | | this.queryParams.hospitaldistrictcodes.includes("all") |
| | | ? this.getAllWardCodes() |
| | | : this.queryParams.hospitaldistrictcodes, |
| | | deptcodes: this.queryParams.deptcodes.includes("all") |
| | | ? this.getAllDeptCodes() |
| | | : this.queryParams.deptcodes, |
| | | }; |
| | | |
| | | // 根据统计维度设置参数 |
| | | if (this.queryParams.groupType == "1") { |
| | | params.hospitaldistrictcodes = []; |
| | | } else if (this.queryParams.groupType == "2") { |
| | | params.deptcodes = []; |
| | | } |
| | | |
| | | // 设置时间参数 |
| | | if ( |
| | | this.queryParams.dateRange && |
| | | this.queryParams.dateRange.length === 2 |
| | | ) { |
| | | params.starttime = this.queryParams.dateRange[0]; |
| | | params.endtime = this.queryParams.dateRange[1]; |
| | | } |
| | | |
| | | // 设置其他参数 |
| | | if (this.queryParams.hospType) { |
| | | params.hospType = this.queryParams.hospType; |
| | | } |
| | | if (this.queryParams.visittime) { |
| | | params.visittime = this.queryParams.visittime; |
| | | } |
| | | |
| | | // 调用接口 |
| | | const response = await gethelibraryCount(params); |
| | | this.statisticsData = { |
| | | total: response.total || 0, |
| | | list: response.list || [], |
| | | }; |
| | | } catch (error) { |
| | | console.error("获取统计数据失败:", error); |
| | | this.$message.error("获取统计数据失败"); |
| | | this.statisticsData = { total: 0, list: [] }; |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | getAllWardCodes() { |
| | | return this.flatArrayhospit |
| | | .filter((item) => item.value !== "all") |
| | | .map((item) => item.value); |
| | | }, |
| | | |
| | | getAllDeptCodes() { |
| | | return this.flatArraydept |
| | | .filter((item) => item.value !== "all") |
| | | .map((item) => item.value); |
| | | }, |
| | | // 统计维度变更 |
| | | handleGroupTypeChange(value) { |
| | | // 切换维度时清空对应的选择 |
| | | if (value === "dept") { |
| | | this.queryParams.hospitaldistrictcodes = []; |
| | | } else if (value === "ward") { |
| | | this.queryParams.deptcodes = []; |
| | | } |
| | | }, |
| | | |
| | | // 处理搜索 |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // 重置搜索条件 |
| | | resetQuery() { |
| | | this.queryParams = { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | groupType: "dept", |
| | | deptcodes: [], |
| | | hospitaldistrictcodes: [], |
| | | hospType: undefined, |
| | | starttime: undefined, |
| | | endtime: undefined, |
| | | visittime: undefined, |
| | | dateRange: [], |
| | | orderBy: "totalCount", |
| | | order: "descending", |
| | | }; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // 表格排序 |
| | | handleSortChange({ column, prop, order }) { |
| | | if (prop) { |
| | | this.queryParams.orderBy = prop; |
| | | this.queryParams.order = order; |
| | | this.getList(); |
| | | } |
| | | }, |
| | | |
| | | // 根据成功率获取进度条颜色 |
| | | getRateColor(rate) { |
| | | const percentage = rate * 100; |
| | | if (percentage >= 90) return "#67C23A"; |
| | | if (percentage >= 80) return "#E6A23C"; |
| | | if (percentage >= 60) return "#409EFF"; |
| | | return "#F56C6C"; |
| | | }, |
| | | |
| | | // 查看分组详情 |
| | | handleGroupDetail(row) { |
| | | this.currentGroup = row; |
| | | this.detailTitle = `${row.groupName} - 宣教统计详情`; |
| | | this.detailActiveTab = "trend"; |
| | | this.detailVisible = true; |
| | | this.loadDetailData(); |
| | | }, |
| | | |
| | | // 加载详情数据 |
| | | async loadDetailData() { |
| | | this.detailLoading = true; |
| | | try { |
| | | // 这里应该调用获取详情的接口 |
| | | // 模拟数据 |
| | | setTimeout(() => { |
| | | this.detailList = [ |
| | | { |
| | | patientName: "张三", |
| | | patientNo: "P202312001", |
| | | sendTime: "2023-12-01 10:30:00", |
| | | readTime: "2023-12-01 14:20:00", |
| | | educationTitle: "骨科术后康复指导", |
| | | status: "已读", |
| | | }, |
| | | { |
| | | patientName: "李四", |
| | | patientNo: "P202312002", |
| | | sendTime: "2023-12-01 11:15:00", |
| | | readTime: "", |
| | | educationTitle: "心血管疾病预防", |
| | | status: "发送成功", |
| | | }, |
| | | { |
| | | patientName: "王五", |
| | | patientNo: "P202312003", |
| | | sendTime: "2023-12-02 09:45:00", |
| | | readTime: "2023-12-02 16:10:00", |
| | | educationTitle: "糖尿病饮食指导", |
| | | status: "已读", |
| | | }, |
| | | ]; |
| | | this.detailLoading = false; |
| | | }, 500); |
| | | } catch (error) { |
| | | console.error("加载详情数据失败:", error); |
| | | this.$message.error("加载详情数据失败"); |
| | | this.detailLoading = false; |
| | | } |
| | | }, |
| | | |
| | | // 查看详情 |
| | | handleDetail(row) { |
| | | this.currentGroup = row; |
| | | this.detailTitle = `${row.groupName} - 明细数据`; |
| | | this.detailActiveTab = "detail"; |
| | | this.detailVisible = true; |
| | | this.loadDetailData(); |
| | | }, |
| | | |
| | | // 导出当前分组数据 |
| | | handleExportGroup(row) { |
| | | this.$confirm(`确定要导出 "${row.groupName}" 的统计数据吗?`, "提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | // 这里调用导出接口 |
| | | this.$message.success("导出任务已开始,请稍后在下载中心查看"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | |
| | | // 导出全部数据 |
| | | handleExport() { |
| | | this.$confirm("确定要导出全部统计数据吗?", "提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | // 构建导出参数 |
| | | const exportParams = { ...this.queryParams }; |
| | | delete exportParams.pageNum; |
| | | delete exportParams.pageSize; |
| | | |
| | | // 这里调用导出接口 |
| | | this.$message.success("导出任务已开始,请稍后在下载中心查看"); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | |
| | | // 关闭详情弹窗 |
| | | handleCloseDetail(done) { |
| | | this.$confirm("确认关闭?", "提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | }) |
| | | .then(() => { |
| | | done(); |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| | | <style lang="scss" scoped> |
| | | .education-statistics { |
| | | padding: 20px; |
| | | background: #fff; |
| | | min-height: calc(100vh - 84px); |
| | | |
| | | .search-container { |
| | | background: #f8f9fa; |
| | | padding: 20px; |
| | | border-radius: 8px; |
| | | margin-bottom: 20px; |
| | | border: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .summary-cards { |
| | | margin-bottom: 20px; |
| | | |
| | | .summary-card { |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | padding: 20px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | text-align: center; |
| | | border: 1px solid #ebeef5; |
| | | transition: all 0.3s ease; |
| | | |
| | | &:hover { |
| | | transform: translateY(-5px); |
| | | box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .card-title { |
| | | font-size: 14px; |
| | | color: #909399; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .card-value { |
| | | font-size: 28px; |
| | | font-weight: 600; |
| | | color: #409eff; |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .card-desc { |
| | | font-size: 12px; |
| | | color: #c0c4cc; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .table-container { |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | padding: 20px; |
| | | border: 1px solid #ebeef5; |
| | | |
| | | .group-name { |
| | | color: #409eff; |
| | | cursor: pointer; |
| | | text-decoration: underline; |
| | | transition: color 0.3s; |
| | | |
| | | &:hover { |
| | | color: #66b1ff; |
| | | } |
| | | } |
| | | |
| | | .count-highlight { |
| | | font-weight: 600; |
| | | color: #606266; |
| | | } |
| | | |
| | | .success-count { |
| | | color: #67c23a; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .read-count { |
| | | color: #e6a23c; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .rate-text { |
| | | display: block; |
| | | margin-top: 5px; |
| | | font-size: 12px; |
| | | color: #606266; |
| | | } |
| | | } |
| | | |
| | | .detail-header { |
| | | margin-bottom: 20px; |
| | | padding: 20px; |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | |
| | | .detail-item { |
| | | label { |
| | | color: #909399; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | span { |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | color: #303133; |
| | | } |
| | | |
| | | .rate-highlight { |
| | | color: #409eff; |
| | | font-weight: 600; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .detail-tabs { |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .chart-placeholder { |
| | | height: 300px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background: #f8f9fa; |
| | | border-radius: 8px; |
| | | color: #909399; |
| | | border: 1px dashed #dcdfe6; |
| | | } |
| | | } |
| | | |
| | | // 响应式调整 |
| | | @media (max-width: 1200px) { |
| | | .education-statistics { |
| | | padding: 10px; |
| | | } |
| | | |
| | | .summary-cards { |
| | | .el-col { |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | } |
| | | </style> |