From c058f45f55404afc5f54b9a09eca2957b8b13dd6 Mon Sep 17 00:00:00 2001 From: zpc Date: Sun, 7 Dec 2025 18:22:50 +0800 Subject: [PATCH] 321 --- .../SQ/SQReservationsController.cs | 181 +++++++++++++++++- server/CoreCms.Net.Web.Admin/Doc.xml | 14 ++ .../views/sq/sqroompricing/date-details.html | 82 +++++++- .../views/sq/sqroompricing/holiday-price.html | 118 +++++------- .../wwwroot/views/sq/sqroompricing/index.html | 3 +- 5 files changed, 315 insertions(+), 83 deletions(-) diff --git a/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQReservationsController.cs b/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQReservationsController.cs index e9add25..0317cf2 100644 --- a/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQReservationsController.cs +++ b/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQReservationsController.cs @@ -1,4 +1,4 @@ -/*********************************************************************** +/*********************************************************************** * Project: CoreCms * ProjectName: 核心内容管理系统 * Web: https://www.corecms.net @@ -1195,6 +1195,169 @@ ICoreCmsUserServices userServices #endregion + #region 解散预约====================================================== + + // POST: Api/SQReservations/DissolveReservation + /// + /// 后台解散预约(强制取消整个组局) + /// + /// 预约ID + /// + [HttpPost] + [Description("解散预约")] + public async Task DissolveReservation([FromBody] FMIntId entity) + { + var jm = new AdminUiCallBack(); + + if (entity == null || entity.id <= 0) + { + jm.msg = "参数错误"; + return jm; + } + + // 查询预约信息 + var reservation = await _SQReservationsServices.QueryByClauseAsync(r => r.id == entity.id); + if (reservation == null) + { + jm.msg = "预约不存在"; + return jm; + } + + // 检查预约状态 + if (reservation.status >= 3) // 3=已结束,4=已取消 + { + jm.msg = "该预约已结束或已取消,无法再次解散"; + return jm; + } + + // 1. 更新预约状态为已取消 + var updateResult = await _SQReservationsServices.UpdateAsync( + it => new SQReservations + { + status = 4, // 已取消 + updated_at = DateTime.Now, + remarks = $"后台于{DateTime.Now:yyyy-MM-dd HH:mm:ss}强制解散" + }, + it => it.id == entity.id); + + if (!updateResult) + { + jm.msg = "解散预约失败"; + return jm; + } + + // 2. 有押金时,已支付押金(is_refund=2)的参与者标记为发起退款(is_refund=3) + if (reservation.deposit_fee.HasValue && reservation.deposit_fee.Value > 0) + { + await _SQReservationParticipantsServices.UpdateAsync( + it => new SQReservationParticipants + { + is_refund = 3 // 发起退款 + }, + it => it.reservation_id == entity.id && it.status == 0 && it.is_refund == 2 && it.paymentId != null && it.paymentId != ""); + } + + // 3. 所有参与者标记为已退出 + await _SQReservationParticipantsServices.UpdateAsync( + it => new SQReservationParticipants + { + status = 1, // 已退出 + quit_time = DateTime.Now, + remarks = $"后台于{DateTime.Now:yyyy-MM-dd HH:mm:ss}强制解散组局" + }, + it => it.reservation_id == entity.id && it.status == 0); + + jm.code = 0; + jm.msg = "解散预约成功"; + return jm; + } + + #endregion + + + #region 请出参与者====================================================== + + // POST: Api/SQReservations/KickParticipant + /// + /// 后台请出参与者(如果是发起者则解散整个组局) + /// + /// 参与者ID + /// + [HttpPost] + [Description("请出参与者")] + public async Task KickParticipant([FromBody] FMIntId entity) + { + var jm = new AdminUiCallBack(); + + if (entity == null || entity.id <= 0) + { + jm.msg = "参数错误"; + return jm; + } + + // 查询参与者信息 + var participant = await _SQReservationParticipantsServices.QueryByClauseAsync(p => p.id == entity.id); + if (participant == null) + { + jm.msg = "参与者不存在"; + return jm; + } + + // 检查参与者状态 + if (participant.status == 1) + { + jm.msg = "该参与者已退出"; + return jm; + } + + // 查询预约信息 + var reservation = await _SQReservationsServices.QueryByClauseAsync(r => r.id == participant.reservation_id); + if (reservation == null) + { + jm.msg = "预约不存在"; + return jm; + } + + // 检查预约状态 + if (reservation.status >= 3) + { + jm.msg = "该预约已结束或已取消"; + return jm; + } + + // 如果是发起者,解散整个组局 + if (participant.role == 1) + { + // 调用解散预约逻辑 + return await DissolveReservation(new FMIntId { id = reservation.id }); + } + + // 普通参与者:标记为已退出 + participant.status = 1; + participant.quit_time = DateTime.Now; + participant.remarks = $"后台于{DateTime.Now:yyyy-MM-dd HH:mm:ss}请出组局"; + + // 有押金且已支付时,标记为发起退款 + if (reservation.deposit_fee.HasValue && reservation.deposit_fee.Value > 0 && participant.is_refund == 2 && !string.IsNullOrEmpty(participant.paymentId)) + { + participant.is_refund = 3; // 发起退款 + } + + var updateResult = await _SQReservationParticipantsServices.UpdateAsync(participant); + if (updateResult.code != 0) + { + jm.msg = "请出参与者失败"; + return jm; + } + + jm.code = 0; + jm.msg = "请出参与者成功"; + return jm; + } + + #endregion + + #region SearchUsers // POST: Api/SQReservations/SearchUsers /// @@ -1216,8 +1379,8 @@ ICoreCmsUserServices userServices if (!string.IsNullOrEmpty(searchText)) { // 支持按用户名、昵称、手机号搜索 - where = where.And(p => p.userName.Contains(searchText) || - p.nickName.Contains(searchText) || + where = where.And(p => p.userName.Contains(searchText) || + p.nickName.Contains(searchText) || p.mobile.Contains(searchText) || p.id.ToString().Contains(searchText)); } @@ -1278,8 +1441,8 @@ ICoreCmsUserServices userServices } // 检查用户是否已经是参与者 - var existingParticipant = await _SQReservationParticipantsServices.QueryListByClauseAsync(p => - p.reservation_id == entity.reservationId && + var existingParticipant = await _SQReservationParticipantsServices.QueryListByClauseAsync(p => + p.reservation_id == entity.reservationId && p.user_id == entity.userId); if (existingParticipant.Any()) @@ -1365,8 +1528,8 @@ ICoreCmsUserServices userServices } // 检查该预约是否已有发起者 - var existingInitiator = await _SQReservationParticipantsServices.QueryListByClauseAsync(p => - p.reservation_id == entity.reservationId && + var existingInitiator = await _SQReservationParticipantsServices.QueryListByClauseAsync(p => + p.reservation_id == entity.reservationId && p.role == 1); // 1=发起者 if (existingInitiator.Any()) @@ -1401,7 +1564,7 @@ ICoreCmsUserServices userServices return jm; } #endregion - - + + } } diff --git a/server/CoreCms.Net.Web.Admin/Doc.xml b/server/CoreCms.Net.Web.Admin/Doc.xml index 1637011..7b049a2 100644 --- a/server/CoreCms.Net.Web.Admin/Doc.xml +++ b/server/CoreCms.Net.Web.Admin/Doc.xml @@ -3990,6 +3990,20 @@ + + + 后台解散预约(强制取消整个组局) + + 预约ID + + + + + 后台请出参与者(如果是发起者则解散整个组局) + + 参与者ID + + 搜索用户 diff --git a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/date-details.html b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/date-details.html index 204af3e..1c57539 100644 --- a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/date-details.html +++ b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/date-details.html @@ -164,7 +164,8 @@ slotHtml += '
组局名称:' + (reservation.title || '无') + '
'; slotHtml += '
参与人数:' + (reservation.player_count || 0) + '人
'; slotHtml += '
鸽子费:' + (reservation.deposit_fee || 0) + '元
'; - slotHtml += '
最晚到店:' + (reservation.latest_arrival_time || '无') + '
'; + slotHtml += '
最晚到店:' + (reservation.latest_arrival_time || '无') + '
'; + slotHtml += '
'; slotHtml += ' '; slotHtml += '
'; slotHtml += '
玩法类型:' + (reservation.game_type || '无') + '
'; @@ -255,13 +256,90 @@ return '' + refundText + ''; } }, - { field: 'remarks', title: '备注', minWidth: 150 } + { field: 'remarks', title: '备注', minWidth: 120 }, + { + field: 'operation', + title: '操作', + width: 140, + fixed: 'right', + templet: function (d) { + if (d.status === 1) { + return '已退出'; + } + var btnText = d.role === 1 ? '请出(解散组局)' : '请出组局'; + var btnClass = d.role === 1 ? 'layui-btn-danger' : 'layui-btn-warm'; + return ''; + } + } ]] }); }); } } } + // 绑定解散预约按钮事件 + $(document).off('click', '.btn-dissolve-reservation').on('click', '.btn-dissolve-reservation', function () { + var reservationId = $(this).data('id'); + var reservationTitle = $(this).data('title'); + + layer.confirm('确定要解散组局【' + reservationTitle + '】吗?

所有已支付押金的参与者将发起退款。', { + title: '解散预约确认', + btn: ['确定解散', '取消'], + icon: 3 + }, function (index) { + layer.close(index); + var loadIndex = layer.load(2); + coreHelper.Post("Api/SQReservations/DissolveReservation", { id: reservationId }, function (res) { + layer.close(loadIndex); + if (res.code === 0) { + layer.msg('解散成功', { icon: 1 }); + // 关闭弹窗并刷新对应日期 + layer.closeAll('page'); + if (typeof window._refreshSingleDay === 'function') { + window._refreshSingleDay(dateStr); + } + } else { + layer.msg(res.msg || '解散失败', { icon: 2 }); + } + }); + }); + }); + + // 绑定请出参与者按钮事件 + $(document).off('click', '.btn-kick-participant').on('click', '.btn-kick-participant', function () { + var participantId = $(this).data('id'); + var role = $(this).data('role'); + var userName = $(this).data('name'); + + var confirmMsg = ''; + if (role === 1) { + confirmMsg = '该用户【' + userName + '】是发起者,请出将解散整个组局,确定继续吗?'; + } else { + confirmMsg = '确定要将用户【' + userName + '】请出组局吗?

如已支付押金将发起退款。'; + } + + layer.confirm(confirmMsg, { + title: '请出组局确认', + btn: ['确定请出', '取消'], + icon: 3 + }, function (index) { + layer.close(index); + var loadIndex = layer.load(2); + coreHelper.Post("Api/SQReservations/KickParticipant", { id: participantId }, function (res) { + layer.close(loadIndex); + if (res.code === 0) { + layer.msg(res.msg || '操作成功', { icon: 1 }); + // 关闭弹窗并刷新对应日期 + layer.closeAll('page'); + if (typeof window._refreshSingleDay === 'function') { + window._refreshSingleDay(dateStr); + } + } else { + layer.msg(res.msg || '操作失败', { icon: 2 }); + } + }); + }); + }); } else { layer.msg(e.msg || '获取数据失败'); } diff --git a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/holiday-price.html b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/holiday-price.html index 829e2ba..a231636 100644 --- a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/holiday-price.html +++ b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/holiday-price.html @@ -21,106 +21,81 @@
- -
-
-
- - 未启用的时段将使用普通价格,已启用的时段将覆盖当天的普通价格 -
-
-
-
+
-
- -
-
- 普通价格描述: - -
-
- 会员价格描述: - -
-
- (默认: 普通 - / 会员 -) +
+
+ +
+ 普通价格: + + 会员价格: +
+
-
+
-
- -
-
- 普通价格描述: - -
-
- 会员价格描述: - -
-
- (默认: 普通 - / 会员 -) +
+
+ +
+ 普通价格: + + 会员价格: +
+
-
+
-
- -
-
- 普通价格描述: - -
-
- 会员价格描述: - -
-
- (默认: 普通 - / 会员 -) +
+
+ +
+ 普通价格: + + 会员价格: +
+
-
+
-
- -
-
- 普通价格描述: - -
-
- 会员价格描述: - -
-
- (默认: 普通 - / 会员 -) +
+
+ +
+ 普通价格: + + 会员价格: +
+
@@ -179,9 +154,10 @@ var slotType = slot.time_slot_type; var slotItem = $('.time-slot-item[data-slot="' + slotType + '"]'); - // 显示默认价格描述 - slotItem.find('#default_price_' + slotType + ' .default-standard').text(slot.default_price_desc_standard || '-'); - slotItem.find('#default_price_' + slotType + ' .default-member').text(slot.default_price_desc_member || '-'); + // 显示默认价格提示 + var defaultStandard = slot.default_price_desc_standard || '-'; + var defaultMember = slot.default_price_desc_member || '-'; + $('#default_price_tip_' + slotType).html('当前默认价格:普通 ' + defaultStandard + ' / 会员 ' + defaultMember).show(); if (slot.has_holiday_price) { // 已有节假日价格,回显 @@ -190,10 +166,10 @@ slotItem.find('input[name="price_desc_member_' + slotType + '"]').val(slot.holiday_price_desc_member || ''); toggleSlotForm(slotType, true); } else { - // 没有节假日价格,使用默认价格描述 + // 没有节假日价格,不填充默认值,保持输入框为空 slotItem.find('input[name="switch_' + slotType + '"]').prop('checked', false); - slotItem.find('input[name="price_desc_standard_' + slotType + '"]').val(slot.default_price_desc_standard || ''); - slotItem.find('input[name="price_desc_member_' + slotType + '"]').val(slot.default_price_desc_member || ''); + slotItem.find('input[name="price_desc_standard_' + slotType + '"]').val(''); + slotItem.find('input[name="price_desc_member_' + slotType + '"]').val(''); toggleSlotForm(slotType, false); } }); diff --git a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html index d5113c1..ac98bc0 100644 --- a/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html +++ b/server/CoreCms.Net.Web.Admin/wwwroot/views/sq/sqroompricing/index.html @@ -1161,7 +1161,8 @@ }); } - // 刷新单个日期 + // 刷新单个日期(同时挂载到window供弹窗调用) + window._refreshSingleDay = refreshSingleDay; function refreshSingleDay(dateStr) { if (!selectedRoomId || !dateStr) { return;