Files
17168ERP/web/admin/guadan/statistics_table.aspx

267 lines
9.8 KiB
Plaintext
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.
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="statistics_table.aspx.cs" Inherits="admin_guadan_statistics_table" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<!-- 今日使用情況 -->
<div class="section mb-6">
<v-card outlined class="pa-1">
<v-card-title class="headline grey--text text--darken-2">
掛單統計
</v-card-title>
<v-divider class="mb-4"></v-divider>
<v-card-text>
<div class="row row-cols-2 row-cols-sm-3 row-cols-md-4 row-cols-lg-5 g-3 mt-1">
<div class="col">
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
<div class="fs-2">📝</div>
<div class="text-muted small mt-1">总挂单次数</div>
<div class="fw-bold fs-5 mt-1">{{ guadanStatistics.guadanTotalCount }}</div>
</div>
</div>
<div class="col">
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
<div class="fs-2">📋</div>
<div class="text-muted small mt-1">当前挂单数量</div>
<div class="fw-bold fs-5 mt-1">{{ guadanStatistics.guadanCurrentCount }}</div>
</div>
</div>
<div class="col">
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
<div class="fs-2">👥</div>
<div class="text-muted small mt-1">总挂单人数</div>
<div class="fw-bold fs-5 mt-1">
{{ guadanStatistics.guadanPeopleTotal }} (男:{{ guadanStatistics.guadanPeopleMale }},女:{{ guadanStatistics.guadanPeopleFemale }}
</div>
</div>
</div>
<div class="col">
<div class="p-3 bg-light text-center rounded shadow" style="min-height: 180px;">
<div class="fs-2">👨👩</div>
<div class="text-muted small mt-1">已預約掛單人數</div>
<div class="fw-bold fs-5 mt-1">
{{ guadanStatistics.guadanPeopleCurrent }} (男:{{ guadanStatistics.guadanPeopleCurrentMale }},女:{{ guadanStatistics.guadanPeopleCurrentFemale }}
</div>
</div>
</div>
</div>
</v-card-text>
</v-card>
</div>
<!-- 近期床位使用統計 -->
<div class="section container">
<!-- 日期筛选区 -->
<div class="d-flex align-center flex-wrap" style="gap: 5px;">
<!-- 开始日期 -->
<v-menu
ref="menu1"
v-model="menu1"
:close-on-content-click="false"
transition="scale-transition"
offset-y
min-width="auto"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="startDate"
label="開始日期"
prepend-icon="mdi-calendar"
readonly
v-bind="attrs"
v-on="on"
dense
outlined
></v-text-field>
</template>
<v-date-picker v-model="startDate" @input="menu1 = false"></v-date-picker>
</v-menu>
<!-- 结束日期 -->
<v-menu
ref="menu2"
v-model="menu2"
:close-on-content-click="false"
transition="scale-transition"
offset-y
min-width="auto"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
v-model="endDate"
label="結束日期"
prepend-icon="mdi-calendar"
readonly
v-bind="attrs"
v-on="on"
dense
outlined
></v-text-field>
</template>
<v-date-picker v-model="endDate" @input="menu2 = false"></v-date-picker>
</v-menu>
<!-- 查询按钮 -->
<v-btn
color="primary"
@click="getList"
style="align-self: stretch;"
>
查詢
</v-btn>
<v-btn
color="primary"
style="align-self: stretch;"
@click="exportStatisticsToExcel">
導出下面表格數據到Excel
</v-btn>
</div>
</div>
<v-divider class="mb-4"></v-divider>
<div>
<!-- 表格 -->
<v-data-table
:items="items"
:headers="headers"
class="elevation-2"
dense
hide-default-footer
:items-per-page="10"
>
<template #item.date="{ item }">
<span>{{ item.date | timeString('YYYY-MM-DD') }}</span>
</template>
<template #item.todaytotalbookers="{item}">
<span>
{{item?.todaytotalbookers + '(男' + '女)'}}
</span>
</template>
<template #item.checkin="{item}">
<span>
{{item?.checkin + '(男' + '女)'}}
</span>
</template>
<template #item.bedusagerate="{ item }">
{{ ((item.todaytotalbookers / bedcount) * 100).toFixed(2) + '%' }}
</template>
<template #item.roomcount="{item}">
{{roomcount}}
</template>
<template #item.bedcount="{item}">
{{bedcount}}
</template>
</v-data-table>
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
<script>
Vue.filter('timeString', function (value, myFormat) {
return value == null || value == "" ? "" : moment(value).format(myFormat || 'YYYY-MM-DD, HH:mm:ss');
});
new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
items: [],
headers: [
{ text: '日期', value: 'date' },
{ text: '房间数量', value: 'roomcount' },
{ text: '床位数量', value: 'bedcount' },
{ text: '预约人数', value: 'todaytotalbookers' },
{ text: '已入住人数', value: 'checkin'},
{ text: '可用床位', value: 'availableBeds' },
{ text: '床位利用率', value: 'bedusagerate' }
],
startDate: null,
endDate: null,
menu1: false,
menu2: false,
bedcount: 0,
roomcount: 0,
guadanStatistics: {
guadanTotalCount: 0,
guadanCurrentCount: 0,
guadanPeopleTotal: 0,
guadanPeopleMale: 0,
guadanPeopleFemale: 0,
guadanPeopleCurrent: 0,
guadanPeopleCurrentMale: 0,
guadanPeopleCurrentFemale: 0
},
}
},
methods: {
async getList() {
try {
const res = await axios.get('/api/guadan/guadanstatisticstable/list', {
params: {
start: this.startDate || '',
end: this.endDate || ''
}
});
this.items = res.data.statistics;
this.roomcount = res.data.roomcount;
this.bedcount = res.data.bedcount;
} catch (e) {
console.error(e);
}
},
exportStatisticsToExcel() {
if (!this.items || !this.items.length) {
console.warn("没有数据可导出");
return;
}
// 1. 取 items 数组并格式化
const sheetData = this.items.map(item => ({
日期: item.date.split('T')[0], // 格式化成 YYYY-MM-DD
预订人数: item.todaytotalbookers,
入住人数: item.checkin
}));
// 2. 转换成 XLSX Sheet
const ws = XLSX.utils.json_to_sheet(sheetData);
// 3. 创建 Workbook 并添加 Sheet
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "统计数据");
// 4. 写入 Excel 并下载
const wbout = XLSX.write(wb, { bookType: "xlsx", type: "array" });
saveAs(new Blob([wbout], { type: "application/octet-stream" }), "statistics.xlsx");
},
GetGuadanStatistics() {
axios.get('/api/guadanStatistics/GetGuadanStatistics')
.then((res) => {
this.guadanStatistics = res.data.guadanStatistics;
})
}
},
mounted() {
this.getList();
this.GetGuadanStatistics();
}
})
</script>
<!-- CDN 方式引入 XLSX 和 FileSaver -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
</asp:Content>