Commit 5db8632e by 杨树贤

签到服务

parent a08abd05
<?php
namespace App\Http\Controllers;
use App\Http\Filters\CheckInFilter;
use App\Models\CheckIn;
use App\Models\ExchangeSetting;
use App\Models\Integral;
use App\Models\UserIntegral;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class CheckInController extends Controller
{
public function index(Request $request, CheckIn $checkIn, CheckInFilter $filter)
{
$page = $request->has('page') ? $request->page : self::DEFAULT_PAGE;
$pageSize = $request->has('page_size') ? $request->page_size : self::DEFAULT_PAGE_SIZE;
$checkIns = $checkIn->getCheckInList($page, $pageSize, $filter);
return $this->Export(0, 'ok', $checkIns);
}
public function store(Request $request, CheckIn $checkIn)
{
$data = [
'user_id' => $request->user_id,
'add_time' => time(),
];
$canCheckIn = $checkIn->canCheckInFromRedis($data['user_id']);
if (!$canCheckIn) {
return $this->Export(ErrorCode(1, 1), '今天已签到,无法再进行签到');
} else {
$res = $checkIn->addCheckIn($data);
if ($res) {
return $this->Export(0, 'ok');
} else {
return $this->Export(ErrorCode(18, 5), '新增签到记录失败');
}
}
}
}
\ No newline at end of file
...@@ -10,17 +10,59 @@ class Controller extends BaseController ...@@ -10,17 +10,59 @@ class Controller extends BaseController
const DEFAULT_PAGE_SIZE = 10; const DEFAULT_PAGE_SIZE = 10;
const DEFAULT_PAGE = 1; const DEFAULT_PAGE = 1;
public function Export( $Errcode=0,$ErrMsg='', $dataArr=[]) { //错误码基础常量列表
if(!empty($dataArr) && !is_array($dataArr)) { const CREATE_INTEGRAL_FAIL = 1;
const UPDATE_INTEGRAL_FAIL = 2;
const DELETE_INTEGRAL_FAIL = 3;
const BATCH_UPDATE_INTEGRAL_STATUS_FAIL = 4;
const UPDATE_INTEGRAL_STATUS_FAIL = 5;
const CREATE_USER_INTEGRAL_BILL_FAIL = 6;
const UPDATE_USER_INTEGRAL_BILL_FAIL = 7;
const DELETE_USER_INTEGRAL_BILL_FAIL = 8;
const UPDATE_USER_INTEGRAL_STATUS_FAIL = 9;
const BATCH_UPDATE_USER_INTEGRAL_STATUS_FAIL = 10;
//新增兑换商品项目失败
const ADD_EXCHANGE_SETTING_FAIL = 11;
//更新兑换商品项目失败
const UPDATE_EXCHANGE_SETTING_FAIL = 12;
//删除兑换商品项目失败
const DELETE_EXCHANGE_SETTING_FAIL = 13;
//修改兑换商品项目可使用状态失败
const UPDATE_EXCHANGE_SETTING_STATUS_FAIL = 14;
//批量更新兑换商品项目可使用状态失败
const BATCH_UPDATE_EXCHANGE_SETTING_STATUS_FAIL = 15;
//审核用户兑换失败
const AUDIT_USER_EXCHANGE_FAIL = 16;
//审核批量拒绝兑换失败
const BATCH_AUDIT_REJECT_USER_EXCHANGE = 17;
//新增签到记录失败
const ADD_CHECK_IN_FAIL = 18;
public function Export($Errcode = 0, $ErrMsg = '', $dataArr = [])
{
if (!empty($dataArr) && !is_array($dataArr)) {
$Errcode = -1; $Errcode = -1;
$ErrMsg = '系统错误'; $ErrMsg = '系统错误';
} }
$data=['errcode'=>$Errcode, 'errmsg'=>$ErrMsg]; $data = ['errcode' => $Errcode, 'errmsg' => $ErrMsg];
if(($data['errcode'] < 10000 || $data['errcode'] >= 50000) && $data['errcode'] !==0 )//非正常返回码,上报 if (($data['errcode'] < 10000 || $data['errcode'] >= 50000) && $data['errcode'] !== 0)//非正常返回码,上报
ErrorLog($Errcode,$ErrMsg); {
ErrorLog($Errcode, $ErrMsg);
}
if (!empty($dataArr)) {
foreach ($dataArr as $k => $v) {
$data[$k] = $v;
}
}
if(!empty($dataArr)) foreach ($dataArr as $k=>$v) $data[$k]=$v;
return json_encode($data); return json_encode($data);
} }
......
<?php
namespace App\Http\Filters;
class CheckInFilter extends QueryFilter
{
public function user_id($userId = 0)
{
return $this->builder->where('user_id', $userId);
}
}
\ No newline at end of file
<?php
namespace App\Models;
use App\Http\Filters\QueryFilter;
use App\Tasks\IntegralBillTask;
use Common\Model\RedisModel;
use Carbon\Carbon;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class CheckIn extends Model
{
protected $table = 'check_in';
public $timestamps = false;
const INTEGRAL_TYPE_CHECK_IN = 4;
public function scopePage($query, $page = 1, $pageSize = 10)
{
return $query->offset(($page - 1) * $pageSize)->limit($pageSize);
}
public function scopeFilter($query, QueryFilter $filters)
{
return $filters->apply($query);
}
//获取签到记录
public function getCheckInList($page, $pageSize, $filter)
{
$checkIns = CheckIn::filter($filter)->page($page, $pageSize)
->orderBy('id', 'desc')->get()->toArray();
$count = CheckIn::filter($filter)->count();
return ['data' => $checkIns, 'count' => $count];
}
//添加签到记录
public function addCheckIn($data)
{
$result = DB::transaction(function () use ($data) {
$result = DB::table('check_in')->insert($data);
if (!$result) {
return false;
}
//使用异步任务去添加流水
$data['integral_id'] = self::INTEGRAL_TYPE_CHECK_IN;
$task = new IntegralBillTask($data);
$result = Task::deliver($task);
if (!$result) {
return false;
}
//添加流水成功后,要把签到记录放到redis
$date = Carbon::now()->toDateString();
$hashKey = 'ic_welfare_check_in_' . $date;
$userId = $data['user_id'];
$redis = new RedisModel();
$redis->hset($hashKey, $userId, $data['add_time']);
return true;
});
return $result;
}
//判断是否可以签到
public function canCheckInFromRedis($userId)
{
$redis = new RedisModel();
//先判断 ic_welfare_check_in_日期 在不在,不在的话就添加一个并且给过期时间
$date = Carbon::now()->toDateString();
$hashKey = 'ic_welfare_check_in_' . $date;
$exist = $redis->exists($hashKey);
if (!$exist) {
//设置晚上12点过期
$todayEndTime = Carbon::now()->endOfDay()->timestamp;
$redis->expireAt($hashKey, $todayEndTime);
//因为连最基础的键都没有,就代表肯定没有签到过
return true;
}
//如果没有,就代表用户今天没有签到
$checkInTime = $redis->hget($hashKey, $userId);
if (!$checkInTime) {
//因为他今天没有签到过,所以本次签到是可以执行的
return true;
}
return false;
}
}
\ No newline at end of file
...@@ -26,6 +26,12 @@ class Integral extends Model ...@@ -26,6 +26,12 @@ class Integral extends Model
return $filters->apply($query); return $filters->apply($query);
} }
//获取单个红包详情
public function getIntegral($id)
{
return DB::table('integrals')->where('id', $id)->first();
}
//获取活动红包列表 //获取活动红包列表
public function getIntegralList($page, $pageSize, $filter) public function getIntegralList($page, $pageSize, $filter)
{ {
......
...@@ -41,6 +41,14 @@ class UserIntegral extends Model ...@@ -41,6 +41,14 @@ class UserIntegral extends Model
return $res; return $res;
} }
public function updateUserIntegralByUserId($userId, $data = [])
{
$res = DB::table('user_integrals')->where('user_id', $userId)
->update($data);
return $res;
}
public function batchUpdateStatus($ids = [], $data = []) public function batchUpdateStatus($ids = [], $data = [])
{ {
$res = DB::table('user_integrals') $res = DB::table('user_integrals')
...@@ -52,6 +60,6 @@ class UserIntegral extends Model ...@@ -52,6 +60,6 @@ class UserIntegral extends Model
public function getUserIntegral($userId) public function getUserIntegral($userId)
{ {
return DB::table('user_integrals')->where('user_id', $userId)->get()->toArray(); return DB::table('user_integrals')->where('user_id', $userId)->first();
} }
} }
\ No newline at end of file
...@@ -4,66 +4,72 @@ ...@@ -4,66 +4,72 @@
namespace App\Tasks; namespace App\Tasks;
use App\Models\Integral;
use App\Models\IntegralBill; use App\Models\IntegralBill;
use App\Models\UserIntegral; use App\Models\UserIntegral;
use Common\Model\RedisModel; use Common\Model\RedisModel;
use Hhxsv5\LaravelS\Swoole\Task\Task; use Hhxsv5\LaravelS\Swoole\Task\Task;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class IntegralBillTask extends Task class IntegralBillTask extends Task
{ {
private $userId; private $data;
private $integralId;
public function __construct($userId, $integralId) public function __construct($data)
{ {
$this->userId = $userId; $this->data = $data;
$this->integralId = $integralId;
} }
public function handle() public function handle()
{ {
try { try {
DB::transaction(function () { DB::transaction(function () {
$userId = $this->data['user_id'];
$integralId = $this->data['integral_id'];
//数据库里面插入数据 //数据库里面插入数据
$data = [ $data = [
'user_id' => $this->userId, 'user_id' => $userId,
'integral_id' => $this->integralId, 'integral_id' => $integralId,
'status' => 1, 'status' => 1,
'add_time' => time(), 'add_time' => $this->data['add_time'],
]; ];
$integralBill = new IntegralBill(); $integralBill = new IntegralBill();
$result = $integralBill->createIntegralBill($data); $result = $integralBill->createIntegralBill($data);
if (!$result) { if (!$result) {
throw \Exception("插入用户红包账单失败,用户id是$this->userId,兑换类型id是$this->integralId"); throw new \Exception("插入用户红包账单失败,用户id是$userId,兑换类型id是$integralId");
} }
$userIntegral = new UserIntegral(); $userIntegral = new UserIntegral();
$data = $userIntegral->getUserIntegral($this->userId); $data = (array)$userIntegral->getUserIntegral($userId);
if ($data) { if ($data) {
//将用户的累计可兑换金额写进redis里面的ic_user里面去 //将用户的累计可兑换金额写进redis里面的ic_user里面去
$amount = $data['amount']; $integral = new Integral();
$res = $integral->getIntegral($integralId);
$amount = $res->amount;
$redis = new RedisModel(); $redis = new RedisModel();
$user = json_decode($redis->hget('ic_user', $this->userId), true); $user = json_decode($redis->hget('ic_user', $userId), true);
$user['integral'] = $data['integral'] + $amount; $user['integral'] = $data['integral'] + $amount;
$result = $redis->hset('ic_user', $this->userId, json_encode($user)); $result = $redis->hset('ic_user', $userId, json_encode($user));
//还要写进user_integrals数据库 //还要写进user_integrals数据库
if ($result) { if ($result !== false) {
$data = [ $data = [
'integral' => $data['integral'] + $amount, 'integral' => $data['integral'] + $amount,
'update_time' => time(), 'update_time' => time(),
]; ];
$result = $userIntegral->updateUserIntegral($this->userId, $data); $result = $userIntegral->updateUserIntegralByUserId($userId, $data);
if (!$result) { if (!$result) {
throw \Exception("更新用户剩余积分失败,用户id是$this->userId,兑换类型id是$this->integralId"); throw new \Exception("更新用户剩余积分失败,用户id是$userId,兑换类型id是$integralId");
} }
} else { } else {
throw \Exception("更新redis里ic_user的integral失败,用户id是$this->userId,兑换类型id是$this->integralId"); throw new \Exception("更新redis里ic_user的integral失败,用户id是$userId,兑换类型id是$integralId");
} }
} }
}); });
} catch (\Exception $e) { } catch (\Exception $e) {
//抛出致命错误日志 //抛出致命错误日志
Log::Error($e);
ErrorLog(ErrorCode(1, 9), $e); ErrorLog(ErrorCode(1, 9), $e);
} }
} }
......
...@@ -143,13 +143,13 @@ return [ ...@@ -143,13 +143,13 @@ return [
'host' => env('REDIS_HOST', '127.0.0.1'), 'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null), 'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379), 'port' => env('REDIS_PORT', 6379),
'database' => 1 'database' => 0
], ],
'read' =>[ 'read' =>[
'host' => env('REDIS_READ_HOST', ''), 'host' => env('REDIS_READ_HOST', ''),
'password' => env('REDIS_READ_PASSWORD', null), 'password' => env('REDIS_READ_PASSWORD', null),
'port' => env('REDIS_READ_PORT', 6379), 'port' => env('REDIS_READ_PORT', 6379),
'database' => 1 'database' => 0
] ]
], ],
......
...@@ -62,7 +62,7 @@ return [ ...@@ -62,7 +62,7 @@ return [
'dispatch_mode' => 2, 'dispatch_mode' => 2,
'reactor_num' => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 4, 'reactor_num' => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 4,
'worker_num' => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 8, 'worker_num' => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 8,
//'task_worker_num' => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 8, 'task_worker_num' => function_exists('swoole_cpu_num') ? swoole_cpu_num() * 2 : 8,
'task_ipc_mode' => 1, 'task_ipc_mode' => 1,
'task_max_request' => 8000, 'task_max_request' => 8000,
'task_tmpdir' => @is_writable('/dev/shm/') ? '/dev/shm' : '/tmp', 'task_tmpdir' => @is_writable('/dev/shm/') ? '/dev/shm' : '/tmp',
......
...@@ -69,3 +69,8 @@ $router->post('/user_exchanges/batchAuditReject', 'UserExchangesController@batch ...@@ -69,3 +69,8 @@ $router->post('/user_exchanges/batchAuditReject', 'UserExchangesController@batch
//抢兑换名额 //抢兑换名额
$router->post('/rob/exchange/quota', 'ExchangeController@create'); $router->post('/rob/exchange/quota', 'ExchangeController@create');
//用户签到
$router->post('/check_in/list','CheckInController@index');
$router->post('/check_in/add','CheckInController@store');
9058 23914
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment