This commit is contained in:
zpc 2025-09-03 04:08:16 +08:00
parent 9e31244b9d
commit 4a7111fe4c
5 changed files with 454 additions and 13 deletions

View File

@ -0,0 +1,34 @@
/***********************************************************************
* Project: CoreCms
* ProjectName:
* Web: https://www.corecms.net
* Author:
* Email: jianweie@163.com
* CreateTime: 2025/1/15 10:00:00
* Description:
***********************************************************************/
using System.ComponentModel.DataAnnotations;
namespace CoreCms.Net.Model.FromBody
{
/// <summary>
/// 添加参与者请求模型
/// </summary>
public class FMAddParticipant
{
/// <summary>
/// 预约ID
/// </summary>
[Display(Name = "预约ID")]
[Required(ErrorMessage = "请输入预约ID")]
public int reservationId { get; set; }
/// <summary>
/// 用户ID
/// </summary>
[Display(Name = "用户ID")]
[Required(ErrorMessage = "请输入用户ID")]
public int userId { get; set; }
}
}

View File

@ -0,0 +1,41 @@
/***********************************************************************
* Project: CoreCms
* ProjectName:
* Web: https://www.corecms.net
* Author:
* Email: jianweie@163.com
* CreateTime: 2025/1/15 10:00:00
* Description:
***********************************************************************/
using System.ComponentModel.DataAnnotations;
namespace CoreCms.Net.Model.FromBody
{
/// <summary>
/// 设置发起者请求模型
/// </summary>
public class FMBecomeInitiator
{
/// <summary>
/// 预约ID
/// </summary>
[Display(Name = "预约ID")]
[Required(ErrorMessage = "请输入预约ID")]
public int reservationId { get; set; }
/// <summary>
/// 参与者ID
/// </summary>
[Display(Name = "参与者ID")]
[Required(ErrorMessage = "请输入参与者ID")]
public int participantId { get; set; }
/// <summary>
/// 用户ID
/// </summary>
[Display(Name = "用户ID")]
[Required(ErrorMessage = "请输入用户ID")]
public int userId { get; set; }
}
}

View File

@ -1194,5 +1194,214 @@ ICoreCmsUserServices userServices
}
#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
}
}

View File

@ -3824,6 +3824,24 @@
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQReservationsController.SearchUsers">
<summary>
搜索用户
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQReservationsController.AddParticipant(CoreCms.Net.Model.FromBody.FMAddParticipant)">
<summary>
添加参与者
</summary>
<returns></returns>
</member>
<member name="M:CoreCms.Net.Web.Admin.Controllers.SQReservationsController.BecomeInitiator(CoreCms.Net.Model.FromBody.FMBecomeInitiator)">
<summary>
设置发起者
</summary>
<returns></returns>
</member>
<member name="T:CoreCms.Net.Web.Admin.Controllers.SQRoomsController">
<summary>
房间表

View File

@ -204,7 +204,12 @@
{
title: '参与人员', sort: false, width: 300, templet: function (d) {
if (!d.participants || d.participants.length === 0) {
return '<div style="color: #999; font-style: italic;">暂无参与人员</div>';
return '<div style="margin-bottom: 5px;">' +
'<span style="background: #1E9FFF; color: white; padding: 2px 6px; border-radius: 3px; font-size: 12px; margin-right: 5px;">参与者</span>' +
'<span style="color: #666; font-size: 12px;">(0人)</span>' +
'<span style="background: #5FB878; color: white; padding: 2px 6px; border-radius: 3px; font-size: 12px; margin-left: 5px; cursor: pointer;" onclick="addParticipant(' + d.id + ')">添加参与者</span>' +
'</div>' +
'<div style="color: #999; font-style: italic;">暂无参与人员</div>';
}
var html = '<div style="line-height: 1.6;line-height: 1.6;overflow: auto;height: 100%;width: 100%;">';
@ -239,17 +244,20 @@
html += '</div>';
}
// 显示参与者
if (participants.length > 0) {
// 统计正常状态的参与者数量
var normalParticipantsCount = participants.filter(function (it) {
return it.status == 0;
}).length;
// 显示参与者标签(无论是否有参与者都要显示)
// 统计正常状态的参与者数量
var normalParticipantsCount = participants.filter(function (it) {
return it.status == 0;
}).length;
html += '<div style="margin-bottom: 5px;">';
html += '<span style="background: #1E9FFF; color: white; padding: 2px 6px; border-radius: 3px; font-size: 12px; margin-right: 5px;">参与者</span>';
html += '<span style="color: #666; font-size: 12px;">(' + normalParticipantsCount + '人)</span>';
html += '</div>';
html += '<div style="margin-bottom: 5px;">';
html += '<span style="background: #1E9FFF; color: white; padding: 2px 6px; border-radius: 3px; font-size: 12px; margin-right: 5px;">参与者</span>';
html += '<span style="color: #666; font-size: 12px;">(' + normalParticipantsCount + '人)</span>';
html += '<span style="background: #5FB878; color: white; padding: 2px 6px; border-radius: 3px; font-size: 12px; margin-left: 5px; cursor: pointer;" onclick="addParticipant(' + d.id + ')">添加参与者</span>';
html += '</div>';
// 显示参与者列表
if (participants.length > 0) {
participants.forEach(function (it, index) {
var statusText = '';
@ -264,14 +272,15 @@
html += '<div style="margin-left: 15px; margin-bottom: 8px; font-size: 12px; border-left: 2px solid #E6E6E6; padding-left: 8px;">';
html += '<div style="margin-bottom: 3px;">';
html += '<span style="color: #333; font-weight: 500;">' + (it.UserName || '用户' + it.user_id) + '</span>';
html += '<span style="color: #333; font-weight: 500;">' + (it.userName || '用户' + it.user_id) + '</span>';
html += '<span style="color: #999; margin-left: 5px;">(ID: ' + it.user_id + ')</span>';
if (statusText) {
html += '<span style="background: ' + statusColor + '; color: white; padding: 1px 4px; border-radius: 2px; font-size: 10px; margin-left: 5px;">' + statusText + '</span>';
}
// 当用户状态为正常时,显示强制退出按钮
// 当用户状态为正常时,显示强制退出按钮和成为发起者按钮
if (it.status == 0) {
html += '<span style="background: #FF5722; color: white; padding: 1px 4px; border-radius: 2px; font-size: 10px; margin-left: 5px; cursor: pointer;" onclick="forceExitParticipant(' + JSON.stringify(it).replace(/"/g, '&quot;') + ', ' + it.id + ')">强制退出</span>';
html += '<span style="background: #1E9FFF; color: white; padding: 1px 4px; border-radius: 2px; font-size: 10px; margin-left: 5px; cursor: pointer;" onclick="becomeInitiator(' + JSON.stringify(it).replace(/"/g, '&quot;') + ', ' + d.id + ')">成为发起者</span>';
}
html += '</div>';
@ -326,6 +335,9 @@
html += '</div>';
});
} else {
// 如果没有参与者,显示提示信息
html += '<div style="color: #999; font-style: italic; margin-left: 15px;">暂无参与人员</div>';
}
html += '</div>';
@ -724,4 +736,131 @@
});
});
}
// 添加参与者函数
function addParticipant(reservationId) {
// 弹出添加参与者窗口
layer.open({
type: 1,
title: '添加参与者',
area: ['800px', '600px'],
content: `
<div style="padding: 20px;">
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">查询用户</label>
<div class="layui-input-block">
<input type="text" id="searchUserInput" placeholder="请输入用户名或用户ID" class="layui-input" style="width: 300px; display: inline-block;">
<button class="layui-btn layui-btn-sm" onclick="searchUsers()" style="margin-left: 10px;">查询</button>
</div>
</div>
</div>
<div id="userTableContainer" style="margin-top: 20px;">
<table id="userTable" lay-filter="userTable"></table>
</div>
</div>
`,
success: function(layero, index) {
// 初始化用户表格
layui.use(['table'], function() {
var table = layui.table;
table.render({
elem: '#userTable',
url: layui.setter.apiUrl + 'Api/SQReservations/SearchUsers',
method: 'POST',
page: true,
limit: 10,
limits: [10, 20, 50],
cols: [[
{type: 'radio', fixed: 'left'},
{field: 'id', title: '用户ID', width: 80},
{field: 'userName', title: '用户名', width: 150},
{field: 'nickName', title: '昵称', width: 150},
{field: 'mobile', title: '手机号', width: 120},
{field: 'email', title: '邮箱', width: 200}
]],
done: function() {
// 监听行选择
table.on('radio(userTable)', function(obj) {
// 存储选中的用户
window.selectedUser = obj.data;
});
}
});
});
},
btn: ['确定', '取消'],
yes: function(index, layero) {
if (!window.selectedUser) {
layer.msg('请先选择一个用户', {icon: 2});
return;
}
// 确认添加参与者
layer.confirm('确定要添加用户 "' + window.selectedUser.userName + '" 为参与者吗?', {
icon: 3,
title: '确认添加'
}, function(confirmIndex) {
layer.close(confirmIndex);
// 调用API添加参与者
coreHelper.Post("Api/SQReservations/AddParticipant", {
reservationId: reservationId,
userId: window.selectedUser.id
}, function(e) {
if (e.code === 0) {
layer.msg('添加参与者成功', {icon: 1});
layer.close(index);
// 重新加载表格数据
layui.table.reloadData('LAY-app-SQReservations-tableBox');
} else {
layer.msg(e.msg || '添加失败', {icon: 2});
}
});
});
}
});
}
// 搜索用户函数
function searchUsers() {
var searchText = document.getElementById('searchUserInput').value.trim();
if (!searchText) {
layer.msg('请输入搜索内容', {icon: 2});
return;
}
// 重新加载用户表格
layui.table.reloadData('userTable', {
where: {
searchText: searchText
}
});
}
// 成为发起者函数
function becomeInitiator(participant, reservationId) {
layer.confirm('确定要将用户 "' + (participant.UserName || '用户' + participant.user_id) + '" 设置为发起者吗?', {
icon: 3,
title: '确认操作'
}, function(index) {
// 关闭确认框
layer.close(index);
// 调用API设置发起者
coreHelper.Post("Api/SQReservations/BecomeInitiator", {
reservationId: reservationId,
participantId: participant.id,
userId: participant.user_id
}, function(e) {
if (e.code === 0) {
layer.msg('设置发起者成功', {icon: 1});
// 重新加载表格数据
layui.table.reloadData('LAY-app-SQReservations-tableBox');
} else {
layer.msg(e.msg || '操作失败', {icon: 2});
}
});
});
}
</script>