update from old git

This commit is contained in:
2025-09-04 18:30:54 +08:00
parent af2c152ef6
commit 61502cb3bd
46 changed files with 6420 additions and 0 deletions

1548
web/admin/guadan/create.aspx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_guadan_create : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}

View File

@@ -0,0 +1,52 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="edit.aspx.cs" Inherits="admin_guadan_guadantime_edit" %>
<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="container mt-4">
<h3 class="mb-4">编辑挂单时间设置</h3>
<asp:Panel CssClass="card p-4 shadow-sm">
<!-- 最早入住时间 -->
<div class="mb-3 row align-items-center">
<label class="col-sm-3 col-form-label">最早入住时间:</label>
<div class="col-sm-3">
<asp:DropDownList ID="ddlEarliestCheckIn" runat="server" CssClass="form-select"></asp:DropDownList>
</div>
</div>
<!-- 最晚退房时间 -->
<div class="mb-3 row align-items-center">
<label class="col-sm-3 col-form-label">最晚退房时间:</label>
<div class="col-sm-3">
<asp:DropDownList ID="ddlLatestCheckOut" runat="server" CssClass="form-select"></asp:DropDownList>
</div>
</div>
<!-- 是否可用 -->
<div class="mb-3 row align-items-center">
<label class="col-sm-3 col-form-label">是否可用:</label>
<div class="col-sm-3">
<asp:CheckBox ID="chkIsActive" runat="server" CssClass="form-check-input" />
</div>
</div>
<!-- 按钮 -->
<div class="mt-4">
<asp:Button ID="btnSave" runat="server" Text="保存" CssClass="btn btn-primary me-2" OnClick="btnSave_Click" />
<asp:HyperLink ID="hlBack" runat="server" NavigateUrl="timeindex.aspx" Text="返回列表" CssClass="btn btn-secondary" />
</div>
<!-- 消息提示 -->
<div id="divMessage" runat="server" class="mt-3 text-success"></div>
</asp:Panel>
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
</asp:Content>

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_guadan_guadantime_edit : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
private Guid SettingId
{
get
{
if (Guid.TryParse(Request.QueryString["id"], out Guid id))
return id;
else
return Guid.Empty;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindTimeDropdowns();
if (SettingId != Guid.Empty)
{
LoadSetting();
}
else
{
divMessage.InnerText = "未指定要编辑的记录。";
btnSave.Enabled = false;
}
}
}
private void BindTimeDropdowns()
{
ddlEarliestCheckIn.Items.Clear();
ddlLatestCheckOut.Items.Clear();
for (int h = 0; h < 24; h++)
{
ddlEarliestCheckIn.Items.Add($"{h:D2}:00");
ddlEarliestCheckIn.Items.Add($"{h:D2}:30");
ddlLatestCheckOut.Items.Add($"{h:D2}:00");
ddlLatestCheckOut.Items.Add($"{h:D2}:30");
}
}
private void LoadSetting()
{
var setting = _db.GuadanTimeSetting.FirstOrDefault(x => x.Id == SettingId);
if (setting != null)
{
ddlEarliestCheckIn.SelectedValue = setting.EarliestCheckIn;
ddlLatestCheckOut.SelectedValue = setting.LatestCheckOut;
chkIsActive.Checked = setting.IsActive;
}
else
{
divMessage.InnerText = "找不到指定记录。";
btnSave.Enabled = false;
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
if (SettingId == Guid.Empty)
return;
try
{
{
var setting = _db.GuadanTimeSetting.FirstOrDefault(x => x.Id == SettingId);
if (setting != null)
{
setting.EarliestCheckIn = ddlEarliestCheckIn.SelectedValue;
setting.LatestCheckOut = ddlLatestCheckOut.SelectedValue;
setting.IsActive = chkIsActive.Checked;
setting.UpdatedAt = DateTime.Now;
_db.SaveChanges();
divMessage.InnerText = "保存成功!";
}
else
{
divMessage.InnerText = "记录不存在,保存失败。";
}
}
}
catch (Exception ex)
{
divMessage.InnerText = "保存失败:" + ex.Message;
}
}
}

View File

