Commit 5aa8c0fb by 杨树贤

Merge branch 'Development'

parents 910b4cfd cb1944f0
<?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);
} }
......
...@@ -42,7 +42,6 @@ class IntegralBillsController extends Controller ...@@ -42,7 +42,6 @@ class IntegralBillsController extends Controller
{ {
$data = [ $data = [
'user_id' => $request->user_id, 'user_id' => $request->user_id,
'amount' => $request->integral_amount,
'integral_id' => $request->integral_id, 'integral_id' => $request->integral_id,
'status' => 1, 'status' => 1,
'add_time' => time(), 'add_time' => time(),
......
<?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
...@@ -7,7 +7,7 @@ namespace App\Models; ...@@ -7,7 +7,7 @@ namespace App\Models;
use App\Http\Filters\QueryFilter; use App\Http\Filters\QueryFilter;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen; use Common\Model\RedisModel;
//活动红包模型 //活动红包模型
class Integral extends Model class Integral extends Model
...@@ -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)
{ {
...@@ -53,7 +59,7 @@ class Integral extends Model ...@@ -53,7 +59,7 @@ class Integral extends Model
} else { } else {
$count = $redis->hlen('ic_welfare_integrals'); $count = $redis->hlen('ic_welfare_integrals');
} }
$integrals = arraySequence($integrals,'id','SORT_ASC'); $integrals = arraySequence($integrals, 'id', 'SORT_ASC');
return ['data' => array_values($integrals), 'count' => $count]; return ['data' => array_values($integrals), 'count' => $count];
} }
...@@ -84,12 +90,10 @@ class Integral extends Model ...@@ -84,12 +90,10 @@ class Integral extends Model
//这里如果没有数据放到缓存了,直接删除key //这里如果没有数据放到缓存了,直接删除key
if ($data) { if ($data) {
$result = $redis->hmset('ic_welfare_integrals', $data); $redis->hmset('ic_welfare_integrals', $data);
} else { } else {
$result = $redis->del('ic_welfare_integrals'); $redis->del('ic_welfare_integrals');
} }
return $result;
} }
//添加单个红包 //添加单个红包
...@@ -102,10 +106,7 @@ class Integral extends Model ...@@ -102,10 +106,7 @@ class Integral extends Model
if (!$id) { if (!$id) {
return false; return false;
} }
$result = $this->addIntegralToRedis($id, $data); $this->addIntegralToRedis($id, $data);
if ($result === false) {
throw new \Exception('新增红包活动缓存数据失败', ErrorCode(19, 5));
}
return true; return true;
}, 5); }, 5);
...@@ -117,9 +118,7 @@ class Integral extends Model ...@@ -117,9 +118,7 @@ class Integral extends Model
public function addIntegralToRedis($id, $data) public function addIntegralToRedis($id, $data)
{ {
$redis = new RedisModel(); $redis = new RedisModel();
$result = $redis->hset('ic_welfare_integrals', $id, json_encode($data)); $redis->hset('ic_welfare_integrals', $id, json_encode($data));
return $result;
} }
//更新单个红包活动 //更新单个红包活动
...@@ -133,13 +132,10 @@ class Integral extends Model ...@@ -133,13 +132,10 @@ class Integral extends Model
} }
if ($result) { if ($result) {
$result = $this->changeIntegralsFromRedis([$id]); $this->changeIntegralsFromRedis([$id]);
if ($result === false) {
throw new \Exception('更新红包活动缓存数据失败', ErrorCode(20, 5));
}
} }
return $result ? true : false; return true;
}, 5); }, 5);
return $result; return $result;
...@@ -150,14 +146,11 @@ class Integral extends Model ...@@ -150,14 +146,11 @@ class Integral extends Model
{ {
$redis = new RedisModel(); $redis = new RedisModel();
$integral = $redis->hget('ic_welfare_integrals', $id); $integral = $redis->hget('ic_welfare_integrals', $id);
$result = false;
if ($integral) { if ($integral) {
//为什么用array_merge,因为右边的数组的键值会覆盖左边的对应值 //为什么用array_merge,因为右边的数组的键值会覆盖左边的对应值
$data = array_merge(json_decode($integral, true), $data); $data = array_merge(json_decode($integral, true), $data);
$result = $redis->hset('ic_welfare_integrals', $id, json_encode($data)); $redis->hset('ic_welfare_integrals', $id, json_encode($data));
} }
return $result;
} }
...@@ -169,10 +162,7 @@ class Integral extends Model ...@@ -169,10 +162,7 @@ class Integral extends Model
if (!$result) { if (!$result) {
return false; return false;
} }
$result = $this->changeIntegralsFromRedis($ids); $this->changeIntegralsFromRedis($ids);
if ($result === false) {
throw new \Exception('更新部分红包信息到redis失败', ErrorCode(21, 5));
}
return true; return true;
}, 5); }, 5);
...@@ -199,16 +189,10 @@ class Integral extends Model ...@@ -199,16 +189,10 @@ class Integral extends Model
$redis = new RedisModel(); $redis = new RedisModel();
if ($needDelete) { if ($needDelete) {
$result = $redis->hdel('ic_welfare_integrals', $needDelete); $redis->hdel('ic_welfare_integrals', $needDelete);
if ($result === false) {
return false;
}
} }
if ($needUpdate) { if ($needUpdate) {
$result = $redis->hmset('ic_welfare_integrals', $needUpdate); $redis->hmset('ic_welfare_integrals', $needUpdate);
if ($result === false) {
return false;
}
} }
return true; return true;
......
...@@ -44,9 +44,7 @@ class IntegralBill extends Model ...@@ -44,9 +44,7 @@ class IntegralBill extends Model
public function createIntegralBill($data = []) public function createIntegralBill($data = [])
{ {
$res = DB::transaction(function () use ($data) { $res = DB::table('integral_bills')->insert($data);
DB::table('integral_bills')->insert($data);
});
return $res; return $res;
} }
......
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Redis;
class RedisModel extends Model
{
const WRITE_CONNECT_METHOD = ['set', 'del', 'rpush','lpush', 'expire', 'hset', 'hmset', 'hdel','hsetnx','hincrby'];
private $read = [];
private $write = [];
public function __construct($ConnectWrite = 'default', $ConnectRead = 'read')
{
parent::__construct();
$this->read = Redis::connection($ConnectRead);
$this->write = Redis::connection($ConnectWrite);
}
public function __call($method, $args)
{
$cls = &$this;
$tmp = function($method, $args) use ($cls) {
if (strpos($method, 'pipeline_')) {//使用管道
$method = substr($method, 9);
if (in_array($method, $cls::WRITE_CONNECT_METHOD)) {
return $cls->write->pipeline(function ($pipe) use ($args) {
foreach ($args as $arg) {
$pipe->$method(...$arg);
}
});
} else {
try {
return $cls->read->pipeline(function ($pipe) use ($args) {
foreach ($args as $arg) {
$pipe->$method(...$arg);
}
});
} catch (ConnectionException $e) {
return $cls->write->pipeline(function ($pipe) use ($args) {
foreach ($args as $arg) {
$pipe->$method(...$arg);
}
});
}
}
} else {
if (in_array($method, $cls::WRITE_CONNECT_METHOD)) {
return $cls->write->$method(...$args);
} else {
try {
return $cls->read->$method(...$args);
} catch (ConnectionException $e) {
return $cls->write->$method(...$args);
}
}
}
};
try {
return $tmp($method, $args);
} catch (\Exception $e) {
dd($e);
return false;
}
// if (strpos($method, 'catch_') === 0) {
// $method = substr($method, 6);
// try {
// return $tmp($method, $args);
// } catch (\Exception $e) {
// return null;
// }
// } else {
// return $tmp($method, $args);
// }
}
}
...@@ -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')
...@@ -49,4 +57,9 @@ class UserIntegral extends Model ...@@ -49,4 +57,9 @@ class UserIntegral extends Model
return $res; return $res;
} }
public function getUserIntegral($userId)
{
return DB::table('user_integrals')->where('user_id', $userId)->first();
}
} }
\ No newline at end of file
<?php
namespace App\Tasks;
use App\Models\Integral;
use App\Models\IntegralBill;
use App\Models\UserIntegral;
use Common\Model\RedisModel;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class IntegralBillTask extends Task
{
private $data;
public function __construct($data)
{
$this->data = $data;
}
public function handle()
{
try {
DB::transaction(function () {
$userId = $this->data['user_id'];
$integralId = $this->data['integral_id'];
//数据库里面插入数据
$data = [
'user_id' => $userId,
'integral_id' => $integralId,
'status' => 1,
'add_time' => $this->data['add_time'],
];
$integralBill = new IntegralBill();
$result = $integralBill->createIntegralBill($data);
if (!$result) {
throw new \Exception("插入用户红包账单失败,用户id是$userId,兑换类型id是$integralId");
}
$userIntegral = new UserIntegral();
$data = (array)$userIntegral->getUserIntegral($userId);
if ($data) {
//将用户的累计可兑换金额写进redis里面的ic_user里面去
$integral = new Integral();
$res = $integral->getIntegral($integralId);
$amount = $res->amount;
$redis = new RedisModel();
$user = json_decode($redis->hget('ic_user', $userId), true);
$user['integral'] = $data['integral'] + $amount;
$result = $redis->hset('ic_user', $userId, json_encode($user));
//还要写进user_integrals数据库
if ($result !== false) {
$data = [
'integral' => $data['integral'] + $amount,
'update_time' => time(),
];
$result = $userIntegral->updateUserIntegralByUserId($userId, $data);
if (!$result) {
throw new \Exception("更新用户剩余积分失败,用户id是$userId,兑换类型id是$integralId");
}
} else {
throw new \Exception("更新redis里ic_user的integral失败,用户id是$userId,兑换类型id是$integralId");
}
}
});
} catch (\Exception $e) {
//抛出致命错误日志
Log::Error($e);
ErrorLog(ErrorCode(1, 9), $e);
}
}
public function finish()
{
}
}
\ No newline at end of file
...@@ -28,9 +28,9 @@ $app = new Laravel\Lumen\Application( ...@@ -28,9 +28,9 @@ $app = new Laravel\Lumen\Application(
realpath(__DIR__.'/../') realpath(__DIR__.'/../')
); );
$app->withFacades(); $app->withFacades();
$app->withEloquent(); $app->withEloquent();
/* /*
...@@ -46,7 +46,7 @@ $app = new Laravel\Lumen\Application( ...@@ -46,7 +46,7 @@ $app = new Laravel\Lumen\Application(
$app->singleton( $app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class, Illuminate\Contracts\Debug\ExceptionHandler::class,
// App\Exceptions\Handler::class // App\Exceptions\Handler::class
Common\Exceptions\Handler::class Common\Exceptions\Handler::class
); );
...@@ -66,10 +66,10 @@ $app->singleton( ...@@ -66,10 +66,10 @@ $app->singleton(
| |
*/ */
$app->middleware([ $app->middleware([
// App\Http\Middleware\ExampleMiddleware::class // App\Http\Middleware\ExampleMiddleware::class
App\Http\Middleware\UniqueMiddleware::class, App\Http\Middleware\UniqueMiddleware::class,
]); ]);
// $app->routeMiddleware([ // $app->routeMiddleware([
// 'auth' => App\Http\Middleware\Authenticate::class, // 'auth' => App\Http\Middleware\Authenticate::class,
......
...@@ -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' => 2 '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' => 2 '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