【修复】修复日历签到连续签到的统计错误的问题,增加用户签到redis锁。

This commit is contained in:
大灰灰
2022-10-21 14:26:00 +08:00
parent c88951e1f3
commit c8175d1090
2 changed files with 74 additions and 25 deletions

View File

@@ -67,15 +67,45 @@ namespace CoreCms.Net.Services
var jm = new AdminUiCallBack(); var jm = new AdminUiCallBack();
try try
{ {
var dt = DateTime.Now;
var dtStr = dt.ToString("yyyy-MM-dd");
var checkDataStr = entity.checkInData.ToString("yyyy-MM-dd");
if (dtStr != checkDataStr)
{
jm.msg = "签到日期不符,签到提交日期非今日";
return jm;
}
var id = await _dal.InsertAsync(entity); var id = await _dal.InsertAsync(entity);
var userCheckIn = await _userCheckInServices.QueryByClauseAsync(p => p.userId == entity.userId); var userCheckIn = await _userCheckInServices.QueryByClauseAsync(p => p.userId == entity.userId);
if (userCheckIn != null) if (userCheckIn != null)
{ {
userCheckIn.continuousCheckInCount += 1; //累计签到
userCheckIn.cumulativeCheckInCount += 1; userCheckIn.cumulativeCheckInCount += 1;
//判断是否是连续签到
//判断是否是连续签到逻辑是获取用户最后一次的签到记录检查查询到的签到记录的checkInData是不是昨天的checkInData是的话就是连续签到continuousCheckInCount++,不是的话就是断签了continuousCheckInCount设置成1重新开始就行了。
var lastCheck = await _dal.QueryByClauseAsync(p => p.id < id, true);
if (lastCheck == null)
{
userCheckIn.continuousCheckInCount = 1;
}
else
{
var yesterdayDataStr = dt.AddDays(-1).ToString("yyyy-MM-dd");
var lastCheckDataStr = lastCheck.checkInData.ToString("yyyy-MM-dd");
if (yesterdayDataStr == lastCheckDataStr)
{
//累加
userCheckIn.continuousCheckInCount += 1;
}
else
{
//重置
userCheckIn.continuousCheckInCount = 1;
}
}
await _userCheckInServices.UpdateAsync(userCheckIn); await _userCheckInServices.UpdateAsync(userCheckIn);
} }
else else

View File

@@ -1,7 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using CoreCms.Net.Auth.HttpContextUser; using CoreCms.Net.Auth.HttpContextUser;
using CoreCms.Net.Caching.AutoMate.RedisCache;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository; using CoreCms.Net.IRepository;
using CoreCms.Net.IServices; using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities; using CoreCms.Net.Model.Entities;
@@ -22,17 +25,17 @@ namespace CoreCms.Net.Web.WebApi.Controllers
{ {
private readonly ICoreCmsUserCheckInDetailsServices _userCheckInDetailsServices; private readonly ICoreCmsUserCheckInDetailsServices _userCheckInDetailsServices;
private readonly IHttpContextUser _user; private readonly IHttpContextUser _user;
private readonly IRedisOperationRepository _redisOperationRepository;
//简单的异步锁
private readonly AsyncLock _mutex = new AsyncLock();
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
/// </summary> /// </summary>
public CheckInController(IHttpContextUser user, ICoreCmsUserCheckInDetailsServices userCheckInDetailsServices) public CheckInController(IHttpContextUser user, ICoreCmsUserCheckInDetailsServices userCheckInDetailsServices, IRedisOperationRepository redisOperationRepository)
{ {
_user = user; _user = user;
_userCheckInDetailsServices = userCheckInDetailsServices; _userCheckInDetailsServices = userCheckInDetailsServices;
_redisOperationRepository = redisOperationRepository;
} }
@@ -44,27 +47,48 @@ namespace CoreCms.Net.Web.WebApi.Controllers
[Authorize] [Authorize]
public async Task<WebApiCallBack> DoUserCheckIn([FromBody] FMDoUserCheckIn entity) public async Task<WebApiCallBack> DoUserCheckIn([FromBody] FMDoUserCheckIn entity)
{ {
using (await _mutex.LockAsync()) var jm = new WebApiCallBack();
var lockKey = "LOCK_DoUserCheckIn:user_" + _user.ID;
var lockHolder = Guid.NewGuid().ToString("N"); //锁持有者
var redisUserLock = await _redisOperationRepository.LockTakeAsync(lockKey, lockHolder, TimeSpan.FromSeconds(5));
if (redisUserLock)
{ {
var jm = new WebApiCallBack(); try
var isHave = await _userCheckInDetailsServices.ExistsAsync(p => p.userId == _user.ID && p.checkInData == entity.date);
if (isHave)
{ {
jm.msg = "今日您已签到"; var isHave = await _userCheckInDetailsServices.ExistsAsync(p => p.userId == _user.ID && p.checkInData == entity.date);
if (isHave)
{
jm.msg = "今日您已签到";
return jm;
}
var detail = new CoreCmsUserCheckInDetails
{
userId = _user.ID,
checkInData = entity.date,
createTime = DateTime.Now
};
var callBack = await _userCheckInDetailsServices.DoCheckIn(detail);
jm.status = callBack.code == 0;
jm.msg = callBack.msg;
jm.data = callBack.data;
return jm; return jm;
} }
var detail = new CoreCmsUserCheckInDetails catch (Exception e)
{ {
userId = _user.ID, jm.msg = "数据处理异常";
checkInData = entity.date, jm.otherData = e;
createTime = DateTime.Now }
}; finally
var callBack = await _userCheckInDetailsServices.DoCheckIn(detail); {
jm.status = callBack.code == 0; await _redisOperationRepository.LockReleaseAsync(lockKey, lockHolder);
jm.msg = callBack.msg; }
jm.data = callBack.data;
return jm;
} }
else
{
jm.msg = "当前请求太频繁_请稍后再试";
}
return jm;
} }
/// <summary> /// <summary>
@@ -101,12 +125,7 @@ namespace CoreCms.Net.Web.WebApi.Controllers
var list = await _userCheckInDetailsServices.QueryListByClauseAsync(p => p.userId == _user.ID && p.checkInData > min && p.checkInData < max); var list = await _userCheckInDetailsServices.QueryListByClauseAsync(p => p.userId == _user.ID && p.checkInData > min && p.checkInData < max);
var stringArr = new List<string>(); var stringArr = list.Select(item => item.checkInData.ToString("yyyy-MM-dd")).ToList();
foreach (var item in list)
{
var stringStr = item.checkInData.ToString("yyyy-MM-dd");
stringArr.Add(stringStr);
}
jm.status = true; jm.status = true;
jm.data = stringArr; jm.data = stringArr;