public ActionResult MakeReservation([FromBody] ReservationViewModel model)
        {
            var result = new JsonResultModel();

            try
            {
                if (ModelState.IsValid)
                {
                    string msg;
                    if (!HttpContext.RequestServices.GetService <ReservationHelper>().IsReservationAvailable(model, out msg))
                    {
                        result.ErrorMsg = msg;
                        return(Json(result));
                    }

                    var reservation = new Reservation()
                    {
                        ReservationForDate = model.ReservationForDate,
                        ReservationForTime = model.ReservationForTime,
                        ReservationPlaceId = model.ReservationPlaceId,

                        ReservationUnit            = model.ReservationUnit,
                        ReservationActivityContent = model.ReservationActivityContent,
                        ReservationPersonName      = model.ReservationPersonName,
                        ReservationPersonPhone     = model.ReservationPersonPhone,

                        ReservationFromIp = HttpContext.Connection.RemoteIpAddress.ToString(), //记录预约人IP地址

                        UpdateBy      = model.ReservationPersonName,
                        UpdateTime    = DateTime.Now,
                        ReservationId = Guid.NewGuid()
                    };
                    //TODO:验证最大可预约时间段,同一个手机号,同一个IP地址
                    // 需要验证这种预约判断是否可以通用,可能有bug
                    foreach (var item in model.ReservationForTimeIds.Split(',').Select(_ => Convert.ToInt32(_)))
                    {
                        reservation.ReservationPeriod += (1 << item);
                    }
                    var bValue = _reservertionBLL.Insert(reservation);
                    if (bValue > 0)
                    {
                        result.Result = true;
                        result.Status = JsonResultStatus.Success;
                    }
                    else
                    {
                        result.ErrorMsg = "预约失败";
                        result.Status   = JsonResultStatus.ProcessFail;
                    }
                    return(Json(result));
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                result.Status   = JsonResultStatus.ProcessFail;
                result.ErrorMsg = ex.Message;
            }
            return(Json(result));
        }
Esempio n. 2
0
        /// <summary>
        /// 新建预约
        /// </summary>
        /// <param name="reservation">预约信息</param>
        /// <param name="msg">预约错误提示信息</param>
        /// <param name="isAdmin">是否是管理员预约</param>
        /// <returns></returns>
        public bool MakeReservation(ReservationViewModel reservation, out string msg,
                                    bool isAdmin = false)
        {
            if (reservation == null ||
                string.IsNullOrEmpty(reservation.ReservationPersonName) ||
                string.IsNullOrEmpty(reservation.ReservationPersonPhone) ||
                string.IsNullOrEmpty(reservation.ReservationForTimeIds) ||
                Guid.Empty == reservation.ReservationPlaceId)
            {
                msg = "预约信息不完整";
                return(false);
            }
            if (IsReservationInfoInBlockList(reservation, out msg))
            {
                return(false);
            }
            var reservationForDate = reservation.ReservationForDate;

            if (!IsReservationForDateAvailable(reservationForDate, isAdmin, out msg))
            {
                return(false);
            }

            using (var redisLock = RedisManager.GetRedLockClient($"reservation:{reservation.ReservationPlaceId:N}:{reservation.ReservationForDate:yyyyMMdd}"))
            {
                if (redisLock.TryLock())
                {
                    if (!IsReservationForPeriodAvailable(reservationForDate, reservation.ReservationPlaceId, reservation.ReservationForTimeIds))
                    {
                        msg = "预约时间段冲突,请重新选择预约时间段";
                        return(false);
                    }

                    var reservationEntity = new Reservation()
                    {
                        ReservationForDate = reservation.ReservationForDate,
                        ReservationForTime = reservation.ReservationForTime,
                        ReservationPlaceId = reservation.ReservationPlaceId,

                        ReservationUnit            = reservation.ReservationUnit,
                        ReservationActivityContent = reservation.ReservationActivityContent,
                        ReservationPersonName      = reservation.ReservationPersonName,
                        ReservationPersonPhone     = reservation.ReservationPersonPhone,
                        ReservationFromIp          = DependencyResolver.Current.ResolveService <IHttpContextAccessor>().HttpContext.GetUserIP(),

                        UpdateBy      = reservation.ReservationPersonName,
                        UpdateTime    = DateTime.UtcNow,
                        ReservationId = Guid.NewGuid()
                    };
                    //验证最大可预约时间段,同一个手机号,同一个IP地址
                    foreach (var item in reservation.ReservationForTimeIds.Split(',').Select(_ => Convert.ToInt32(_)))
                    {
                        reservationEntity.ReservationPeriod += (1 << item);
                    }
                    if (isAdmin)
                    {
                        reservationEntity.ReservationStatus = ReservationStatus.Reviewed;
                    }
                    _bllReservation.Insert(reservationEntity);

                    return(true);
                }
                else
                {
                    msg = "系统繁忙,请稍后重试!";
                    return(false);
                }
            }
        }
        /// <summary>
        /// 新建预约
        /// </summary>
        /// <param name="reservation">预约信息</param>
        /// <param name="msg">预约错误提示信息</param>
        /// <param name="isAdmin">是否是管理员预约</param>
        /// <returns></returns>
        public bool MakeReservation(ReservationViewModel reservation, out string msg,
                                    bool isAdmin = false)
        {
            if (reservation == null ||
                string.IsNullOrEmpty(reservation.ReservationPersonName) ||
                string.IsNullOrEmpty(reservation.ReservationPersonPhone) ||
                string.IsNullOrEmpty(reservation.ReservationForTimeIds) ||
                Guid.Empty == reservation.ReservationPlaceId)
            {
                msg = "预约信息不完整";
                return(false);
            }
            if (IsReservationInfoInBlockList(reservation, out msg))
            {
                return(false);
            }
            var reservationForDate = reservation.ReservationForDate;

            if (!IsReservationForDateAvailable(reservationForDate, isAdmin, out msg))
            {
                return(false);
            }

            var reservationKey =
                $"reservation:{reservation.ReservationPlaceId:N}:{reservation.ReservationForDate:yyyyMMdd}";

            var redis = DependencyResolver.Current.GetService <IDatabase>();

            if (redis != null)
            {
                using (var redisLock = RedisManager.GetRedLockClient(reservationKey))
                {
                    if (redisLock.TryLock())
                    {
                        return(CheckInner(out msg));
                    }
                    else
                    {
                        msg = "系统繁忙,请稍后重试!";
                        return(false);
                    }
                }
            }

            lock (reservationKey)
            {
                return(CheckInner(out msg));
            }

            bool CheckInner(out string errorMsg)
            {
                if (!IsReservationForPeriodAvailable(reservationForDate, reservation.ReservationPlaceId, reservation.ReservationForTimeIds))
                {
                    errorMsg = "预约时间段冲突,请重新选择预约时间段";
                    return(false);
                }

                var context = DependencyResolver.ResolveService <IHttpContextAccessor>().HttpContext;
                var userId  = context.User.GetUserId <Guid>();

                if (!isAdmin)
                {
                    if (_bllReservation.Count(r =>
                                              r.ReservedBy == userId &&
                                              r.ReservationTime.AddHours(8).Date == DateTime.UtcNow.AddHours(8).Date
                                              ) >= MaxReservationCount)
                    {
                        errorMsg = "今日预约已达上限,请明日再约";
                        return(false);
                    }
                }

                var reservationEntity = new Reservation()
                {
                    ReservationForDate = reservation.ReservationForDate,
                    ReservationForTime = reservation.ReservationForTime,
                    ReservationPlaceId = reservation.ReservationPlaceId,

                    ReservationUnit            = reservation.ReservationUnit,
                    ReservationActivityContent = reservation.ReservationActivityContent,
                    ReservationPersonName      = reservation.ReservationPersonName,
                    ReservationPersonPhone     = reservation.ReservationPersonPhone,
                    ReservationFromIp          = context.GetUserIP(),

                    ReservedBy = userId,

                    UpdateBy        = reservation.ReservationPersonName,
                    ReservationTime = DateTime.UtcNow,
                    UpdateTime      = DateTime.UtcNow,
                    ReservationId   = Guid.NewGuid()
                };

                //验证最大可预约时间段,同一个手机号,同一个IP地址
                foreach (var item in reservation.ReservationForTimeIds.SplitArray <int>())
                {
                    reservationEntity.ReservationPeriod += (1 << item);
                }
                if (isAdmin)
                {
                    reservationEntity.ReservationStatus = ReservationStatus.Reviewed;
                }
                _bllReservation.Insert(reservationEntity);
                errorMsg = string.Empty;
                return(true);
            }
        }