mahjong_group/server/CoreCms.Net.Web.Admin/Controllers/SQ/SQReservationsController.cs
zpc 4cdbf82d77 cs120_9 修复说明:
问题原因:ApprovePigeonFee 方法中的SQL查询条件 AND p.role != 1 排除了发起者。在2人局中,如果只有发起者到场,查询结果为空,导致鸽子费无法分配给任何人。

修复方案:移除 AND p.role != 1 条件,让发起者也能收到鸽子费分配。现在只要是已到场(is_arrive=1)且状态正常(status=0)的参与者,都能分到未赴约用户的鸽子费。
2026-01-02 15:32:38 +08:00

1913 lines
73 KiB
C#
Raw Permalink 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.

/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2025/9/2 17:54:05
* Description: 暂无
***********************************************************************/
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.Entities.Expression;
using CoreCms.Net.Model.FromBody;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Filter;
using CoreCms.Net.Loging;
using CoreCms.Net.IServices;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.Utility.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using NPOI.HSSF.UserModel;
using SqlSugar;
using CoreCms.Net.Web.Admin.Infrastructure;
using CoreCms.Net.Services;
using System.Collections.Generic;
using AutoMapper;
using CoreCms.Net.Model.ViewModels.SQ;
using CoreCms.Net.IRepository.UnitOfWork;
namespace CoreCms.Net.Web.Admin.Controllers
{
/// <summary>
/// 预约表
///</summary>
[Description("预约表")]
[Route("api/[controller]/[action]")]
[ApiController]
[RequiredErrorForAdmin]
[Authorize]
public class SQReservationsController : ControllerBase
{
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly ISQReservationsServices _SQReservationsServices;
private readonly ISQRoomsServices _SQRoomsServices;
private readonly ISysDictionaryDataServices _sysDictionaryDataServices;
private readonly ISysDictionaryServices _sysDictionaryServices;
private readonly ISQReservationParticipantsServices _SQReservationParticipantsServices;
private readonly IMapper _mapper;
private readonly ICoreCmsUserServices _userServices;
private readonly ISQEarningsServices _sQEarningsServices;
private readonly ISQMessageServices _sQMessageServices;
private readonly IUnitOfWork _unitOfWork;
/// <summary>
/// 构造函数
///</summary>
public SQReservationsController(IWebHostEnvironment webHostEnvironment
, ISQReservationsServices SQReservationsServices
, ISQRoomsServices SQRoomsServices
, ISysDictionaryServices sysDictionaryServices
, ISysDictionaryDataServices sysDictionaryDataServices
, ISQReservationParticipantsServices sQReservationParticipantsServices
, IMapper mapper
, ICoreCmsUserServices userServices
, ISQEarningsServices sQEarningsServices
, ISQMessageServices sQMessageServices
, IUnitOfWork unitOfWork
)
{
_webHostEnvironment = webHostEnvironment;
_SQReservationsServices = SQReservationsServices;
_SQRoomsServices = SQRoomsServices;
_sysDictionaryServices = sysDictionaryServices;
_sysDictionaryDataServices = sysDictionaryDataServices;
_SQReservationParticipantsServices = sQReservationParticipantsServices;
_mapper = mapper;
_userServices = userServices;
_sQEarningsServices = sQEarningsServices;
_sQMessageServices = sQMessageServices;
_unitOfWork = unitOfWork;
}
#region ============================================================
// POST: Api/SQReservations/GetPageList
/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("获取列表")]
public async Task<AdminUiCallBack> GetPageList()
{
var jm = new AdminUiCallBack();
var pageCurrent = Request.Form["page"].FirstOrDefault().ObjectToInt(1);
var pageSize = Request.Form["limit"].FirstOrDefault().ObjectToInt(30);
var where = PredicateBuilder.True<SQReservations>();
//获取排序字段
var orderField = Request.Form["orderField"].FirstOrDefault();
Expression<Func<SQReservations, object>> orderEx = orderField switch
{
"id" => p => p.id,
"title" => p => p.title,
"room_id" => p => p.room_id,
"room_name" => p => p.room_name,
"start_time" => p => p.start_time,
"end_time" => p => p.end_time,
"duration_minutes" => p => p.duration_minutes,
"player_count" => p => p.player_count,
"game_type" => p => p.game_type,
"game_rule" => p => p.game_rule,
"extra_info" => p => p.extra_info,
"is_smoking" => p => p.is_smoking,
"gender_limit" => p => p.gender_limit,
"credit_limit" => p => p.credit_limit,
"min_age" => p => p.min_age,
"max_age" => p => p.max_age,
"deposit_fee" => p => p.deposit_fee,
"status" => p => p.status,
"created_at" => p => p.created_at,
"updated_at" => p => p.updated_at,
_ => p => p.id
};
//设置排序方式
var orderDirection = Request.Form["orderDirection"].FirstOrDefault();
var orderBy = orderDirection switch
{
"asc" => OrderByType.Asc,
"desc" => OrderByType.Desc,
_ => OrderByType.Desc
};
//查询筛选
//预约ID int
var id = Request.Form["id"].FirstOrDefault().ObjectToInt(0);
if (id > 0)
{
where = where.And(p => p.id == id);
}
//组局名称 nvarchar
var title = Request.Form["title"].FirstOrDefault();
if (!string.IsNullOrEmpty(title))
{
where = where.And(p => p.title.Contains(title));
}
//房间ID int
var room_id = Request.Form["room_id"].FirstOrDefault().ObjectToInt(0);
if (room_id > 0)
{
where = where.And(p => p.room_id == room_id);
}
//房间名称(冗余存储,比如 304号-大包30元/小时) nvarchar
var room_name = Request.Form["room_name"].FirstOrDefault();
if (!string.IsNullOrEmpty(room_name))
{
where = where.And(p => p.room_name.Contains(room_name));
}
//开始时间 datetime
var start_time = Request.Form["start_time"].FirstOrDefault();
if (!string.IsNullOrEmpty(start_time))
{
if (start_time.Contains("到"))
{
var dts = start_time.Split("到");
var dtStart = dts[0].Trim().ObjectToDate();
where = where.And(p => p.start_time > dtStart);
var dtEnd = dts[1].Trim().ObjectToDate();
where = where.And(p => p.start_time < dtEnd);
}
else
{
var dt = start_time.ObjectToDate();
where = where.And(p => p.start_time > dt);
}
}
//结束时间 datetime
var end_time = Request.Form["end_time"].FirstOrDefault();
if (!string.IsNullOrEmpty(end_time))
{
if (end_time.Contains("到"))
{
var dts = end_time.Split("到");
var dtStart = dts[0].Trim().ObjectToDate();
where = where.And(p => p.end_time > dtStart);
var dtEnd = dts[1].Trim().ObjectToDate();
where = where.And(p => p.end_time < dtEnd);
}
else
{
var dt = end_time.ObjectToDate();
where = where.And(p => p.end_time > dt);
}
}
//时长(分钟) int
var duration_minutes = Request.Form["duration_minutes"].FirstOrDefault().ObjectToInt(0);
if (duration_minutes > 0)
{
where = where.And(p => p.duration_minutes == duration_minutes);
}
//人数 int
var player_count = Request.Form["player_count"].FirstOrDefault().ObjectToInt(0);
if (player_count > 0)
{
where = where.And(p => p.player_count == player_count);
}
//玩法类型(如:补克) nvarchar
var game_type = Request.Form["game_type"].FirstOrDefault();
if (!string.IsNullOrEmpty(game_type))
{
where = where.And(p => p.game_type.Contains(game_type));
}
//具体规则(如:斗地主) nvarchar
var game_rule = Request.Form["game_rule"].FirstOrDefault();
if (!string.IsNullOrEmpty(game_rule))
{
where = where.And(p => p.game_rule.Contains(game_rule));
}
//其他补充 nvarchar
var extra_info = Request.Form["extra_info"].FirstOrDefault();
if (!string.IsNullOrEmpty(extra_info))
{
where = where.And(p => p.extra_info.Contains(extra_info));
}
//是否禁烟0=不限制1=禁烟2=不禁烟 int
var is_smoking = Request.Form["is_smoking"].FirstOrDefault().ObjectToInt(0);
if (is_smoking > 0)
{
where = where.And(p => p.is_smoking == is_smoking);
}
//性别限制0=不限1=男2=女 int
var gender_limit = Request.Form["gender_limit"].FirstOrDefault().ObjectToInt(0);
if (gender_limit > 0)
{
where = where.And(p => p.gender_limit == gender_limit);
}
//最低信誉分 decimal
var credit_limit = Request.Form["credit_limit"].FirstOrDefault().ObjectToDecimal(0);
if (credit_limit > 0)
{
where = where.And(p => p.credit_limit == credit_limit);
}
//最小年龄限制 int
var min_age = Request.Form["min_age"].FirstOrDefault().ObjectToInt(0);
if (min_age > 0)
{
where = where.And(p => p.min_age == min_age);
}
//最大年龄限制0=不限 int
var max_age = Request.Form["max_age"].FirstOrDefault().ObjectToInt(0);
if (max_age > 0)
{
where = where.And(p => p.max_age == max_age);
}
//鸽子费(保证金) decimal
var deposit_fee = Request.Form["deposit_fee"].FirstOrDefault().ObjectToDecimal(0);
if (deposit_fee > 0)
{
where = where.And(p => p.deposit_fee == deposit_fee);
}
//状态0=待开始1=进行中2=已结束3=取消 int
var status = Request.Form["status"].FirstOrDefault().ObjectToInt(0);
if (status > 0)
{
where = where.And(p => p.status == status);
}
//创建时间 datetime
var created_at = Request.Form["created_at"].FirstOrDefault();
if (!string.IsNullOrEmpty(created_at))
{
if (created_at.Contains("到"))
{
var dts = created_at.Split("到");
var dtStart = dts[0].Trim().ObjectToDate();
where = where.And(p => p.created_at > dtStart);
var dtEnd = dts[1].Trim().ObjectToDate();
where = where.And(p => p.created_at < dtEnd);
}
else
{
var dt = created_at.ObjectToDate();
where = where.And(p => p.created_at > dt);
}
}
//更新时间 datetime
var updated_at = Request.Form["updated_at"].FirstOrDefault();
if (!string.IsNullOrEmpty(updated_at))
{
if (updated_at.Contains("到"))
{
var dts = updated_at.Split("到");
var dtStart = dts[0].Trim().ObjectToDate();
where = where.And(p => p.updated_at > dtStart);
var dtEnd = dts[1].Trim().ObjectToDate();
where = where.And(p => p.updated_at < dtEnd);
}
else
{
var dt = updated_at.ObjectToDate();
where = where.And(p => p.updated_at > dt);
}
}
//获取数据
var list = await _SQReservationsServices.QueryPageAsync(where, orderEx, orderBy, pageCurrent, pageSize, true);
var pageList = _mapper.Map<List<SQReservationsDto>>(list);
var rIds = list.Select(it => it.id).ToList();
if (rIds != null && rIds.Count > 0)
{
var participants = await _SQReservationParticipantsServices.QueryListByClauseAsync(it => rIds.Contains(it.reservation_id), "", true);
List<CoreCmsUser> userList = new List<CoreCmsUser>();
if (participants != null && participants.Count > 0)
{
var userIds = participants.Select(it => it.user_id).ToList();
userList = await _userServices.QueryListByClauseAsync(it => userIds.Contains(it.id), "", true);
}
foreach (var item in pageList)
{
var temp = participants.Where(it => it.reservation_id == item.id).OrderBy(it => it.role).ThenBy(it => it.status).ToList();
var dto = _mapper.Map<List<SQReservationParticipantsDto>>(temp);
if (userList != null && userList.Count > 0)
{
foreach (var p in dto)
{
var u = userList.FirstOrDefault(it => it.id == p.user_id);
if (u != null)
{
p.UserName = u.nickName;
p.AvatarImage = u.avatarImage;
}
}
}
item.Participants = dto;
}
}
//返回数据
jm.data = pageList;
jm.code = 0;
jm.count = list.TotalCount;
jm.msg = "数据调用成功!";
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/GetIndex
/// <summary>
/// 首页数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("首页数据")]
public AdminUiCallBack GetIndex()
{
var list = _SQRoomsServices.QueryListByClause(it => it.status);
var data = list.Select(it => new { it.name, it.id }).ToList();
var dic = _sysDictionaryServices.QueryListByClause(it => !it.deleted, it => it.sortNumber
, OrderByType.Asc);
var dicData = _sysDictionaryDataServices.QueryListByClause(it => !it.deleted);
var options = new List<object>();
foreach (var item in dic)
{
var d = dicData.Where(it => it.dictId == item.id).Select(it => new { name = it.dictDataName, it.id }).ToList();
options.Add(new
{
name = item.dictName,
item.id,
children = d
});
}
//返回数据
var jm = new AdminUiCallBack { code = 0, msg = "" };
jm.data = new { roomOptions = data, dicOptions = options };
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/GetCreate
/// <summary>
/// 创建数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("创建数据")]
public AdminUiCallBack GetCreate()
{
//返回数据
var jm = new AdminUiCallBack { code = 0 };
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/DoCreate
/// <summary>
/// 创建提交
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("创建提交")]
public async Task<AdminUiCallBack> DoCreate([FromBody] SQReservations entity)
{
entity.created_at = DateTime.Now;
entity.updated_at = DateTime.Now;
entity.remarks = "后台管理手动创建!";
var jm = await _SQReservationsServices.InsertAsync(entity);
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/GetEdit
/// <summary>
/// 编辑数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("编辑数据")]
public async Task<AdminUiCallBack> GetEdit([FromBody] FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _SQReservationsServices.QueryByIdAsync(entity.id, false);
if (model == null)
{
jm.msg = "不存在此信息";
return jm;
}
jm.code = 0;
jm.data = model;
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/Edit
/// <summary>
/// 编辑提交
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("编辑提交")]
public async Task<AdminUiCallBack> DoEdit([FromBody] SQReservations entity)
{
var e = _SQReservationsServices.QueryById(entity.id);
if (e == null)
{
throw new ArgumentNullException("未找到数据");
}
entity.created_at = e.created_at;
entity.remarks = e.remarks;
entity.updated_at = DateTime.Now;
var jm = await _SQReservationsServices.UpdateAsync(entity);
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/DoDelete/10
/// <summary>
/// 单选删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("单选删除")]
public async Task<AdminUiCallBack> DoDelete([FromBody] FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _SQReservationsServices.ExistsAsync(p => p.id == entity.id, true);
if (!model)
{
jm.msg = GlobalConstVars.DataisNo;
return jm;
}
jm = await _SQReservationsServices.DeleteByIdAsync(entity.id);
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/DoBatchDelete/10,11,20
/// <summary>
/// 批量删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("批量删除")]
public async Task<AdminUiCallBack> DoBatchDelete([FromBody] FMArrayIntIds entity)
{
var jm = await _SQReservationsServices.DeleteByIdsAsync(entity.id);
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/GetDetails/10
/// <summary>
/// 预览数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("预览数据")]
public async Task<AdminUiCallBack> GetDetails([FromBody] FMIntId entity)
{
var jm = new AdminUiCallBack();
var model = await _SQReservationsServices.QueryByIdAsync(entity.id, false);
if (model == null)
{
jm.msg = "不存在此信息";
return jm;
}
jm.code = 0;
jm.data = model;
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/SelectExportExcel/10
/// <summary>
/// 选择导出
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
[HttpPost]
[Description("选择导出")]
public async Task<AdminUiCallBack> SelectExportExcel([FromBody] FMArrayIntIds entity)
{
var jm = new AdminUiCallBack();
//创建Excel文件的对象
var book = new HSSFWorkbook();
//添加一个sheet
var mySheet = book.CreateSheet("Sheet1");
//获取list数据
var listModel = await _SQReservationsServices.QueryListByClauseAsync(p => entity.id.Contains(p.id), p => p.id, OrderByType.Asc, true);
//给sheet1添加第一行的头部标题
var headerRow = mySheet.CreateRow(0);
var headerStyle = ExcelHelper.GetHeaderStyle(book);
var cell0 = headerRow.CreateCell(0);
cell0.SetCellValue("预约ID");
cell0.CellStyle = headerStyle;
mySheet.SetColumnWidth(0, 10 * 256);
var cell1 = headerRow.CreateCell(1);
cell1.SetCellValue("组局名称");
cell1.CellStyle = headerStyle;
mySheet.SetColumnWidth(1, 10 * 256);
var cell2 = headerRow.CreateCell(2);
cell2.SetCellValue("房间ID");
cell2.CellStyle = headerStyle;
mySheet.SetColumnWidth(2, 10 * 256);
var cell3 = headerRow.CreateCell(3);
cell3.SetCellValue("房间名称");
cell3.CellStyle = headerStyle;
mySheet.SetColumnWidth(3, 10 * 256);
var cell4 = headerRow.CreateCell(4);
cell4.SetCellValue("开始时间");
cell4.CellStyle = headerStyle;
mySheet.SetColumnWidth(4, 10 * 256);
var cell5 = headerRow.CreateCell(5);
cell5.SetCellValue("结束时间");
cell5.CellStyle = headerStyle;
mySheet.SetColumnWidth(5, 10 * 256);
var cell6 = headerRow.CreateCell(6);
cell6.SetCellValue("时长(分钟)");
cell6.CellStyle = headerStyle;
mySheet.SetColumnWidth(6, 10 * 256);
var cell7 = headerRow.CreateCell(7);
cell7.SetCellValue("人数");
cell7.CellStyle = headerStyle;
mySheet.SetColumnWidth(7, 10 * 256);
var cell8 = headerRow.CreateCell(8);
cell8.SetCellValue("玩法类型");
cell8.CellStyle = headerStyle;
mySheet.SetColumnWidth(8, 10 * 256);
var cell9 = headerRow.CreateCell(9);
cell9.SetCellValue("具体规则");
cell9.CellStyle = headerStyle;
mySheet.SetColumnWidth(9, 10 * 256);
var cell10 = headerRow.CreateCell(10);
cell10.SetCellValue("其他补充");
cell10.CellStyle = headerStyle;
mySheet.SetColumnWidth(10, 10 * 256);
var cell11 = headerRow.CreateCell(11);
cell11.SetCellValue("是否禁烟");
cell11.CellStyle = headerStyle;
mySheet.SetColumnWidth(11, 10 * 256);
var cell12 = headerRow.CreateCell(12);
cell12.SetCellValue("性别限制");
cell12.CellStyle = headerStyle;
mySheet.SetColumnWidth(12, 10 * 256);
var cell13 = headerRow.CreateCell(13);
cell13.SetCellValue("最低信誉分");
cell13.CellStyle = headerStyle;
mySheet.SetColumnWidth(13, 10 * 256);
var cell14 = headerRow.CreateCell(14);
cell14.SetCellValue("最小年龄限制");
cell14.CellStyle = headerStyle;
mySheet.SetColumnWidth(14, 10 * 256);
var cell15 = headerRow.CreateCell(15);
cell15.SetCellValue("最大年龄限制");
cell15.CellStyle = headerStyle;
mySheet.SetColumnWidth(15, 10 * 256);
var cell16 = headerRow.CreateCell(16);
cell16.SetCellValue("鸽子费");
cell16.CellStyle = headerStyle;
mySheet.SetColumnWidth(16, 10 * 256);
var cell17 = headerRow.CreateCell(17);
cell17.SetCellValue("状态");
cell17.CellStyle = headerStyle;
mySheet.SetColumnWidth(17, 10 * 256);
var cell18 = headerRow.CreateCell(18);
cell18.SetCellValue("创建时间");
cell18.CellStyle = headerStyle;
mySheet.SetColumnWidth(18, 10 * 256);
var cell19 = headerRow.CreateCell(19);
cell19.SetCellValue("更新时间");
cell19.CellStyle = headerStyle;
mySheet.SetColumnWidth(19, 10 * 256);
headerRow.Height = 30 * 20;
var commonCellStyle = ExcelHelper.GetCommonStyle(book);
//将数据逐步写入sheet1各个行
for (var i = 0; i < listModel.Count; i++)
{
var rowTemp = mySheet.CreateRow(i + 1);
var rowTemp0 = rowTemp.CreateCell(0);
rowTemp0.SetCellValue(listModel[i].id.ToString());
rowTemp0.CellStyle = commonCellStyle;
var rowTemp1 = rowTemp.CreateCell(1);
rowTemp1.SetCellValue(listModel[i].title.ToString());
rowTemp1.CellStyle = commonCellStyle;
var rowTemp2 = rowTemp.CreateCell(2);
rowTemp2.SetCellValue(listModel[i].room_id.ToString());
rowTemp2.CellStyle = commonCellStyle;
var rowTemp3 = rowTemp.CreateCell(3);
rowTemp3.SetCellValue(listModel[i].room_name.ToString());
rowTemp3.CellStyle = commonCellStyle;
var rowTemp4 = rowTemp.CreateCell(4);
rowTemp4.SetCellValue(listModel[i].start_time.ToString());
rowTemp4.CellStyle = commonCellStyle;
var rowTemp5 = rowTemp.CreateCell(5);
rowTemp5.SetCellValue(listModel[i].end_time.ToString());
rowTemp5.CellStyle = commonCellStyle;
var rowTemp6 = rowTemp.CreateCell(6);
rowTemp6.SetCellValue(listModel[i].duration_minutes.ToString());
rowTemp6.CellStyle = commonCellStyle;
var rowTemp7 = rowTemp.CreateCell(7);
rowTemp7.SetCellValue(listModel[i].player_count.ToString());
rowTemp7.CellStyle = commonCellStyle;
var rowTemp8 = rowTemp.CreateCell(8);
rowTemp8.SetCellValue(listModel[i].game_type.ToString());
rowTemp8.CellStyle = commonCellStyle;
var rowTemp9 = rowTemp.CreateCell(9);
rowTemp9.SetCellValue(listModel[i].game_rule.ToString());
rowTemp9.CellStyle = commonCellStyle;
var rowTemp10 = rowTemp.CreateCell(10);
rowTemp10.SetCellValue(listModel[i].extra_info.ToString());
rowTemp10.CellStyle = commonCellStyle;
var rowTemp11 = rowTemp.CreateCell(11);
rowTemp11.SetCellValue(listModel[i].is_smoking.ToString());
rowTemp11.CellStyle = commonCellStyle;
var rowTemp12 = rowTemp.CreateCell(12);
rowTemp12.SetCellValue(listModel[i].gender_limit.ToString());
rowTemp12.CellStyle = commonCellStyle;
var rowTemp13 = rowTemp.CreateCell(13);
rowTemp13.SetCellValue(listModel[i].credit_limit.ToString());
rowTemp13.CellStyle = commonCellStyle;
var rowTemp14 = rowTemp.CreateCell(14);
rowTemp14.SetCellValue(listModel[i].min_age.ToString());
rowTemp14.CellStyle = commonCellStyle;
var rowTemp15 = rowTemp.CreateCell(15);
rowTemp15.SetCellValue(listModel[i].max_age.ToString());
rowTemp15.CellStyle = commonCellStyle;
var rowTemp16 = rowTemp.CreateCell(16);
rowTemp16.SetCellValue(listModel[i].deposit_fee.ToString());
rowTemp16.CellStyle = commonCellStyle;
var rowTemp17 = rowTemp.CreateCell(17);
rowTemp17.SetCellValue(listModel[i].status.ToString());
rowTemp17.CellStyle = commonCellStyle;
var rowTemp18 = rowTemp.CreateCell(18);
rowTemp18.SetCellValue(listModel[i].created_at.ToString());
rowTemp18.CellStyle = commonCellStyle;
var rowTemp19 = rowTemp.CreateCell(19);
rowTemp19.SetCellValue(listModel[i].updated_at.ToString());
rowTemp19.CellStyle = commonCellStyle;
}
// 导出excel
string webRootPath = _webHostEnvironment.WebRootPath;
string tpath = "/files/" + DateTime.Now.ToString("yyyy-MM-dd") + "/";
string fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "-SQReservations导出(选择结果).xls";
string filePath = webRootPath + tpath;
DirectoryInfo di = new DirectoryInfo(filePath);
if (!di.Exists)
{
di.Create();
}
FileStream fileHssf = new FileStream(filePath + fileName, FileMode.Create);
book.Write(fileHssf);
fileHssf.Close();
jm.code = 0;
jm.msg = GlobalConstVars.ExcelExportSuccess;
jm.data = tpath + fileName;
return jm;
}
#endregion
#region ============================================================
// POST: Api/SQReservations/QueryExportExcel/10
/// <summary>
/// 查询导出
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("查询导出")]
public async Task<AdminUiCallBack> QueryExportExcel()
{
var jm = new AdminUiCallBack();
var where = PredicateBuilder.True<SQReservations>();
//查询筛选
//预约ID int
var id = Request.Form["id"].FirstOrDefault().ObjectToInt(0);
if (id > 0)
{
where = where.And(p => p.id == id);
}
//组局名称 nvarchar
var title = Request.Form["title"].FirstOrDefault();
if (!string.IsNullOrEmpty(title))
{
where = where.And(p => p.title.Contains(title));
}
//房间ID int
var room_id = Request.Form["room_id"].FirstOrDefault().ObjectToInt(0);
if (room_id > 0)
{
where = where.And(p => p.room_id == room_id);
}
//房间名称(冗余存储,比如 304号-大包30元/小时) nvarchar
var room_name = Request.Form["room_name"].FirstOrDefault();
if (!string.IsNullOrEmpty(room_name))
{
where = where.And(p => p.room_name.Contains(room_name));
}
//开始时间 datetime
var start_time = Request.Form["start_time"].FirstOrDefault();
if (!string.IsNullOrEmpty(start_time))
{
var dt = start_time.ObjectToDate();
where = where.And(p => p.start_time > dt);
}
//结束时间 datetime
var end_time = Request.Form["end_time"].FirstOrDefault();
if (!string.IsNullOrEmpty(end_time))
{
var dt = end_time.ObjectToDate();
where = where.And(p => p.end_time > dt);
}
//时长(分钟) int
var duration_minutes = Request.Form["duration_minutes"].FirstOrDefault().ObjectToInt(0);
if (duration_minutes > 0)
{
where = where.And(p => p.duration_minutes == duration_minutes);
}
//人数 int
var player_count = Request.Form["player_count"].FirstOrDefault().ObjectToInt(0);
if (player_count > 0)
{
where = where.And(p => p.player_count == player_count);
}
//玩法类型(如:补克) nvarchar
var game_type = Request.Form["game_type"].FirstOrDefault();
if (!string.IsNullOrEmpty(game_type))
{
where = where.And(p => p.game_type.Contains(game_type));
}
//具体规则(如:斗地主) nvarchar
var game_rule = Request.Form["game_rule"].FirstOrDefault();
if (!string.IsNullOrEmpty(game_rule))
{
where = where.And(p => p.game_rule.Contains(game_rule));
}
//其他补充 nvarchar
var extra_info = Request.Form["extra_info"].FirstOrDefault();
if (!string.IsNullOrEmpty(extra_info))
{
where = where.And(p => p.extra_info.Contains(extra_info));
}
//是否禁烟0=不限制1=禁烟2=不禁烟 int
var is_smoking = Request.Form["is_smoking"].FirstOrDefault().ObjectToInt(0);
if (is_smoking > 0)
{
where = where.And(p => p.is_smoking == is_smoking);
}
//性别限制0=不限1=男2=女 int
var gender_limit = Request.Form["gender_limit"].FirstOrDefault().ObjectToInt(0);
if (gender_limit > 0)
{
where = where.And(p => p.gender_limit == gender_limit);
}
//最低信誉分 decimal
var credit_limit = Request.Form["credit_limit"].FirstOrDefault().ObjectToDecimal(0);
if (credit_limit > 0)
{
where = where.And(p => p.credit_limit == credit_limit);
}
//最小年龄限制 int
var min_age = Request.Form["min_age"].FirstOrDefault().ObjectToInt(0);
if (min_age > 0)
{
where = where.And(p => p.min_age == min_age);
}
//最大年龄限制0=不限 int
var max_age = Request.Form["max_age"].FirstOrDefault().ObjectToInt(0);
if (max_age > 0)
{
where = where.And(p => p.max_age == max_age);
}
//鸽子费(保证金) decimal
var deposit_fee = Request.Form["deposit_fee"].FirstOrDefault().ObjectToDecimal(0);
if (deposit_fee > 0)
{
where = where.And(p => p.deposit_fee == deposit_fee);
}
//状态0=待开始1=进行中2=已结束3=取消 int
var status = Request.Form["status"].FirstOrDefault().ObjectToInt(0);
if (status > 0)
{
where = where.And(p => p.status == status);
}
//创建时间 datetime
var created_at = Request.Form["created_at"].FirstOrDefault();
if (!string.IsNullOrEmpty(created_at))
{
var dt = created_at.ObjectToDate();
where = where.And(p => p.created_at > dt);
}
//更新时间 datetime
var updated_at = Request.Form["updated_at"].FirstOrDefault();
if (!string.IsNullOrEmpty(updated_at))
{
var dt = updated_at.ObjectToDate();
where = where.And(p => p.updated_at > dt);
}
//获取数据
//创建Excel文件的对象
var book = new HSSFWorkbook();
//添加一个sheet
var mySheet = book.CreateSheet("Sheet1");
//获取list数据
var listModel = await _SQReservationsServices.QueryListByClauseAsync(where, p => p.id, OrderByType.Asc, true);
//给sheet1添加第一行的头部标题
var headerRow = mySheet.CreateRow(0);
var headerStyle = ExcelHelper.GetHeaderStyle(book);
var cell0 = headerRow.CreateCell(0);
cell0.SetCellValue("预约ID");
cell0.CellStyle = headerStyle;
mySheet.SetColumnWidth(0, 10 * 256);
var cell1 = headerRow.CreateCell(1);
cell1.SetCellValue("组局名称");
cell1.CellStyle = headerStyle;
mySheet.SetColumnWidth(1, 10 * 256);
var cell2 = headerRow.CreateCell(2);
cell2.SetCellValue("房间ID");
cell2.CellStyle = headerStyle;
mySheet.SetColumnWidth(2, 10 * 256);
var cell3 = headerRow.CreateCell(3);
cell3.SetCellValue("房间名称");
cell3.CellStyle = headerStyle;
mySheet.SetColumnWidth(3, 10 * 256);
var cell4 = headerRow.CreateCell(4);
cell4.SetCellValue("开始时间");
cell4.CellStyle = headerStyle;
mySheet.SetColumnWidth(4, 10 * 256);
var cell5 = headerRow.CreateCell(5);
cell5.SetCellValue("结束时间");
cell5.CellStyle = headerStyle;
mySheet.SetColumnWidth(5, 10 * 256);
var cell6 = headerRow.CreateCell(6);
cell6.SetCellValue("时长(分钟)");
cell6.CellStyle = headerStyle;
mySheet.SetColumnWidth(6, 10 * 256);
var cell7 = headerRow.CreateCell(7);
cell7.SetCellValue("人数");
cell7.CellStyle = headerStyle;
mySheet.SetColumnWidth(7, 10 * 256);
var cell8 = headerRow.CreateCell(8);
cell8.SetCellValue("玩法类型");
cell8.CellStyle = headerStyle;
mySheet.SetColumnWidth(8, 10 * 256);
var cell9 = headerRow.CreateCell(9);
cell9.SetCellValue("具体规则");
cell9.CellStyle = headerStyle;
mySheet.SetColumnWidth(9, 10 * 256);
var cell10 = headerRow.CreateCell(10);
cell10.SetCellValue("其他补充");
cell10.CellStyle = headerStyle;
mySheet.SetColumnWidth(10, 10 * 256);
var cell11 = headerRow.CreateCell(11);
cell11.SetCellValue("是否禁烟");
cell11.CellStyle = headerStyle;
mySheet.SetColumnWidth(11, 10 * 256);
var cell12 = headerRow.CreateCell(12);
cell12.SetCellValue("性别");
cell12.CellStyle = headerStyle;
mySheet.SetColumnWidth(12, 10 * 256);
var cell13 = headerRow.CreateCell(13);
cell13.SetCellValue("最低信誉分");
cell13.CellStyle = headerStyle;
mySheet.SetColumnWidth(13, 10 * 256);
var cell14 = headerRow.CreateCell(14);
cell14.SetCellValue("最小年龄限制");
cell14.CellStyle = headerStyle;
mySheet.SetColumnWidth(14, 10 * 256);
var cell15 = headerRow.CreateCell(15);
cell15.SetCellValue("最大年龄限制");
cell15.CellStyle = headerStyle;
mySheet.SetColumnWidth(15, 10 * 256);
var cell16 = headerRow.CreateCell(16);
cell16.SetCellValue("鸽子费");
cell16.CellStyle = headerStyle;
mySheet.SetColumnWidth(16, 10 * 256);
var cell17 = headerRow.CreateCell(17);
cell17.SetCellValue("状态");
cell17.CellStyle = headerStyle;
mySheet.SetColumnWidth(17, 10 * 256);
var cell18 = headerRow.CreateCell(18);
cell18.SetCellValue("创建时间");
cell18.CellStyle = headerStyle;
mySheet.SetColumnWidth(18, 10 * 256);
var cell19 = headerRow.CreateCell(19);
cell19.SetCellValue("更新时间");
cell19.CellStyle = headerStyle;
mySheet.SetColumnWidth(19, 10 * 256);
headerRow.Height = 30 * 20;
var commonCellStyle = ExcelHelper.GetCommonStyle(book);
//将数据逐步写入sheet1各个行
for (var i = 0; i < listModel.Count; i++)
{
var rowTemp = mySheet.CreateRow(i + 1);
var rowTemp0 = rowTemp.CreateCell(0);
rowTemp0.SetCellValue(listModel[i].id.ToString());
rowTemp0.CellStyle = commonCellStyle;
var rowTemp1 = rowTemp.CreateCell(1);
rowTemp1.SetCellValue(listModel[i].title.ToString());
rowTemp1.CellStyle = commonCellStyle;
var rowTemp2 = rowTemp.CreateCell(2);
rowTemp2.SetCellValue(listModel[i].room_id.ToString());
rowTemp2.CellStyle = commonCellStyle;
var rowTemp3 = rowTemp.CreateCell(3);
rowTemp3.SetCellValue(listModel[i].room_name.ToString());
rowTemp3.CellStyle = commonCellStyle;
var rowTemp4 = rowTemp.CreateCell(4);
rowTemp4.SetCellValue(listModel[i].start_time.ToString());
rowTemp4.CellStyle = commonCellStyle;
var rowTemp5 = rowTemp.CreateCell(5);
rowTemp5.SetCellValue(listModel[i].end_time.ToString());
rowTemp5.CellStyle = commonCellStyle;
var rowTemp6 = rowTemp.CreateCell(6);
rowTemp6.SetCellValue(listModel[i].duration_minutes.ToString());
rowTemp6.CellStyle = commonCellStyle;
var rowTemp7 = rowTemp.CreateCell(7);
rowTemp7.SetCellValue(listModel[i].player_count.ToString());
rowTemp7.CellStyle = commonCellStyle;
var rowTemp8 = rowTemp.CreateCell(8);
rowTemp8.SetCellValue(listModel[i].game_type.ToString());
rowTemp8.CellStyle = commonCellStyle;
var rowTemp9 = rowTemp.CreateCell(9);
rowTemp9.SetCellValue(listModel[i].game_rule.ToString());
rowTemp9.CellStyle = commonCellStyle;
var rowTemp10 = rowTemp.CreateCell(10);
rowTemp10.SetCellValue(listModel[i].extra_info.ToString());
rowTemp10.CellStyle = commonCellStyle;
var rowTemp11 = rowTemp.CreateCell(11);
rowTemp11.SetCellValue(listModel[i].is_smoking.ToString());
rowTemp11.CellStyle = commonCellStyle;
var rowTemp12 = rowTemp.CreateCell(12);
rowTemp12.SetCellValue(listModel[i].gender_limit.ToString());
rowTemp12.CellStyle = commonCellStyle;
var rowTemp13 = rowTemp.CreateCell(13);
rowTemp13.SetCellValue(listModel[i].credit_limit.ToString());
rowTemp13.CellStyle = commonCellStyle;
var rowTemp14 = rowTemp.CreateCell(14);
rowTemp14.SetCellValue(listModel[i].min_age.ToString());
rowTemp14.CellStyle = commonCellStyle;
var rowTemp15 = rowTemp.CreateCell(15);
rowTemp15.SetCellValue(listModel[i].max_age.ToString());
rowTemp15.CellStyle = commonCellStyle;
var rowTemp16 = rowTemp.CreateCell(16);
rowTemp16.SetCellValue(listModel[i].deposit_fee.ToString());
rowTemp16.CellStyle = commonCellStyle;
var rowTemp17 = rowTemp.CreateCell(17);
rowTemp17.SetCellValue(listModel[i].status.ToString());
rowTemp17.CellStyle = commonCellStyle;
var rowTemp18 = rowTemp.CreateCell(18);
rowTemp18.SetCellValue(listModel[i].created_at.ToString());
rowTemp18.CellStyle = commonCellStyle;
var rowTemp19 = rowTemp.CreateCell(19);
rowTemp19.SetCellValue(listModel[i].updated_at.ToString());
rowTemp19.CellStyle = commonCellStyle;
}
// 写入到excel
string webRootPath = _webHostEnvironment.WebRootPath;
string tpath = "/files/" + DateTime.Now.ToString("yyyy-MM-dd") + "/";
string fileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + "-SQReservations导出(查询结果).xls";
string filePath = webRootPath + tpath;
DirectoryInfo di = new DirectoryInfo(filePath);
if (!di.Exists)
{
di.Create();
}
FileStream fileHssf = new FileStream(filePath + fileName, FileMode.Create);
book.Write(fileHssf);
fileHssf.Close();
jm.code = 0;
jm.msg = GlobalConstVars.ExcelExportSuccess;
jm.data = tpath + fileName;
return jm;
}
#endregion
#region 退======================================================
[HttpPost]
[Description("强制退出参与者")]
public AdminUiCallBack ForceExitParticipant([FromBody] FMIntId entity)
{
var jm = new AdminUiCallBack();
if (entity.id > 0)
{
var re = _SQReservationParticipantsServices.QueryById(entity.id);
if (re != null)
{
re.status = 1;
re.remarks = $"后台于{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}强制退出!";
if (re.is_refund == 1)
{
re.is_refund = 2;
}
_SQReservationParticipantsServices.Update(re);
jm.msg = "强制退出成功";
jm.code = 0;
}
}
return jm;
}
#endregion
#region ======================================================
// POST: Api/SQReservations/DissolveReservation
/// <summary>
/// 后台解散预约(强制取消整个组局)
/// </summary>
/// <param name="entity">预约ID</param>
/// <returns></returns>
[HttpPost]
[Description("解散预约")]
public async Task<AdminUiCallBack> 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
/// <summary>
/// 后台请出参与者(如果是发起者则解散整个组局)
/// </summary>
/// <param name="entity">参与者ID</param>
/// <returns></returns>
[HttpPost]
[Description("请出参与者")]
public async Task<AdminUiCallBack> 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
/// <summary>
/// 搜索用户
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("搜索用户")]
public async Task<AdminUiCallBack> SearchUsers()
{
var jm = new AdminUiCallBack();
var pageCurrent = Request.Form["page"].FirstOrDefault().ObjectToInt(1);
var pageSize = Request.Form["limit"].FirstOrDefault().ObjectToInt(10);
var searchText = Request.Form["searchText"].FirstOrDefault();
var where = PredicateBuilder.True<CoreCmsUser>();
// 搜索条件
if (!string.IsNullOrEmpty(searchText))
{
// 支持按用户名、昵称、手机号搜索
where = where.And(p => p.userName.Contains(searchText) ||
p.nickName.Contains(searchText) ||
p.mobile.Contains(searchText) ||
p.id.ToString().Contains(searchText));
}
// 只查询正常状态的用户
where = where.And(p => p.isDelete == false);
var list = await _userServices.QueryPageAsync(where, p => p.id, OrderByType.Desc, pageCurrent, pageSize);
jm.code = 0;
jm.count = list.TotalCount;
jm.msg = "查询成功";
jm.data = list.Select(p => new
{
id = p.id,
userName = p.userName,
nickName = p.nickName,
mobile = p.mobile
}).ToList();
return jm;
}
// POST: Api/SQReservations/AddParticipant
/// <summary>
/// 添加参与者
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("添加参与者")]
public async Task<AdminUiCallBack> AddParticipant([FromBody] FMAddParticipant entity)
{
var jm = new AdminUiCallBack();
try
{
// 验证参数
if (entity.reservationId <= 0 || entity.userId <= 0)
{
jm.msg = "参数错误";
return jm;
}
// 检查预约是否存在
var reservation = await _SQReservationsServices.QueryByIdAsync(entity.reservationId);
if (reservation == null)
{
jm.msg = "预约不存在";
return jm;
}
// 检查用户是否存在
var user = await _userServices.QueryByIdAsync(entity.userId);
if (user == null)
{
jm.msg = "用户不存在";
return jm;
}
// 检查用户是否已经是参与者
var existingParticipant = await _SQReservationParticipantsServices.QueryListByClauseAsync(p =>
p.reservation_id == entity.reservationId &&
p.user_id == entity.userId);
if (existingParticipant.Any())
{
jm.msg = "该用户已经是参与者";
return jm;
}
// 创建新的参与者记录
var participant = new SQReservationParticipants
{
reservation_id = entity.reservationId,
user_id = entity.userId,
role = 0, // 0=参与者
join_time = DateTime.Now,
status = 0, // 0=正常
is_refund = 0, // 0=无需退款
remarks = $"后台于{DateTime.Now:yyyy-MM-dd HH:mm:ss}添加"
};
var result = await _SQReservationParticipantsServices.InsertAsync(participant);
if (result.code == 0)
{
jm.code = 0;
jm.msg = "添加参与者成功";
}
else
{
jm.msg = "添加参与者失败";
}
}
catch (Exception ex)
{
jm.msg = "添加参与者时发生错误:" + ex.Message;
}
return jm;
}
// POST: Api/SQReservations/BecomeInitiator
/// <summary>
/// 设置发起者
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("设置发起者")]
public async Task<AdminUiCallBack> BecomeInitiator([FromBody] FMBecomeInitiator entity)
{
var jm = new AdminUiCallBack();
try
{
// 验证参数
if (entity.reservationId <= 0 || entity.participantId <= 0 || entity.userId <= 0)
{
jm.msg = "参数错误";
return jm;
}
// 检查预约是否存在
var reservation = await _SQReservationsServices.QueryByIdAsync(entity.reservationId);
if (reservation == null)
{
jm.msg = "预约不存在";
return jm;
}
// 检查参与者是否存在
var participant = await _SQReservationParticipantsServices.QueryByIdAsync(entity.participantId);
if (participant == null)
{
jm.msg = "参与者不存在";
return jm;
}
// 检查用户是否存在
var user = await _userServices.QueryByIdAsync(entity.userId);
if (user == null)
{
jm.msg = "用户不存在";
return jm;
}
// 检查该预约是否已有发起者
var existingInitiator = await _SQReservationParticipantsServices.QueryListByClauseAsync(p =>
p.reservation_id == entity.reservationId &&
p.role == 1); // 1=发起者
if (existingInitiator.Any())
{
// 如果已有发起者,将其改为参与者
var oldInitiator = existingInitiator.First();
oldInitiator.role = 0; // 0=参与者
oldInitiator.remarks = $"后台于{DateTime.Now:yyyy-MM-dd HH:mm:ss}将原发起者改为参与者";
await _SQReservationParticipantsServices.UpdateAsync(oldInitiator);
}
// 将指定参与者设置为发起者
participant.role = 1; // 1=发起者
participant.remarks = $"后台于{DateTime.Now:yyyy-MM-dd HH:mm:ss}设置为发起者";
var result = await _SQReservationParticipantsServices.UpdateAsync(participant);
if (result.code == 0)
{
jm.code = 0;
jm.msg = "设置发起者成功";
}
else
{
jm.msg = "设置发起者失败";
}
}
catch (Exception ex)
{
jm.msg = "设置发起者时发生错误:" + ex.Message;
}
return jm;
}
#endregion
#region ======================================================
/// <summary>
/// 获取鸽子费待审核列表
/// </summary>
/// <returns></returns>
[HttpPost]
[Description("获取鸽子费待审核列表")]
public async Task<AdminUiCallBack> GetPigeonFeeAuditList()
{
var jm = new AdminUiCallBack();
var pageCurrent = Request.Form["page"].FirstOrDefault().ObjectToInt(1);
var pageSize = Request.Form["limit"].FirstOrDefault().ObjectToInt(30);
// 筛选条件
var reservationId = Request.Form["reservation_id"].FirstOrDefault().ObjectToInt(0);
var userId = Request.Form["user_id"].FirstOrDefault().ObjectToInt(0);
var keyword = Request.Form["keyword"].FirstOrDefault(); // 用户昵称或手机号
// 预约时间筛选
var startTimeBegin = Request.Form["start_time_begin"].FirstOrDefault();
var startTimeEnd = Request.Form["start_time_end"].FirstOrDefault();
// 标记时间筛选
var markTimeBegin = Request.Form["mark_time_begin"].FirstOrDefault();
var markTimeEnd = Request.Form["mark_time_end"].FirstOrDefault();
// 构建SQL查询 - 查询 is_arrive=2未赴约待审核且预约有鸽子费的参与者
// 注意未赴约用户可能已被标记为status=1已退出但仍需要审核
var sql = @"
SELECT
p.id AS participant_id,
p.reservation_id,
r.title AS reservation_title,
p.user_id,
u.nickName AS nick_name,
u.mobile,
ISNULL(r.deposit_fee, 0) AS deposit_fee,
r.start_time,
r.end_time,
r.room_name,
(SELECT TOP 1 check_reservation FROM SQReservationParticipants WHERE reservation_id = p.reservation_id AND role = 1) AS mark_time,
p.is_arrive
FROM SQReservationParticipants p
INNER JOIN SQReservations r ON p.reservation_id = r.id
INNER JOIN CoreCmsUser u ON p.user_id = u.id
WHERE p.is_arrive = 2
AND ISNULL(r.deposit_fee, 0) > 0";
// 添加筛选条件
if (reservationId > 0)
{
sql += $" AND p.reservation_id = {reservationId}";
}
if (userId > 0)
{
sql += $" AND p.user_id = {userId}";
}
if (!string.IsNullOrEmpty(keyword))
{
sql += $" AND (u.nickName LIKE '%{keyword}%' OR u.mobile LIKE '%{keyword}%')";
}
if (!string.IsNullOrEmpty(startTimeBegin))
{
var dt = startTimeBegin.ObjectToDate();
sql += $" AND r.start_time >= '{dt:yyyy-MM-dd HH:mm:ss}'";
}
if (!string.IsNullOrEmpty(startTimeEnd))
{
var dt = startTimeEnd.ObjectToDate();
sql += $" AND r.start_time <= '{dt:yyyy-MM-dd HH:mm:ss}'";
}
if (!string.IsNullOrEmpty(markTimeBegin))
{
var dt = markTimeBegin.ObjectToDate();
sql += $" AND (SELECT TOP 1 check_reservation FROM SQReservationParticipants WHERE reservation_id = p.reservation_id AND role = 1) >= '{dt:yyyy-MM-dd HH:mm:ss}'";
}
if (!string.IsNullOrEmpty(markTimeEnd))
{
var dt = markTimeEnd.ObjectToDate();
sql += $" AND (SELECT TOP 1 check_reservation FROM SQReservationParticipants WHERE reservation_id = p.reservation_id AND role = 1) <= '{dt:yyyy-MM-dd HH:mm:ss}'";
}
// 获取总数
var countSql = $"SELECT COUNT(1) FROM ({sql}) AS t";
var totalCount = await _unitOfWork.GetDbClient().Ado.GetIntAsync(countSql);
// 分页排序
sql += $" ORDER BY (SELECT TOP 1 check_reservation FROM SQReservationParticipants WHERE reservation_id = p.reservation_id AND role = 1) DESC";
sql += $" OFFSET {(pageCurrent - 1) * pageSize} ROWS FETCH NEXT {pageSize} ROWS ONLY";
var list = await _unitOfWork.GetDbClient().Ado.SqlQueryAsync<PigeonFeeAuditListDto>(sql);
jm.data = list;
jm.code = 0;
jm.count = totalCount;
jm.msg = "数据调用成功!";
return jm;
}
/// <summary>
/// 审核通过 - 扣除鸽子费并分配给已赴约用户
/// </summary>
/// <param name="request">审核请求参数</param>
/// <returns></returns>
[HttpPost]
[Description("鸽子费审核通过")]
public async Task<AdminUiCallBack> ApprovePigeonFee([FromBody] PigeonFeeAuditRequestDto request)
{
var jm = new AdminUiCallBack();
if (request == null || request.participant_id <= 0 || request.reservation_id <= 0)
{
jm.msg = "参数错误";
return jm;
}
// 获取当前登录管理员ID
var operatorId = HttpContext.User.Claims.FirstOrDefault(c => c.Type == "id")?.Value.ObjectToInt(0) ?? 0;
// 查询参与者信息
var participant = await _SQReservationParticipantsServices.QueryByClauseAsync(
p => p.id == request.participant_id && p.reservation_id == request.reservation_id);
if (participant == null)
{
jm.msg = "参与者记录不存在";
return jm;
}
// 检查状态是否为待审核
if (participant.is_arrive != 2)
{
jm.msg = "该用户不是待审核状态";
return jm;
}
// 查询预约信息
var reservation = await _SQReservationsServices.QueryByClauseAsync(r => r.id == request.reservation_id);
if (reservation == null)
{
jm.msg = "预约不存在";
return jm;
}
// 获取鸽子费金额
var depositFee = reservation.deposit_fee ?? 0;
if (depositFee <= 0)
{
jm.msg = "该预约没有鸽子费";
return jm;
}
// 获取未赴约用户信息(用于消息通知)
var absentUser = await _userServices.QueryByIdAsync(participant.user_id);
var absentUserName = absentUser?.nickName ?? $"用户{participant.user_id}";
// 获取发起者签到时间
var initiatorParticipant = await _SQReservationParticipantsServices.QueryByClauseAsync(
p => p.reservation_id == request.reservation_id && p.role == 1);
var checkTime = initiatorParticipant?.check_reservation;
// 查询符合条件的已赴约用户(包括发起者,排除未赴约用户本人)
// 条件is_arrive=1, status=0, join_time < 签到时间
var eligibleParticipantsSql = $@"
SELECT p.*, u.nickName, u.mobile
FROM SQReservationParticipants p
INNER JOIN CoreCmsUser u ON p.user_id = u.id
WHERE p.reservation_id = {request.reservation_id}
AND p.is_arrive = 1
AND p.status = 0";
// 如果有签到时间,则只选择签到之前加入的参与者
if (checkTime.HasValue)
{
eligibleParticipantsSql += $" AND p.join_time < '{checkTime.Value:yyyy-MM-dd HH:mm:ss}'";
}
var eligibleParticipants = await _unitOfWork.GetDbClient().Ado.SqlQueryAsync<dynamic>(eligibleParticipantsSql);
var participantCount = eligibleParticipants?.Count ?? 0;
try
{
_unitOfWork.BeginTran();
// 1. 更新未赴约用户状态为已审核
await _SQReservationParticipantsServices.UpdateAsync(
it => new SQReservationParticipants
{
is_arrive = 3 // 未赴约,已审核
},
it => it.id == request.participant_id);
// 2. 如果有符合条件的已赴约用户,分配鸽子费
if (participantCount > 0)
{
// 计算每人分得金额(保留两位小数,四舍五入)
var amountPerPerson = Math.Round(depositFee / participantCount, 2, MidpointRounding.AwayFromZero);
foreach (var ep in eligibleParticipants)
{
int epUserId = (int)ep.user_id;
string epNickName = ep.nickName ?? $"用户{epUserId}";
// 为每个用户创建收益记录
var earningsResult = await _sQEarningsServices.AddEarningsAsync(
userId: epUserId,
reservationId: request.reservation_id,
roomId: reservation.room_id,
roomNumber: reservation.room_id.ToString(),
roomName: reservation.room_name,
roomFee: 0, // 鸽子费不涉及房费
earnings: amountPerPerson,
type: 2, // 鸽子费类型
remark: "未赴约用户鸽子费分配",
operatorId: operatorId);
// 发送消息给分到钱的用户
await _sQMessageServices.SendSystemNoticeAsync(
epUserId,
"鸽子费分配通知",
$"{absentUserName} 未能按时参加预约,您收到鸽子费{amountPerPerson}元",
relatedType: 1, // 组局
relatedId: request.reservation_id);
}
}
// 3. 发送消息给未赴约用户
await _sQMessageServices.SendSystemNoticeAsync(
participant.user_id,
"鸽子费扣除通知",
$"您未按时参加预约,鸽子费已扣除{depositFee}元。",
relatedType: 1, // 组局
relatedId: request.reservation_id);
_unitOfWork.CommitTran();
jm.code = 0;
jm.msg = participantCount > 0
? $"审核通过,鸽子费{depositFee}元已分配给{participantCount}位已赴约用户"
: "审核通过,但没有符合条件的已赴约用户分配鸽子费";
}
catch (Exception ex)
{
_unitOfWork.RollbackTran();
jm.msg = "审核失败:" + ex.Message;
}
return jm;
}
/// <summary>
/// 审核未通过 - 退还鸽子费
/// </summary>
/// <param name="request">审核请求参数</param>
/// <returns></returns>
[HttpPost]
[Description("鸽子费审核未通过")]
public async Task<AdminUiCallBack> RejectPigeonFee([FromBody] PigeonFeeAuditRequestDto request)
{
var jm = new AdminUiCallBack();
if (request == null || request.participant_id <= 0 || request.reservation_id <= 0)
{
jm.msg = "参数错误";
return jm;
}
// 查询参与者信息
var participant = await _SQReservationParticipantsServices.QueryByClauseAsync(
p => p.id == request.participant_id && p.reservation_id == request.reservation_id);
if (participant == null)
{
jm.msg = "参与者记录不存在";
return jm;
}
// 检查状态是否为待审核
if (participant.is_arrive != 2)
{
jm.msg = "该用户不是待审核状态";
return jm;
}
// 查询预约信息
var reservation = await _SQReservationsServices.QueryByClauseAsync(r => r.id == request.reservation_id);
if (reservation == null)
{
jm.msg = "预约不存在";
return jm;
}
try
{
_unitOfWork.BeginTran();
// 1. 更新参与者状态
// is_arrive = 1已赴约
// status = 0正常未退出
// is_refund = 3发起退款由退款任务处理
await _SQReservationParticipantsServices.UpdateAsync(
it => new SQReservationParticipants
{
is_arrive = 1, // 已赴约
status = 0, // 正常
is_refund = 3 // 发起退款
},
it => it.id == request.participant_id);
// 2. 发送消息给用户
await _sQMessageServices.SendSystemNoticeAsync(
participant.user_id,
"鸽子费审核结果",
"您的鸽子费已原路退回。",
relatedType: 1, // 组局
relatedId: request.reservation_id);
_unitOfWork.CommitTran();
jm.code = 0;
jm.msg = "审核未通过,鸽子费将原路退回";
}
catch (Exception ex)
{
_unitOfWork.RollbackTran();
jm.msg = "审核失败:" + ex.Message;
}
return jm;
}
#endregion
}
}