введение
В серии статей о регистрации представлены некоторые распространенные реализации операций регистрации, в том числе签到
,补签
,签到任务
И т. д. Основными стеками технологий являются redis и mysql.В этой статье в основном обобщены некоторые проблемы, возникшие после запуска предыдущей функции регистрации, и некоторые итерации кода, вызванные изменением требований.
Ссылки на предыдущие статьиФункция входа для достижения Реализация функции входа 2
Требования и ошибки
и第一版
Требования для сравнения:
- Раньше апельсиновый сок при непрерывном входе запускался только при входе в систему, но теперь его также необходимо запускать при повторном входе.
- Предыдущий цикл входа был основан на месяцах, и не было ограничений на непрерывный вход. текущий месяц.
- Ранее не считалось, что количество дней регистрации после повторной подписи напрямую больше, чем триггерная точка количества последовательных дней регистрации, в результате чего вознаграждение за непрерывную регистрацию не активируется.
- Поскольку операция непрерывной регистрации монтируется асинхронно, клиент, вызывающий общий интерфейс апельсинового сока после регистрации или повторного подписания, не будет обновляться вовремя.
карта разума
Интеллект-карта после корректировки требований выглядит следующим образом:
Логическая сортировка и реализация
Ответьте на четыре вопроса выше, чтобы разобраться в логике кода перед корректировкой кода.
注:之前文章批注过的代码,此篇会用伪代码代替,可以翻看之前的文章查找以前的具体实现代码
Проверял в отделе апельсинового сока подряд раньше
//签到操作记录位图后传入用户id以及连续签到天数记录橙汁
public Boolean doSaveUserIntegral(int userId, int signContinuousCount) {
ListUserIntegralLog userIntegralLogList = new LinkedList();
//先记录本次签到橙汁2ML放入userIntegralLogList集合中等待后续写入
.....
//根据签到连续天数算出当前签到是否符合连续签到,查出奖励橙汁多少并放入userIntegralLogList集合中等待后续写入
.....
//更改个人总橙汁并批量写入橙汁记录
}
План трансформации
Сначала обратите внимание на предыдущий код, нормальные и непрерывные проверки складываются вместе, и нет никакой гарантии, что награда за непрерывную регистрацию в текущем месяце уникальна, поскольку требуется оценка непрерывной регистрации. для дополнительной регистрации необходимо снять часть решения о непрерывной регистрации.
Извлеките решение о непрерывной регистрации и аккумулируйте общую часть апельсинового сока.
// 入参部分,userIntegralLogList 为橙汁记录表的集合,count 为总橙汁增减量,userId 用户id,signContinuousCount 连续签到天数
public void doSaveContinuousIntegral(List<UserIntegralLog> userIntegralLogList, int count, int userId, int signContinuousCount) {
//首先得到这个月的最大天数
int monthLength = LocalDate.now().lengthOfMonth();
//初始化最大满足连续签到次数
int times = 0;
//定义一个数组,存放连续天数满足条件,这个如果需要灵活配置也可放入缓存中.
//我们的时间节点是5天,7天,15天,满月.因为满月无法确定天数所以写做32特殊值
String[] continuousDays = {"5", "7", "15", "32"};
//如果是满月的情况就会有4次命中连续签到,分别为5,7,15,32
//连续签到大于15天的话应该是3次命中,5,7,15
//后面依次类推....
if (signContinuousCount == monthLength) times = 4;
else if (signContinuousCount >= 15) times = 3;
else if (signContinuousCount >= 7) times = 2;
else if (signContinuousCount >= 5) times = 1;
else return;
//连续签到处理,获取缓存配置连续签到奖励
Map<String, String> configurationHashMap = cacheClient.hgetAll("userSign:configuration");
//取出库中连续签到的签到记录类型,周期是一个月.这样就可以查到他连续签到这个月触发了几次.
String startTime = DateUtil.getThisMonthFirstDay().toString();
String endTime = DateUtil.getThisMonthLastDay().toString();
int timesInDb = userIntegralLogService.selectSignByTime(userId, startTime, endTime);
//定义循环,次数为他连续签到次数最大命中次数
for (int i = 0; i < times; i++) {
//当库中存在的条数不为0,则需要-1并跳过这次循环
//如这个月签到连续次数为7,之前签到满了5天给了奖励,这里timesInDb查出为1,然后我们不希望出现重复的奖励,timesInDb-1且跳过这次循环,只记录满7天的这一次奖励
//注:这样设计是因为补签可能为中间的断层,如签到了1,2,3,4,6,7,8,这样如果补签第5天的时候,就会给用户满5天和满7天的奖励,这样写就可以兼容补签和普通签到的逻辑回路
if (timesInDb!= 0) {
timesInDb--;
continue;
}
//后面就是正常的构造橙汁记录表,加入集合中,并叠加count总橙汁
String configuration = configurationHashMap.get(continuousDays[i]);
if (null != configuration) {
JSONObject item = JSONObject.parseObject(configuration);
int giveIntegral = item.getInteger("integral");
if (giveIntegral != 0) {
userIntegralLogList.add(UserIntegralLog.builder()
.createTime(LocalDateTime.now())
.bak(String.format(BusinessConstant.Integral.CONTINUOUS_SIGN_COPY, Integer.parseInt(continuousDays[i])))
.integral(giveIntegral)
.integralType(BusinessConstant.Integral.SIGN_TYPE_CONTINUOUS)
.userId(userId)
.build());
count += giveIntegral;
}
}
}
}
раздел selectSignByTime Dao
@Select("SELECT count(1) from t_user_integral_log where integral_type=2 and user_id=#{userId} and STR_TO_DATE( create_time, '%Y-%m-%d' ) BETWEEN #{startTime} AND #{endTime}")
int selectSignByTime(@Param("userId") int userId, @Param("startTime") String startTime, @Param("endTime") String endTime);
Изменить исходный метод входа
Чтобы решить проблему асинхронного запроса общего апельсинового сока, этот метод был изменен с асинхронного на синхронный.
public Boolean doSaveUserIntegral(int userId, int signContinuousCount) {
int count = 0;
List<UserIntegralLog> userIntegralLogList = new LinkedList<>();
userIntegralLogList.add(UserIntegralLog.builder()
.createTime(LocalDateTime.now())
.operationTime(LocalDate.now())
.bak(BusinessConstant.Integral.NORMAL_SIGN_COPY)
.integral(BusinessConstant.Integral.SIGN_TYPE_NORMAL_INTEGRAL)
.integralType(BusinessConstant.Integral.SIGN_TYPE_NORMAL)
.userId(userId)
.build());
count += BusinessConstant.Integral.SIGN_TYPE_NORMAL_INTEGRAL;
//这就是我们新拆解的方法,抽离连续签到判断以及累加总橙汁部分
doSaveContinuousIntegral(userIntegralLogList, count, userId, signContinuousCount);
// 累加总橙汁和批量写入橙汁记录
return updateUserIntegralCount(userId, count) && userIntegralLogService.saveBatch(userIntegralLogList);
}
Добавлен код обработки для дополнительной части подписи
public Boolean doSaveUserRetroactiveIntegral(int userId, int signContinuousCount) {
List<UserIntegralLog> userIntegralLogList = new LinkedList<>();
int count = 0;
doSaveContinuousIntegral(userIntegralLogList, count, userId, signContinuousCount);
return updateUserIntegralCount(userId, count) && userIntegralLogService.saveBatch(userIntegralLogList);
}
И вызовите этот метод в конце предыдущего метода регистрации, чтобы завершить логику регистрации, запускающей непрерывные вознаграждения за вход.
постскриптум
Давайте рассмотрим предыдущие потребности и проблемы.
- Проблемы 1 и 2 решаются путем извлечения метода doSaveContinuousIntegral и добавления оценки количества раз хранения в каждой оценке.
- Вопрос 3. Изменив диапазон соответствия с == на >=, вычислите общее количество последовательных чекинов, которые необходимо записать, а затем вычтите количество раз, записанных в библиотеке, чтобы непрерывный чекин стал оценка дальности вместо предыдущего точного значения.
- Вопрос 4. Так как в нем не так много вычислений, асинхронность убрана.Эта проблема не возникнет, если используется синхронный метод.
Благодаря этому исправлению я понимаю, что написание кода - это процесс непрерывного совершенствования. Его нельзя усовершенствовать за одну разработку. Необходимо постоянно думать о проблемах из практики и стараться улучшать качество кода навыками, чтобы продолжать улучшить. Наконец祝大家的需求都不会大改
.Ха-ха