setConnect($user_id)->where('user_id', 'eq', $user_id)->where('kandian', '>', 0)->order("id desc")->select(); if ($rows) { $remain = $kandian; foreach ($rows as $row) { if ($remain >0) { if ($row['kandian'] <= $remain) { $row->save(['remain_kandian' => $row['kandian']]); $remain = $remain-$row['kandian']; Log::info("刷新永久书币 用户:{$user_id} 永久剩余书币 充值记录:{$row['id']} 插入:{$row['kandian']},待处理书币:{$remain}"); } else { $row->save(['remain_kandian' => $remain]); Log::info("刷新永久书币 用户:{$user_id} 永久剩余书币 充值记录:{$row['id']} 插入:{$remain},待处理书币:0"); $remain = 0; Log::info("刷新永久书币 用户:{$user_id} 永久剩余书币 已全部处理"); } } else { if ($row['remain_kandian'] >0) { $row->save(['remain_kandian' => 0]); } } } } else { Log::info("刷新永久书币 用户:{$user_id} 永久剩余书币 没有充值记录"); } $cacheKey = CacheConstants::getKandianUserRechargeListCacheKey($user_id); Redis::instance()->del($cacheKey); return true; } /** * 刷新用户的消费记录 * @param $user_id */ public function flushUserConsume($user_id) { //拉出所有的充值记录 排好序 $rechargeRows = model("Recharge")->setConnect($user_id)->where('user_id', 'eq', $user_id)->where('vip_starttime', 'exp', 'is null')->order('id asc')->select(); if (empty($rechargeRows)) { Log::info("刷用户消费记录 用户:{$user_id} 没找到充值记录"); return true; } //扣除负数的永久书币 for ($i = 0; $i< count($rechargeRows); $i++) { if ($rechargeRows[$i]['kandian'] < 0) { //负的的 往前扣 $j = $i; $kandian = abs($rechargeRows[$i]['kandian']); while ($j > 0) { if ($kandian <= 0) { break; } if ($rechargeRows[$j]['kandian'] > 0) { if ($kandian >= $rechargeRows[$j]['kandian']) { //不够扣 $kandian = $kandian - $rechargeRows[$j]['kandian']; $rechargeRows[$j]['kandian'] = 0; } else { //够 $rechargeRows[$j]['kandian'] = $rechargeRows[$j]['kandian'] - $kandian; $kandian = 0; } } $j--; } } } //找出所有的消费记录 从前向后 model("Consume")->setConnect($user_id)->where('user_id', 'eq', $user_id)->chunk(100, function ($consumeRows) use (&$rechargeRows, $user_id) { if (count($consumeRows) > 0) { $stop = false; foreach ($consumeRows as $consumeRow) { $currentConsumeId = $consumeRow['id']; if (count($rechargeRows) <=0) { Log::error("刷用户消费记录 用户:{$user_id} 充值记录不够扣"); break; } $ddFreeKandian = $ddKandian = 0; //找出当时所有免费书币和永久书币 if ($consumeRow['free_kandian']) { Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 免费书币:{$consumeRow['free_kandian']} 开始进行"); //消耗的是免费看点 $remain = $consumeRow['free_kandian']; foreach ($rechargeRows as $key =>$rechargeRow) { if ($rechargeRow['free_kandian'] == 0) { //说明不是免费书币记录 continue; } if ($rechargeRow['free_endtime'] < $consumeRow['createtime']){ continue; } if ($remain > $rechargeRow['free_kandian']) { //不够扣的 if ($rechargeRow['dd'] == 1) { //扣量赠送书币 $ddFreeKandian += $rechargeRow['free_kandian']; Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 免费书币:{$consumeRow['free_kandian']} 刷入扣量免费书币:{$rechargeRow['free_kandian']} 对应充值记录:{$rechargeRow['id']}:当前0"); }else{ Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 免费书币:{$consumeRow['free_kandian']} 刷入免费书币:{$rechargeRow['free_kandian']} 对应充值记录:{$rechargeRow['id']}:当前0"); } $remain -= $rechargeRow['free_kandian']; $rechargeRow['free_kandian'] = 0; unset($rechargeRows[$key]); } else { //够扣 $rechargeRow['free_kandian'] = $rechargeRow['free_kandian'] - $remain; if ($rechargeRow['dd'] == 1) { //扣量赠送书币 $ddFreeKandian += $remain; Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 免费书币:{$consumeRow['free_kandian']} 刷入扣量免费书币:{$remain} 对应充值记录:{$rechargeRow['id']}:当前{$rechargeRow['free_kandian']}"); }else{ Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 免费书币:{$consumeRow['free_kandian']} 刷入免费书币:{$remain} 对应充值记录:{$rechargeRow['id']}:当前{$rechargeRow['free_kandian']}"); } //扣完删除 if ($rechargeRow['free_kandian'] == 0) { unset($rechargeRows[$key]); } break; } } } if ($consumeRow['kandian']) { //永久看点 $remain = $consumeRow['kandian']; Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 永久书币:{$consumeRow['kandian']} 开始进行"); foreach ($rechargeRows as $key =>$rechargeRow) { if ($rechargeRow['free_kandian'] > 0) { //免费的跳过 continue; } if ($rechargeRow['kandian'] <=0) { //负的 删掉 unset($rechargeRows[$key]); continue; } if ($remain > $rechargeRow['kandian']) { //不够扣的 if ($rechargeRow['dd'] == 1) { //扣量永久书币 $ddKandian += $rechargeRow['kandian']; Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 永久书币:{$consumeRow['kandian']} 刷入扣量永久书币:{$rechargeRow['kandian']} 对应充值记录:{$rechargeRow['id']}"); } $remain = $remain - $rechargeRow['kandian']; $rechargeRow['kandian'] = 0; unset($rechargeRows[$key]); } else { //够扣 $rechargeRow['kandian'] = $rechargeRow['kandian'] - $remain; if ($rechargeRow['dd'] == 1) { //扣量赠送书币 $ddKandian += $remain; Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 永久书币:{$consumeRow['kandian']} 刷入扣量永久书币:{$remain} 对应充值记录:{$rechargeRow['id']}"); } //扣完删除 if ($rechargeRow['kandian'] == 0) { unset($rechargeRows[$key]); } break; } } } $consumeRow->save(['dd_kandian' => $ddKandian, 'dd_free_kandian' => $ddFreeKandian]); Log::info("刷用户消费记录 用户:{$user_id} ID:{$currentConsumeId} 永久书币:{$consumeRow['kandian']} 刷入扣量永久书币:{$ddKandian} 免费书币:{$consumeRow['free_kandian']} 刷入扣量免费书币:{$ddFreeKandian}"); } unset($consumeRows); if ($stop) { return false; } } else { return false; } }, 'id', 'asc'); foreach ($rechargeRows as $key => $rechargeRow) { if ($rechargeRow['free_kandian'] != $rechargeRow['remain_free_kandian']) { model("Recharge")->setConnect($user_id) ->update(['remain_free_kandian' => $rechargeRow['free_kandian']], ['id' => $rechargeRow['id']]); LogService::info('错误回滚:' . $rechargeRow['id'] . ':' . $rechargeRow['free_kandian'] . ':' . $rechargeRow['remain_free_kandian']); } } } /** * 重置用户状态 * @param $user_id * @return bool */ public function checkUserFlushState($user_id) { $userInfo = UserService::instance()->getUserModel()->getUserInfo($user_id); if ($userInfo) { try { $userInfo['flush_state'] = $userInfo['flush_state'] ?? UserConstants::USER_FLUSH_STATE_ORIGIN; if ($userInfo['flush_state'] == UserConstants::USER_FLUSH_STATE_ORIGIN) { $this->flushRechargeDd($user_id); $kandianLeft = FinancialService::instance()->getTotalRemainKandian($user_id)->data; //时间差用户 全量跑recharge表 if ($kandianLeft > 0) { $this->flushUserRechargeRemainKandian($user_id, $kandianLeft); } UserService::instance()->update(['flush_state' => UserConstants::USER_FLUSH_STATE_READ], ['id' => $user_id]); // model("User")->setConnect($user_id)->update(['flush_state' => UserConstants::USER_FLUSH_STATE_READ], ['id' => $user_id]); // Redis::instance()->del('UN:'.$user_id); } else if ($userInfo['flush_state'] == UserConstants::USER_FLUSH_STATE_COMMAND) { $this->flushRechargeDd($user_id); $kandianLeft = FinancialService::instance()->getTotalRemainKandian($user_id)->data; $kandian = FinancialService::instance()->getTotalKandian($user_id)->data; if ($kandianLeft != $kandian) { //需要重刷 $this->flushUserRechargeRemainKandian($user_id, $kandianLeft); } UserService::instance()->update(['flush_state' => UserConstants::USER_FLUSH_STATE_READ], ['id' => $user_id]); // model("User")->setConnect($user_id)->update(['flush_state' => UserConstants::USER_FLUSH_STATE_READ], ['id' => $user_id]); // Redis::instance()->del('UN:'.$user_id); } } catch (Exception $e) { Log::info("刷用户剩余永久书币异常 用户ID:{$user_id}"); LogService::exception($e); } } return true; } /** * 设置渠道vip时间 * @param $user_id */ public function flushVip($user_id) { $db = FinancialService::instance()->getRechargeModel() ->setConnect($user_id); $list = $db ->where('user_id', $user_id) ->whereIn('type', [OrderContents::RECHARGE_TYPE_VIP, OrderContents::RECHARGE_TYPE_SYS_VIP]) ->where('dd', OrderContents::ORDER_DEDUCT_NO) ->order('id', 'asc') ->select(); if ($list) { foreach ($list as $index=>$currentRecharge) { if (!$index) { $db->update(['channel_vip_starttime' => $currentRecharge['createtime']], ['id' => $currentRecharge['id']]); } else { $days = intval($list[$index - 1]['day']); $hours = intval($list[$index - 1]['hour']); $preEndTime = $list[$index - 1]['channel_vip_starttime'] + $days * 86400 + $hours * 3600; if ($currentRecharge['createtime'] > $preEndTime) { $db->update(['channel_vip_starttime' => $currentRecharge['createtime']], ['id' => $currentRecharge['id']]); } else { $db->update(['channel_vip_starttime' => $preEndTime], ['id' => $currentRecharge['id']]); } } } } } /** * 更新充值的dd字段 * @param $user_id */ public function flushRechargeDd($user_id) { $orders = OrderService::instance()->getOrderModel() ->where('user_id', $user_id) ->where('state', OrderContents::ORDER_STATE_PAID) ->where('deduct', OrderContents::ORDER_DEDUCT_YES) ->select(); $rechargeIds = []; if ($orders) { foreach ($orders as $order) { $res = FinancialService::instance()->getRechargeModel() ->setConnect($user_id) ->field('id, createtime') ->where('user_id', $user_id) ->where('type', $order['type']) ->where('createtime', '>=', $order['finishtime']) ->order('createtime', 'asc') ->limit(0, 2) ->select(); if (count($res) == 1) { $rechargeIds[] = $res[0]['id']; } elseif (count($res) == 2) {//用一个用户,2个recharge记录相差2s以内算作一个订单的充值 $sub = abs($res[0]['createtime'] - $res[1]['createtime']); if ($sub < 3) { $rechargeIds[] = $res[0]['id']; $rechargeIds[] = $res[1]['id']; } else { $rechargeIds[] = $res[0]['id']; } } } } if ($rechargeIds) { FinancialService::instance()->getRechargeModel() ->setConnect($user_id) ->whereIn('id', $rechargeIds) ->update(['dd' => OrderContents::ORDER_DEDUCT_YES]); LogService::info('用户充值信息更新:' . json_encode($rechargeIds, JSON_UNESCAPED_UNICODE)); } } }