@@ -0,0 +1,40 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="timeindex.aspx.cs" Inherits="admin_guadan_guadantime_timeindex" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
<nav>
<a href="timeset.aspx" class="btn btn-primary">
新建时间参数
</a>
</nav>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<h3>挂单时间设置列表</h3>
<div id="divMessage" runat="server" style="color:red; margin-top:10px;"></div>
<asp:GridView ID="gvTimeSettings" runat="server" AutoGenerateColumns="False"
CssClass="table table-bordered" OnRowCommand="gvTimeSettings_RowCommand">
<Columns>
<asp:BoundField DataField="EarliestCheckIn" HeaderText="最早入住时间" />
<asp:BoundField DataField="LatestCheckOut" HeaderText="最晚退房时间" />
<asp:BoundField DataField="IsActive" HeaderText="是否可用" />
<asp:BoundField DataField="CreatedAt" HeaderText="创建时间" DataFormatString="{0:yyyy-MM-dd HH:mm}" />
<asp:TemplateField HeaderText="操作">
<ItemTemplate>
<asp:HyperLink ID="hlEdit" runat="server" Text="编辑"
NavigateUrl='<%# "edit.aspx?id=" + Eval("Id") %>' CssClass="btn btn-sm btn-primary"></asp:HyperLink>
<asp:Button ID="btnDelete" runat="server" Text="删除" CommandName="DeleteItem"
CommandArgument='<%# Eval("Id") %>' CssClass="btn btn-sm btn-danger"
OnClientClick="return confirm('确定删除这条记录吗?');" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
</asp:Content>

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_guadan_guadantime_timeindex : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindTimeSettings();
}
}
private void BindTimeSettings()
{
{
// 取得最近所有挂单时间设置
var list = _db.GuadanTimeSetting
.OrderByDescending(x => x.CreatedAt)
.ToList();
gvTimeSettings.DataSource = list;
gvTimeSettings.DataBind();
}
}
protected void gvTimeSettings_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DeleteItem")
{
Guid id = Guid.Parse(e.CommandArgument.ToString());
try
{
{
var setting = _db.GuadanTimeSetting.FirstOrDefault(x => x.Id == id);
if (setting != null)
{
_db.GuadanTimeSetting.Remove(setting);
_db.SaveChanges();
}
}
// 重新绑定列表
BindTimeSettings();
}
catch (Exception ex)
{
// 显示错误信息
divMessage.InnerText = "删除失败:" + ex.Message;
}
}
}
}

View File

@@ -0,0 +1,36 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="timeset.aspx.cs" Inherits="admin_guadan_guadantime_timeset" %>
<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>
<h3>入住时间設定</h3>
<div>
<label>最早入住時間:</label>
<asp:DropDownList ID="ddlEarliestCheckIn" runat="server"></asp:DropDownList>
</div>
<div>
<label>最晚退房時間:</label>
<asp:DropDownList ID="ddlLatestCheckOut" runat="server"></asp:DropDownList>
</div>
<div style="margin-top:10px;">
<asp:Button ID="btnSave" runat="server" Text="保存" OnClick="btnSave_Click" />
</div>
<div id="divMessage" runat="server" style="color:green; margin-top:10px;"></div>
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
</asp:Content>

View File

@@ -0,0 +1,65 @@
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_guadan_guadantime_timeset : MyWeb.config
{
private Model.ezEntities _db = new Model.ezEntities();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// 預設時間
// 初始化半小时间隔
for (int h = 0; h < 24; h++)
{
ddlEarliestCheckIn.Items.Add(new System.Web.UI.WebControls.ListItem($"{h:D2}:00"));
ddlEarliestCheckIn.Items.Add(new System.Web.UI.WebControls.ListItem($"{h:D2}:30"));
ddlLatestCheckOut.Items.Add(new System.Web.UI.WebControls.ListItem($"{h:D2}:00"));
ddlLatestCheckOut.Items.Add(new System.Web.UI.WebControls.ListItem($"{h:D2}:30"));
}
// 預設值
ddlEarliestCheckIn.SelectedValue = "08:00";
ddlLatestCheckOut.SelectedValue = "14:00";
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
try
{
if(_db.GuadanTimeSetting.Where( a => a.IsActive == true).Count() > 0)
{
divMessage.InnerText = "已经存在有效的时间设置";
return;
}
string earliest = ddlEarliestCheckIn.SelectedValue;
string latest = ddlLatestCheckOut.SelectedValue;
var setting = new GuadanTimeSetting
{
Id = Guid.NewGuid(),
EarliestCheckIn = earliest,
LatestCheckOut = latest,
IsActive = true,
CreatedAt = DateTime.Now
};
_db.GuadanTimeSetting.Add(setting);
_db.SaveChanges();
// TODO: 保存到資料庫
divMessage.InnerText = $"保存成功!最早入住:{earliest}, 最晚退房:{latest}";
}
catch (Exception ex)
{
divMessage.InnerText = "保存失败:" + ex.Message;
}
}
}

112
web/admin/guadan/index.aspx Normal file
View File

@@ -0,0 +1,112 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="admin_guadan_index" %>
<asp:Content ID="Content1" ContentPlaceHolderID="page_header" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="page_nav" Runat="Server">
<nav>
<a href="create.aspx" class="btn btn-primary" >新建掛單</a>
</nav>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div class="mx-5">
<v-data-table
:items="items"
:headers="headers">
<template #item.actions="{item}">
<a :href="'create.aspx?orderId='+item.guaDanOrderNo" class="btn btn-secondary">編輯</a>
<a class="btn btn-outline-danger" @click="deleteGuadanOrder(item)">取消</a>
</template>
<template #item.room="{item}">
{{item.room.name}}
</template>
<template #item.bed="{item}">
{{item.bed.name}}
</template>
<template #item.status="{item}">
{{item.status}}
</template>
<template #item.start_date="{item}">
{{item.start_date | timeString('YYYY/MM/DD HH:mm')}}
</template>
<template #item.end_date="{item}">
{{item.end_date | timeString('YYYY/MM/DD HH:mm')}}
</template>
<template #item.created_at="{item}">
{{item.created_at | timeString('YYYY/MM/DD HH:mm')}}
</template>
</v-data-table>
</div>
<!-- 更新修改確認彈出視窗 -->
<message-modal ref="messageModal"></message-modal>
<!-- 刪除確認彈出視窗 -->
<confirm-modal ref="confirmModal"></confirm-modal>
</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: 'bookerName'},
{ text: '起始日期', value: 'start_date', align: 'center' },
{ text: '結束日期', value: 'end_date', align: 'center' },
{ text: '掛單人數', value: 'guest_count' },
{ text: '狀態', value: 'statusName', align: 'center' },
{ text: '建立時間', value: 'created_at', align: 'center' },
{ text: '備註', value: 'notes', align: 'center' },
{ text: '操作', value: 'actions', align: 'center' }
],
}
},
methods: {
getGuadanOrder() {
axios.get('/api/guadan/list')
.then((res) => {
this.items = res.data;
}).catch((err) => {
console.log(err);
})
},
deleteGuadanOrder(order) {
this.$refs.confirmModal.open({
message: '確認取消掛單?',
onConfirm: () => {
axios.post('/api/guadan/delete', null, {
params: {
uuid: order.uuid
}
}).then((res) => {
this.items = this.items.filter(a => a.uuid != order.uuid)
this.$refs.messageModal.open({
message: '取消成功'
})
}).catch((error) => {
this.$refs.messageModal.open({
message: '取消失敗'
})
})
}
});
},
},
watch: {
},
mounted() {
this.getGuadanOrder();
},
});
</script>
</asp:Content>

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_guadan_index : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}

View File

@@ -0,0 +1,143 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="statistics.aspx.cs" Inherits="admin_guadan_statistics" %>
<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="container my-4">
<!-- 客房统计 -->
<div class="row row-cols-2 row-cols-sm-3 row-cols-md-4 row-cols-lg-5 g-3">
<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">{{ roomStatistics.roomCount }}</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">{{ roomStatistics.emptyRoomCount }}</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">
{{ roomStatistics.bedCount }} (男:{{ roomStatistics.maleBedCount }},女:{{ roomStatistics.femaleBedCount }}
</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">
{{ roomStatistics.emptyBedCount }} (男:{{ roomStatistics.emptyMaleBedCount }},女:{{ roomStatistics.emptyFemaleBedCount }}
</div>
</div>
</div>
</div>
<!-- 挂单统计 -->
<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>
</div>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(vuetify_options),
data() {
return {
roomStatistics: {
roomCount: 0,
emptyRoomCount: 0,
bedCount: 0,
maleBedCount: 0,
femaleBedCount: 0,
emptyBedCount: 0,
emptyMaleBedCount: 0,
emptyFemaleBedCount: 0
},
guadanStatistics: {
guadanTotalCount: 0,
guadanCurrentCount: 0,
guadanPeopleTotal: 0,
guadanPeopleMale: 0,
guadanPeopleFemale: 0,
guadanPeopleCurrent: 0,
guadanPeopleCurrentMale: 0,
guadanPeopleCurrentFemale: 0
},
}
},
methods: {
GetGuadanStatistics() {
axios.get('/api/guadanStatistics/GetGuadanStatistics')
.then((res) => {
this.roomStatistics = res.data.roomStatistics;
this.guadanStatistics = res.data.guadanStatistics;
})
}
},
watch: {
},
mounted() {
this.GetGuadanStatistics();
// 每两分钟更新一次 (2 * 60 * 1000 毫秒)
setInterval(() => {
this.GetGuadanStatistics();
}, 1 * 60 * 1000);
},
})
</script>
</asp:Content>

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_guadan_statistics : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}

View File

@@ -0,0 +1,13 @@
<%@ Page Title="" Language="C#" MasterPageFile="~/admin/Templates/TBS5ADM001/MasterPage.master" AutoEventWireup="true" CodeFile="update.aspx.cs" Inherits="admin_guadan_update" %>
<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">
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="offCanvasRight" Runat="Server">
</asp:Content>
<asp:Content ID="Content5" ContentPlaceHolderID="footer_script" Runat="Server">
</asp:Content>

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class admin_guadan_update : MyWeb.config
{
protected void Page_Load(object sender, EventArgs e)
{
}
}