diff --git a/.gitignore b/.gitignore index 8088c1b..9454e2b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ vendor/ *.lock .phpunit* /watch -.vscode/settings.json +.vscode/ diff --git a/Envoy.blade.php b/Envoy.blade.php index 6562fe6..39d6cc9 100644 --- a/Envoy.blade.php +++ b/Envoy.blade.php @@ -21,7 +21,7 @@ cd /lanzu_api git pull origin master @if($composer == true) - composer update --lock + composer update --no-dev --lock @endif supervisorctl restart lanzu_api @endtask diff --git a/app/Amqp/Consumer/couponRebateConsumer.php b/app/Amqp/Consumer/couponRebateConsumer.php new file mode 100644 index 0000000..239aee7 --- /dev/null +++ b/app/Amqp/Consumer/couponRebateConsumer.php @@ -0,0 +1,46 @@ +getBody()); + $res = $this->CouponRebateService->couponRebate($data); + //var_dump($res); + if (!$res) { + return Result::REQUEUE; + } + return Result::ACK; + } + + public function isEnable(): bool + { + return parent::isEnable(); + } +} diff --git a/app/Commons/Log.php b/app/Commons/Log.php new file mode 100644 index 0000000..bf5fb24 --- /dev/null +++ b/app/Commons/Log.php @@ -0,0 +1,88 @@ +clientFactory = $clientFactory; + } + + public function getClient() + { + // $options 等同于 GuzzleHttp\Client 构造函数的 $config 参数 + $options = [ + 'timeout' => 2.0, + ]; + // $client 为协程化的 GuzzleHttp\Client 对象 + $client = $this->clientFactory->create($options); + + return $client; + } + + public function event($labels=null,$datas){ + + co(function () use ($labels,$datas){ + + $client = $this->getClient(); + $kv = []; + foreach ($datas as $key => $value) { + $kv[] = $key."=".$value; + } + $pushLabels = []; + + $event_name = 'event_'.env('APP_ENV'); + if(!empty($labels)) $pushLabels[$event_name] = $labels; + + /* + * data format: + curl -v -H "Content-Type: application/json" -XPOST -s "http://39.96.12.39:3100/loki/api/v1/push" --data-raw \ + '{"streams": [{ "stream": { "foo": "bar2" }, "values": [ [ "1596274538882028800", "fizzbuzz" ] ] }]}' + */ + $ts = $this->getMsecTime() . '000000'; + $datas = implode("&",$kv); + $values = [[$ts,$datas]]; + $app_name = env('APP_NAME').'_'.env('APP_ENV'); + + $pushLabels['app']= $app_name; + $pushDatas = [ + 'streams'=>[ + [ + 'stream'=>$pushLabels, + 'values'=>$values, + ] + ] + ]; + $client->post( + 'http://39.96.12.39:3100/loki/api/v1/push', + [ + 'headers'=>[ + 'Content-Type'=>'application/json' + ], + 'body' => json_encode($pushDatas) + ] + ); + //var_dump(json_encode($pushDatas) ); + }); + } + + + public function push($datas){ + $this->event(null,$datas); + } + + public function getMsecTime() + { + list($msec, $sec) = explode(' ', microtime()); + $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000); + return $msectime; + } + +} diff --git a/app/Constants/ErrorCode.php b/app/Constants/ErrorCode.php index a7fee16..b361172 100644 --- a/app/Constants/ErrorCode.php +++ b/app/Constants/ErrorCode.php @@ -33,4 +33,9 @@ class ErrorCode extends AbstractConstants * @Message("Save failure!"); */ const SAVE_FAILURE = 100; + + /** + * @Message("Ssdb Error!") + */ + const SSDB_ERROR = 600; } diff --git a/app/Constants/LogLabel.php b/app/Constants/LogLabel.php new file mode 100644 index 0000000..c09c8df --- /dev/null +++ b/app/Constants/LogLabel.php @@ -0,0 +1,21 @@ +success($this->adService->banners()); + } +} diff --git a/app/Controller/CouponController.php b/app/Controller/CouponController.php index 6e73066..648039a 100644 --- a/app/Controller/CouponController.php +++ b/app/Controller/CouponController.php @@ -12,85 +12,33 @@ declare(strict_types=1); namespace App\Controller; +use Hyperf\Di\Annotation\Inject; use App\Model\CouponUserRecType; use App\Model\Coupon; use App\Model\CouponRec; use Hyperf\DbConnection\Db; use Hyperf\Redis\Redis; use Hyperf\Utils\ApplicationContext; +use App\Request\CouponGetListRequest; +use App\Service\CouponServiceInterface; class CouponController extends BaseController { + /** + * @Inject + * @var CouponServiceInterface + */ + protected $couponService; /** * 获取用户可领取优惠卷接口 */ - public function getSystemCouponUserList() + public function getSystemCouponUserList(CouponGetListRequest $validator) { - $user_id = $this->request->input('user_id', 0); - $receive_type = $this->request->input('receive_type', 0); - - if ($this->empty($user_id) || $this->empty($receive_type)) { - return $this->success(['not_reveive' => []]); - } - - $c_ids = []; - // 渠道开启,查询该渠道可以领取的优惠券ID - // 渠道未开启,查询所有优惠券 - if (env('SUB_CHANNEL') == 1) { - $c_ids = CouponUserRecType::where('receive_type', $receive_type)->pluck('system_coupon_user_id'); - } else { - $c_ids = Coupon::pluck('id'); - } - - $nowTime = time(); - - $where = [ - ['user_id',"=",$user_id] - ]; - - // 渠道开启,查询该用户在此渠道领过的优惠券ID - if (env('SUB_CHANNEL') == 1) { - array_push($where, ['receive_type', "=", $receive_type]); - } - - $cr_ids = CouponRec::where($where)->pluck('system_coupon_user_id'); - - //领过券的ID - $c_ids = $c_ids->toArray(); - $cr_ids = $cr_ids->toArray(); - - // 当前用户可领的优惠券ID - $couponIds = array_diff($c_ids, $cr_ids); - - $whereC = [ - ['u.end_time','>',$nowTime], - ['u.start_time','<=',$nowTime], - ['u.status','=',1], - ]; - - if (env('SUB_CHANNEL') == 1) { - array_push($whereC, ['type.receive_type','=',$receive_type]); - } - - $c = Db::table('ims_system_coupon_user as u') - ->where($whereC) - ->join('ims_system_coupon_user_receivetype as type', 'u.id', '=', 'type.system_coupon_user_id') - ->whereRaw('u.inventory_use < u.inventory and u.inventory-u.inventory_use >= type.one_receive_number') - // ->whereIn('u.id',$c_ids) - // ->whereNotIn('u.id',$cr_ids) - ->whereIn('u.id', $couponIds) - ->select('u.*','type.one_receive_number') - ->orderBy('u.weigh','desc') - // ->orderByRaw('FIELD(u.id, '.implode(", " , $ids).')') - ->limit(4) - ->get(); - foreach ($c as $k => &$v){ - if($v->discount_type == 2){ - $v->discounts = floatval($v->discounts); - } - } - return $this->success(['not_reveive'=>$c]); + $userId = $this->request->input('user_id', 0); + $receiveType = $this->request->input('receive_type', 0); + $res = $this->couponService->getSystemCouponUserList($userId,$receiveType); + return $this->success($res); } //统计用户 diff --git a/app/Controller/CouponRebateController.php b/app/Controller/CouponRebateController.php new file mode 100644 index 0000000..7765de3 --- /dev/null +++ b/app/Controller/CouponRebateController.php @@ -0,0 +1,86 @@ +request->input('user_id', 0); + $res = $this->CouponRebateService->isCouponRebate($user_id); + return $this->success($res); + } + + /** + * 返回活动信息 + */ + public function getActiveInfo() + { + $res = $this->CouponRebateService->getActiveInfo(); + return $this->success($res); + } + + + /** + * 用户领取优惠券 + */ + public function userReceiveCoupon(CouponRebateReceiveRequest $validator) + { + return $this->success($this->CouponRebateService->userReceiveCoupon($this->request->all())); + } + + public function couponRebate() + { + $order_id = $this->request->input('order_id', 0); + $res = $this->CouponRebateService->couponRebate($order_id); + return $this->success($res); + } + + /** + * 将优惠券绑定活动 + */ + public function tieCouponActive(CouponRebateTieRequest $validator) + { + $couponForward = $this->request->input('coupon_forward_ids',[]); + $couponForward = is_array($couponForward) ? implode(',',$couponForward) : $couponForward ; + $couponRepay = $this->request->input('coupon_repay_id',0); + $couponActivity = $this->request->input('coupon_activity',0); + $res = $this->CouponRebateService->tieCouponActive($couponActivity,$couponForward,$couponRepay); + return $this->success($res); + } + + /** + * 清优惠券领取记录(SSDB) + */ + public function clearSsdbCouponReceiveByName(){ + $activity = $this->request->input('activity_type',0); + $userId = $this->request->input('user_id',0); + $get = $this->request->input('get',0); + $isAll = $this->request->input('is_all',0);; + return $this->success($this->CouponRebateService->clearSsdbCouponReceiveByName($activity,$userId, $get, $isAll)); + } +} diff --git a/app/Controller/ParamsTokenController.php b/app/Controller/ParamsTokenController.php new file mode 100644 index 0000000..db1cdca --- /dev/null +++ b/app/Controller/ParamsTokenController.php @@ -0,0 +1,40 @@ +paramsTokenService->generate($this->request->all()); + return $this->success(['token' => $token]); + } + + /** + * 解析token获取对应参数数据 + * @return \Psr\Http\Message\ResponseInterface + */ + public function analyze() + { + $params = $this->paramsTokenService->analyze($this->request->input('token')); + return $this->success($params); + } +} \ No newline at end of file diff --git a/app/Controller/TestController.php b/app/Controller/TestController.php new file mode 100644 index 0000000..f69cea8 --- /dev/null +++ b/app/Controller/TestController.php @@ -0,0 +1,60 @@ +get(TaskExecutor::class); + // $result = $exec->execute(new Task([MethodTask::class, 'handle'], [Coroutine::id()])); + + // $client = ApplicationContext::getContainer()->get(SSDBTask::class); + // $result = $client->exec("set","bar","1234"); + // $result = $client->exec("get","bar"); + + // $client = ApplicationContext::getContainer()->get(MethodTask::class); + // $result = $client->handle("set"); + + + //$log = ApplicationContext::getContainer()->get(Log::class); + $log = $this->log; + + $log->push(['test'=>1,'user_id'=>290,'msg'=>'order']); + $log->event('t1',['test'=>1,'user_id'=>290,'msg'=>'order']); + + //$this->name = 'index1 action '. $result; + return $this->name; + } + + public function index2(RequestInterface $request) + { + $this->name = 'index2 action'; + return $this->name; + } + + public function index3(RequestInterface $request) + { + return $this->name; + } +} \ No newline at end of file diff --git a/app/Exception/Handler/SsdbExceptionHandler.php b/app/Exception/Handler/SsdbExceptionHandler.php new file mode 100644 index 0000000..118d5ef --- /dev/null +++ b/app/Exception/Handler/SsdbExceptionHandler.php @@ -0,0 +1,33 @@ +stopPropagation(); + + $content = json_encode([ + "status" => 'error', + "code" => $throwable->getCode(), + "result" => [], + "message" => $throwable->getMessage() + ]); + + return $response->withHeader('Content-Type', 'application/json')->withBody(new SwooleStream($content)); + } + + public function isValid(Throwable $throwable): bool + { + return $throwable instanceof SsdbException; + } +} \ No newline at end of file diff --git a/app/Exception/SsdbException.php b/app/Exception/SsdbException.php new file mode 100644 index 0000000..c005c38 --- /dev/null +++ b/app/Exception/SsdbException.php @@ -0,0 +1,18 @@ +easy(); + } +} + +class SSDB_Response +{ + public $cmd; + public $code; + public $data = null; + public $message; + + function __construct($code='ok', $data_or_message=null){ + $this->code = $code; + if($code == 'ok'){ + $this->data = $data_or_message; + }else{ + $this->message = $data_or_message; + } + } + + function __toString(){ + if($this->code == 'ok'){ + $s = $this->data === null? '' : json_encode($this->data); + }else{ + $s = $this->message; + } + return sprintf('%-13s %12s %s', $this->cmd, $this->code, $s); + } + + function ok(){ + return $this->code == 'ok'; + } + + function not_found(){ + return $this->code == 'not_found'; + } +} + +// Depricated, use SimpleSSDB instead! +class SSDB +{ + private $debug = false; + public $sock = null; + private $_closed = false; + private $recv_buf = ''; + private $_easy = false; + public $last_resp = null; + + function __construct($host, $port, $timeout_ms=2000){ + $timeout_f = (float)$timeout_ms/1000; + $this->sock = @stream_socket_client("$host:$port", $errno, $errstr, $timeout_f); + if(!$this->sock){ + throw new SSDBException("$errno: $errstr"); + } + $timeout_sec = intval($timeout_ms/1000); + $timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000; + @stream_set_timeout($this->sock, $timeout_sec, $timeout_usec); + if(function_exists('stream_set_chunk_size')){ + @stream_set_chunk_size($this->sock, 1024 * 1024); + } + } + + function set_timeout($timeout_ms){ + $timeout_sec = intval($timeout_ms/1000); + $timeout_usec = ($timeout_ms - $timeout_sec * 1000) * 1000; + @stream_set_timeout($this->sock, $timeout_sec, $timeout_usec); + } + + /** + * After this method invoked with yesno=true, all requesting methods + * will not return a SSDB_Response object. + * And some certain methods like get/zget will return false + * when response is not ok(not_found, etc) + */ + function easy(){ + $this->_easy = true; + } + + function close(){ + if(!$this->_closed){ + @fclose($this->sock); + $this->_closed = true; + $this->sock = null; + } + } + + function closed(){ + return $this->_closed; + } + + private $batch_mode = false; + private $batch_cmds = array(); + + function batch(){ + $this->batch_mode = true; + $this->batch_cmds = array(); + return $this; + } + + function multi(){ + return $this->batch(); + } + + function exec(){ + $ret = array(); + foreach($this->batch_cmds as $op){ + list($cmd, $params) = $op; + $this->send_req($cmd, $params); + } + foreach($this->batch_cmds as $op){ + list($cmd, $params) = $op; + $resp = $this->recv_resp($cmd, $params); + $resp = $this->check_easy_resp($cmd, $resp); + $ret[] = $resp; + } + $this->batch_mode = false; + $this->batch_cmds = array(); + return $ret; + } + + function request(){ + $args = func_get_args(); + $cmd = array_shift($args); + return $this->__call($cmd, $args); + } + + private $async_auth_password = null; + + function auth($password){ + $this->async_auth_password = $password; + return null; + } + + function __call($cmd, $params=array()){ + $cmd = strtolower($cmd); + if($this->async_auth_password !== null){ + $pass = $this->async_auth_password; + $this->async_auth_password = null; + $auth = $this->__call('auth', array($pass)); + if($auth !== true){ + throw new Exception("Authentication failed"); + } + } + + if($this->batch_mode){ + $this->batch_cmds[] = array($cmd, $params); + return $this; + } + + try{ + if($this->send_req($cmd, $params) === false){ + $resp = new SSDB_Response('error', 'send error'); + }else{ + $resp = $this->recv_resp($cmd, $params); + } + }catch(SSDBException $e){ + if($this->_easy){ + throw $e; + }else{ + $resp = new SSDB_Response('error', $e->getMessage()); + } + } + + if($resp->code == 'noauth'){ + $msg = $resp->message; + throw new Exception($msg); + } + + $resp = $this->check_easy_resp($cmd, $resp); + return $resp; + } + + private function check_easy_resp($cmd, $resp){ + $this->last_resp = $resp; + if($this->_easy){ + if($resp->not_found()){ + return NULL; + }else if(!$resp->ok() && !is_array($resp->data)){ + return false; + }else{ + return $resp->data; + } + }else{ + $resp->cmd = $cmd; + return $resp; + } + } + + function multi_set($kvs=array()){ + $args = array(); + foreach($kvs as $k=>$v){ + $args[] = $k; + $args[] = $v; + } + return $this->__call(__FUNCTION__, $args); + } + + function multi_hset($name, $kvs=array()){ + $args = array($name); + foreach($kvs as $k=>$v){ + $args[] = $k; + $args[] = $v; + } + return $this->__call(__FUNCTION__, $args); + } + + function multi_zset($name, $kvs=array()){ + $args = array($name); + foreach($kvs as $k=>$v){ + $args[] = $k; + $args[] = $v; + } + return $this->__call(__FUNCTION__, $args); + } + + function incr($key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function decr($key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function zincr($name, $key, $score=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function zdecr($name, $key, $score=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function zadd($key, $score, $value){ + $args = array($key, $value, $score); + return $this->__call('zset', $args); + } + + function zRevRank($name, $key){ + $args = func_get_args(); + return $this->__call("zrrank", $args); + } + + function zRevRange($name, $offset, $limit){ + $args = func_get_args(); + return $this->__call("zrrange", $args); + } + + function hincr($name, $key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + function hdecr($name, $key, $val=1){ + $args = func_get_args(); + return $this->__call(__FUNCTION__, $args); + } + + private function send_req($cmd, $params){ + $req = array($cmd); + foreach($params as $p){ + if(is_array($p)){ + $req = array_merge($req, $p); + }else{ + $req[] = $p; + } + } + return $this->send($req); + } + + private function recv_resp($cmd, $params){ + $resp = $this->recv(); + if($resp === false){ + return new SSDB_Response('error', 'Unknown error'); + }else if(!$resp){ + return new SSDB_Response('disconnected', 'Connection closed'); + } + if($resp[0] == 'noauth'){ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + switch($cmd){ + case 'dbsize': + case 'ping': + case 'qset': + case 'getbit': + case 'setbit': + case 'countbit': + case 'strlen': + case 'set': + case 'setx': + case 'setnx': + case 'zset': + case 'hset': + case 'qpush': + case 'qpush_front': + case 'qpush_back': + case 'qtrim_front': + case 'qtrim_back': + case 'del': + case 'zdel': + case 'hdel': + case 'hsize': + case 'zsize': + case 'qsize': + case 'hclear': + case 'zclear': + case 'qclear': + case 'multi_set': + case 'multi_del': + case 'multi_hset': + case 'multi_hdel': + case 'multi_zset': + case 'multi_zdel': + case 'incr': + case 'decr': + case 'zincr': + case 'zdecr': + case 'hincr': + case 'hdecr': + case 'zget': + case 'zrank': + case 'zrrank': + case 'zcount': + case 'zsum': + case 'zremrangebyrank': + case 'zremrangebyscore': + case 'ttl': + case 'expire': + if($resp[0] == 'ok'){ + $val = isset($resp[1])? intval($resp[1]) : 0; + return new SSDB_Response($resp[0], $val); + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + case 'zavg': + if($resp[0] == 'ok'){ + $val = isset($resp[1])? floatval($resp[1]) : (float)0; + return new SSDB_Response($resp[0], $val); + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + case 'get': + case 'substr': + case 'getset': + case 'hget': + case 'qget': + case 'qfront': + case 'qback': + if($resp[0] == 'ok'){ + if(count($resp) == 2){ + return new SSDB_Response('ok', $resp[1]); + }else{ + return new SSDB_Response('server_error', 'Invalid response'); + } + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + break; + case 'qpop': + case 'qpop_front': + case 'qpop_back': + if($resp[0] == 'ok'){ + $size = 1; + if(isset($params[1])){ + $size = intval($params[1]); + } + if($size <= 1){ + if(count($resp) == 2){ + return new SSDB_Response('ok', $resp[1]); + }else{ + return new SSDB_Response('server_error', 'Invalid response'); + } + }else{ + $data = array_slice($resp, 1); + return new SSDB_Response('ok', $data); + } + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + break; + case 'keys': + case 'zkeys': + case 'hkeys': + case 'hlist': + case 'zlist': + case 'qslice': + if($resp[0] == 'ok'){ + $data = array(); + if($resp[0] == 'ok'){ + $data = array_slice($resp, 1); + } + return new SSDB_Response($resp[0], $data); + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + case 'auth': + case 'exists': + case 'hexists': + case 'zexists': + if($resp[0] == 'ok'){ + if(count($resp) == 2){ + return new SSDB_Response('ok', (bool)$resp[1]); + }else{ + return new SSDB_Response('server_error', 'Invalid response'); + } + }else{ + $errmsg = isset($resp[1])? $resp[1] : ''; + return new SSDB_Response($resp[0], $errmsg); + } + break; + case 'multi_exists': + case 'multi_hexists': + case 'multi_zexists': + if($resp[0] == 'ok'){ + if(count($resp) % 2 == 1){ + $data = array(); + for($i=1; $idebug){ + echo '> ' . str_replace(array("\r", "\n"), array('\r', '\n'), $s) . "\n"; + } + try{ + while(true){ + $ret = @fwrite($this->sock, $s); + if($ret === false || $ret === 0){ + $this->close(); + throw new SSDBException('Connection lost'); + } + $s = substr($s, $ret); + if(strlen($s) == 0){ + break; + } + @fflush($this->sock); + } + }catch(Exception $e){ + $this->close(); + throw new SSDBException($e->getMessage()); + } + return $ret; + } + + function recv(){ + $this->step = self::STEP_SIZE; + while(true){ + $ret = $this->parse(); + if($ret === null){ + try{ + $data = @fread($this->sock, 1024 * 1024); + if($this->debug){ + echo '< ' . str_replace(array("\r", "\n"), array('\r', '\n'), $data) . "\n"; + } + }catch(Exception $e){ + $data = ''; + } + if($data === false || $data === ''){ + if(feof($this->sock)){ + $this->close(); + throw new SSDBException('Connection lost'); + }else{ + throw new SSDBTimeoutException('Connection timeout'); + } + } + $this->recv_buf .= $data; +# echo "read " . strlen($data) . " total: " . strlen($this->recv_buf) . "\n"; + }else{ + return $ret; + } + } + } + + const STEP_SIZE = 0; + const STEP_DATA = 1; + public $resp = array(); + public $step; + public $block_size; + + private function parse(){ + $spos = 0; + $epos = 0; + $buf_size = strlen($this->recv_buf); + // performance issue for large reponse + //$this->recv_buf = ltrim($this->recv_buf); + while(true){ + $spos = $epos; + if($this->step === self::STEP_SIZE){ + $epos = strpos($this->recv_buf, "\n", $spos); + if($epos === false){ + break; + } + $epos += 1; + $line = substr($this->recv_buf, $spos, $epos - $spos); + $spos = $epos; + + $line = trim($line); + if(strlen($line) == 0){ // head end + $this->recv_buf = substr($this->recv_buf, $spos); + $ret = $this->resp; + $this->resp = array(); + return $ret; + } + $this->block_size = intval($line); + $this->step = self::STEP_DATA; + } + if($this->step === self::STEP_DATA){ + $epos = $spos + $this->block_size; + if($epos <= $buf_size){ + $n = strpos($this->recv_buf, "\n", $epos); + if($n !== false){ + $data = substr($this->recv_buf, $spos, $epos - $spos); + $this->resp[] = $data; + $epos = $n + 1; + $this->step = self::STEP_SIZE; + continue; + } + } + break; + } + } + + // packet not ready + if($spos > 0){ + $this->recv_buf = substr($this->recv_buf, $spos); + } + return null; + } +} \ No newline at end of file diff --git a/app/Listener/ValidatorFactoryResolvedListener.php b/app/Listener/ValidatorFactoryResolvedListener.php index 0bfb047..75b3a36 100644 --- a/app/Listener/ValidatorFactoryResolvedListener.php +++ b/app/Listener/ValidatorFactoryResolvedListener.php @@ -48,6 +48,36 @@ class ValidatorFactoryResolvedListener implements ListenerInterface return $message; }); + // 注册了 base64 验证器规则 + $validatorFactory->extend('base64', function ($attribute, $value, $parameters, $validator) { + + preg_match('/^(data:\s*image\/(\w+);base64,)/', $value, $result); + + if (empty($result)) { + return false; + } + + if ( + in_array('image', $parameters) + && !in_array($result[2], ['jpg','jpeg','png','gif','svg','bmp']) + ) { + return false; + } + + return true; + + }); + + // 注册了 ext_not_in 验证器规则 + $validatorFactory->extend('ext_not_in', function ($attribute, $value, $parameters, $validator) { + + if (empty($parameters)) { + $parameters = ['', 'php', 'exe', 'sql', 'sh', 'bat', 'py', 'go', 'c', 'cpp']; + } + return !in_array($value->getExtension(), $parameters); + + }); + // 注册了 exists_enable 验证器规则,参数是table,field,where1,where2... $validatorFactory->extend('exists_enable', function ($attribute, $value, $parameters, $validator) { @@ -79,6 +109,5 @@ class ValidatorFactoryResolvedListener implements ListenerInterface return $builder->exists(); }); - } } \ No newline at end of file diff --git a/app/Middleware/Auth/ApiMiddleware.php b/app/Middleware/Auth/ApiMiddleware.php index ce06bff..44cf3fc 100644 --- a/app/Middleware/Auth/ApiMiddleware.php +++ b/app/Middleware/Auth/ApiMiddleware.php @@ -39,7 +39,7 @@ class ApiMiddleware implements MiddlewareInterface public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { - if (env('APP_ENV') == 'dev') { + if (env('APP_ENV') == 'dev' || env('APP_ENV') == 'local') { return $handler->handle($request); } diff --git a/app/Middleware/CorsMiddleware.php b/app/Middleware/CorsMiddleware.php new file mode 100644 index 0000000..7fb6495 --- /dev/null +++ b/app/Middleware/CorsMiddleware.php @@ -0,0 +1,34 @@ +withHeader('Access-Control-Allow-Origin', '*') + ->withHeader('Access-Control-Allow-Credentials', 'true') + // Headers 可以根据实际情况进行改写。 + ->withHeader('Access-Control-Allow-Headers', 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,Authorization'); + + Context::set(ResponseInterface::class, $response); + + if ($request->getMethod() == 'OPTIONS') { + return $response; + } + + return $handler->handle($request); + } +} \ No newline at end of file diff --git a/app/Model/Ad.php b/app/Model/Ad.php new file mode 100644 index 0000000..71cdbf9 --- /dev/null +++ b/app/Model/Ad.php @@ -0,0 +1,70 @@ + 'page', + 2 => 'webview', + 3 => 'applet', + ]; + + /** + * 类型 1 = 首页banners + */ + const TYPE_BANNER = 1; + + /** + * 启用状态 + */ + const STATUS_YES = 1; + const STATUS_NO = 2; + + /** + * The table associated with the model. + * + * @var string + */ + protected $table = 'ims_cjdc_ad'; + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = []; + /** + * The attributes that should be cast to native types. + * + * @var array + */ + protected $casts = []; + + protected $appends = [ + 'item_text', + 'redirect_url' + ]; + + /** + * 获取跳转说明 + */ + public function getItemTextAttribute() + { + return self::ITEM[$this->item]; + } + + /** + * 获取跳转连接 + */ + public function getRedirectUrlAttribute() + { + return $this->src ?: $this->src2; + } +} \ No newline at end of file diff --git a/app/Model/OrderMain.php b/app/Model/OrderMain.php new file mode 100644 index 0000000..7c7eb3d --- /dev/null +++ b/app/Model/OrderMain.php @@ -0,0 +1,10 @@ + 'required|nonempty|integer|exists_enable:ims_cjdc_user,id', + 'receive_type' => 'required|nonempty|integer' + ]; + } + + public function messages(): array + { + return [ + 'user_id.*' => ':attribute信息不正确', + 'receive_type.*' => ':attribute必须' + ]; + } + + public function attributes(): array + { + return [ + 'user_id' => '用户ID', + 'receive_type' => '领取方式' + ]; + } +} diff --git a/app/Request/CouponRebateReceiveRequest.php b/app/Request/CouponRebateReceiveRequest.php new file mode 100644 index 0000000..7abce7d --- /dev/null +++ b/app/Request/CouponRebateReceiveRequest.php @@ -0,0 +1,45 @@ + 'required|nonempty|integer|exists_enable:ims_cjdc_user,id', + 'receive_type' => 'required|nonempty|integer', + ]; + } + + public function messages(): array + { + return [ + 'user_id.*' => ':attribute信息不正确', + 'receive_type.*' => ':attribute必须', + ]; + } + + public function attributes(): array + { + return [ + 'user_id' => '领取用户ID', + 'receive_type' => '领取方式', + ]; + } +} diff --git a/app/Request/CouponRebateTieRequest.php b/app/Request/CouponRebateTieRequest.php new file mode 100644 index 0000000..39a5863 --- /dev/null +++ b/app/Request/CouponRebateTieRequest.php @@ -0,0 +1,48 @@ + 'required|nonempty', + 'coupon_forward_ids' => 'required|nonempty', + 'coupon_repay_id' => 'required|nonempty', + ]; + } + + public function messages(): array + { + return [ + 'coupon_activity.*' => ':attribute必须', + 'coupon_forward_ids.*' => ':attribute必须', + 'coupon_repay_id.*' => ':attribute必须', + ]; + } + + public function attributes(): array + { + return [ + 'coupon_activity' => '优惠券活动', + 'coupon_forward_ids' => '领取类型优惠券', + 'coupon_repay_id' => '返还类型优惠券', + ]; + } +} diff --git a/app/Service/AdService.php b/app/Service/AdService.php new file mode 100644 index 0000000..77170ac --- /dev/null +++ b/app/Service/AdService.php @@ -0,0 +1,20 @@ +select(['id','title','logo','item','src','src2']) + ->where([ + 'type' => Ad::TYPE_BANNER, + 'status' => Ad::STATUS_YES + ])->get(); + } +} \ No newline at end of file diff --git a/app/Service/AdServiceInterface.php b/app/Service/AdServiceInterface.php new file mode 100644 index 0000000..f488422 --- /dev/null +++ b/app/Service/AdServiceInterface.php @@ -0,0 +1,11 @@ +0领取失败 + $result = [ + 'status' => 1, + 'coupon_text' => '活动已过期~' + ]; + /* 如果请求的优惠券ids为空,则返回过期提示 */ + if($this->commonService->empty($params["ids"])){ + return $result; + } + + $ids = $params["ids"]; + $idsData = is_array($ids) ? $ids : explode(',',$ids); + + // 错误日志记录 + $errorData = [ + 'coupon_ids' =>$ids, + 'user_id' =>$userId, + 'receiveType' =>$receiveType, + 'sendUserId' =>$sendUserId, + 'phone' =>$phone + ]; + + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + $activity = $ssdb->exec('hget', SsdbKeysPrefix::COUPON_REBATE_ACTIVITY ,'activity'); + // ssdb 键值 + $ssdbKey = 'activity_'.$activity.'_user_'.$userId; + $receiveSsdb = []; + + // 判断是否已全部领取过 + $userReceive = $ssdb->exec('hget', SsdbKeysPrefix::COUPON_REBATE_RECEIVE,$ssdbKey); + if($userReceive === false){ + $ids = $idsData; + }else{ + $userReceiveCouponIds = empty($userReceive) ? [] : explode(',',$userReceive) ; + $ids = array_diff($idsData, $userReceiveCouponIds); + $receiveSsdb = $userReceiveCouponIds; + } + + if(count($ids) > 0){ + try{ + Db::transaction( function() use ($ids,$receiveType,$userId,$sendUserId,$phone,&$result,&$errorData,&$receiveSsdb) { + + $now = time(); + $success = []; + + //获取优惠券信息 (读写锁,完全控制,性能低) + $coupons = Coupon::whereIn('id', $ids)->lockForUpdate() + ->where('active_type',2) + ->where('status',1) + ->where('start_time', '<=', $now) + ->where('end_time', '>=', $now) + ->whereRaw('inventory > inventory_use') + ->select('id','title','inventory','inventory_use','full_amount','discounts','active_type') + ->get(); + + foreach($coupons as $coupon){ + $errorData['coupon_id'] = $coupon->id; + + // 查询一次能领取的数量 + $couponReceiveType = CouponUserRecType::where('system_coupon_user_id',$coupon->id)->select('one_receive_number'); + if (env('SUB_CHANNEL') == 1) { + $couponReceiveType->where('receive_type',$receiveType); + } + $couponReceiveType = $couponReceiveType->first(); + + // 优惠券可领取数量 >= 本次领取数量 + if($coupon->inventory - $coupon->inventory_use >= $couponReceiveType->one_receive_number){ + + // 判断是否领取过 存在记录则领取过 + $isReceive = CouponRec::select('id') + ->where('system_coupon_user_id',$coupon->id) + ->where('user_id',$userId) + ->exists(); + + if(!$isReceive){ + //记录已领取的数量 + $coupon->inventory_use += $couponReceiveType->one_receive_number; + + $couponReceive = new CouponRec; + $couponReceive->user_id = $userId; + $couponReceive->system_coupon_user_id = $coupon->id; + $couponReceive->order_main_id = 0; + $couponReceive->receive_time = $now; + $couponReceive->number = $couponReceiveType->one_receive_number; + $couponReceive->number_remain = $couponReceiveType->one_receive_number; + $couponReceive->status = 0; + $couponReceive->update_time = $now; + $couponReceive->receive_type = $receiveType; + $couponReceive->send_user_id = $sendUserId; + $couponReceive->phone = $phone; + + if ( $couponReceive->save() && $coupon->save() ) { + $success[] = $coupon; + $receiveSsdb[] = $coupon->id; + }else{ + $errorData['msg'] = '添加优惠券到用户领取表或者记录已领取数量失败'; + $this->log->event( + LogLabel::COUPON_LOG, + $errorData + ); + } + } + } + } + if(count($success) > 0){ + $result['status'] = 0; + $result['coupon_text'] = '恭喜您领取成功!'; + } + }); + } catch (Exception $e){ + $errorData['msg'] = $e->getMessage(); + $this->log->event( + LogLabel::COUPON_LOG, + $errorData + ); + } + + if(count($receiveSsdb) > 0){ + + $saveSsdb = [ + $ssdbKey, + implode(',',$receiveSsdb) + ]; + if(false === $ssdb->exec('hset',SsdbKeysPrefix::COUPON_REBATE_RECEIVE, $saveSsdb)){ + $errorData['msg'] = '记录领取优惠券到ssdb失败'; + $this->log->event( + LogLabel::COUPON_LOG, + $errorData + ); + }; + } + }else{ + $result['status'] = 2; + $result['coupon_text'] = '您已领取!赶快去下单吧~'; + } + + return $result; + } + + /* + * 判断用户是否已领取过优惠券 + * */ + public function isCouponRebate($user_id) + { + //获取SSDB上的活动信息 + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + $active = $ssdb->exec('hgetall',SsdbKeysPrefix::COUPON_REBATE_ACTIVITY); + $coupon_ids = explode(',',$active['forward']); + $res = Db::table('ims_system_coupon_user as u') + ->leftjoin('ims_system_coupon_user_receive as r', 'u.id', '=', 'r.system_coupon_user_id') + ->whereIn('r.system_coupon_user_id',$coupon_ids) + ->where([ + ['r.user_id', '=', $user_id], + ['r.receive_type', '=', 4], + ['u.active_type', '=', 2], + ]) + ->select('r.id') + ->first(); + return $res; + } + + /* + *获取活动信息 + */ + public function getActiveInfo() + { + //获取SSDB上的活动信息 + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + $active = $ssdb->exec('hgetall',SsdbKeysPrefix::COUPON_REBATE_ACTIVITY); + $coupon_ids = explode(',',$active['forward']); + $time = time(); + $res = Db::table('ims_system_coupon_user') + ->whereIn('id',$coupon_ids) + ->where([ + ['status', '=', 1], + ['active_type', '=', 2], + ['start_time', '<=', $time], + ['end_time', '>', $time], + ]) + ->whereRaw('inventory > inventory_use') + ->orderBy('weigh', 'desc') + ->orderBy('addtime', 'desc') + ->get(); + return $res; + } + + /** + * 将优惠券绑定活动 + * 领取优惠券 COUPON_REBATE_FORWARD 可多张 + * 返还优惠券 COUPON_REBATE_REPAY 只一张 + */ + public function tieCouponActive($couponActivity, $couponForward, $couponRepay) + { + + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + + $data = [ + 'activity', $couponActivity, + 'forward' , $couponForward, + 'repay' , $couponRepay + ]; + + $result = [ + 'result' => ($ssdb->exec('multi_hset', SsdbKeysPrefix::COUPON_REBATE_ACTIVITY, $data) === false) ? false : true , + 'data' => $ssdb->exec('hgetall', SsdbKeysPrefix::COUPON_REBATE_ACTIVITY) + ]; + + return $result; + } + + /* + * 支付成功 返券 + */ + public function couponRebate($order_id) + { + //获取SSDB上的活动信息 + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + $active = $ssdb->execWithoutTask('hgetall',SsdbKeysPrefix::COUPON_REBATE_ACTIVITY); + //判断返券优惠券是否有库存 + $inventory = Db::table('ims_system_coupon_user') + ->where('id',$active['repay']) + ->whereRaw('inventory > inventory_use') + ->exists(); + if(!$inventory){ + //库存不足 + return false; + } + + //获取活动发放优惠券id + $coupon_ids = explode(',',$active['forward']); + + /* 判断被使用的优惠券类型是否为转发活动优惠券 */ + $coupon = Db::table('ims_system_coupon_user_receive as r') + ->leftjoin('ims_system_coupon_user_use as u', 'u.user_receive_id', '=', 'r.id') + ->where([ + ['u.order_main_id', '=', $order_id], + ['r.send_user_id', '>', 0], + ['r.rebate_type', '=', 1], + ['r.receive_type', '=', 4], + ]) + ->whereIn('r.system_coupon_user_id',$coupon_ids) + ->select('r.user_id', 'r.send_user_id') + ->first(); + /* 如果使用的优惠券为转发活动优惠券 则给赠送者返一张优惠券*/ + if (isset($coupon->send_user_id) && ($coupon->send_user_id) > 0) { + //是否已返过券 + $exists_coupon_rebate = Db::table('ims_system_coupon_user_receive') + ->where([ + ['system_coupon_user_id' ,'=', $active['repay']], + ['user_id' ,'=', $coupon->send_user_id], + ['receive_type' ,'=', 5], + ]) + ->select('id','status') + ->first(); + //开启事务 + Db::beginTransaction(); + try { + //返券 + if($exists_coupon_rebate->id){ + //如果已有该优惠券 则领取数量 和 可用数量 自增1 + Db::table('ims_system_coupon_user_receive') + ->where([ + ['id' ,'=', $exists_coupon_rebate->id], + ]) + ->increment('number'); + Db::table('ims_system_coupon_user_receive') + ->where([ + ['id' ,'=', $exists_coupon_rebate->id], + ]) + ->increment('number_remain'); + //如果该用户在领取表中 status为已用完状态 2 则改为已用部分 1 + if($exists_coupon_rebate->status == 2){ + Db::table('ims_system_coupon_user_receive') + ->where([ + ['id' ,'=', $exists_coupon_rebate->id], + ]) + ->update(['status' => 1]);; + } + }else { + //否则新增一条返券记录 + $nowTime = time(); + Db::table('ims_system_coupon_user_receive')->insert([ + [ + 'user_id' => $coupon->send_user_id, + 'system_coupon_user_id' => $active['repay'], + 'receive_type' => 5, + 'status' => 0, + 'number' => 1, + 'number_remain' => 1, + 'order_main_id' => $order_id, + 'receive_time' => $nowTime, + 'update_time' => $nowTime, + 'created_at' => $nowTime, + 'updated_at' => $nowTime, + ] + ]); + } + //首次返券更新rebate_type字段 防止重复返券 + Db::table('ims_system_coupon_user_receive') + ->where([ + ['user_id','=',$coupon->user_id], + ['receive_type','=',4], + ]) + ->whereIn('system_coupon_user_id',$coupon_ids) + ->update(['rebate_type' => 2]); + //更新库存操作 + Db::table('ims_system_coupon_user') + ->where('id', $active['repay']['repay']) + ->increment('inventory_use'); + + // 提交 + Db::commit(); + } catch (\Exception $e) { + // 回滚 + Db::rollBack(); + $log_Data = array(); + $log_Data['name'] = '返券'; + $log_Data['order_main_id'] = $order_id; + $log_Data['msg'] = '返券失败'; + $this->log->event( + LogLabel::COUPON_LOG, + $log_Data + ); + } + } + $log_Data = array(); + $log_Data['name'] = '返券'; + $log_Data['user_id'] = $order_id; + $log_Data['send_user_id'] = $coupon->send_user_id; + $log_Data['order_main_id'] = $order_id; + $log_Data['msg'] = '返券成功'; + $this->log->event( + LogLabel::COUPON_LOG, + $log_Data + ); + return true; + } + + /** + * 清优惠券领取记录(SSDB) + */ + public function clearSsdbCouponReceiveByName($activity, $userId, $get = 0, $isAll = 0){ + $key = 'activity_'.$activity.'_user_'.$userId; + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + + if($isAll > 0){ + if($get > 0){ + return $ssdb->exec('hgetAll', SsdbKeysPrefix::COUPON_REBATE_RECEIVE); + }else{ + return ( $ssdb->exec('hclear', SsdbKeysPrefix::COUPON_REBATE_RECEIVE) === false) ? false : true ; + } + }else { + if($get > 0){ + return $ssdb->exec('hget', SsdbKeysPrefix::COUPON_REBATE_RECEIVE, $key); + }else{ + return ( $ssdb->exec('hdel', SsdbKeysPrefix::COUPON_REBATE_RECEIVE, $key) === false) ? false : true ; + } + } + } +} \ No newline at end of file diff --git a/app/Service/CouponRebateServiceInterface.php b/app/Service/CouponRebateServiceInterface.php new file mode 100644 index 0000000..df8fc5d --- /dev/null +++ b/app/Service/CouponRebateServiceInterface.php @@ -0,0 +1,22 @@ +get(SSDBTask::class); + $couponActivity = $ssdb->exec('hgetall', SsdbKeysPrefix::COUPON_REBATE_ACTIVITY); + $activityType = $couponActivity === false ? 0 : $couponActivity['activity']; + + $result = [ + 'active_type' => 1, + 'not_receive' => [], + 'jump_data' => [ + 'src' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType, + 'src2' => "/zh_cjdianc/pages/couponrebate/index?activity_type=".$activityType, + 'share_bg' => env('OSS_IMG_HOST').'/static/img/coupon_bg.png', + 'receive_bg' => env('OSS_IMG_HOST').'/static/img/coupon_share.png', + 'coupons' => [] + ] + ]; + $nowTime = time(); + $c_ids = []; + $whereC = [ + ['end_time','>',$nowTime], + ['start_time','<=',$nowTime], + ['status','=',1] + ]; + // 渠道开启,查询该渠道可以领取的优惠券ID + // 渠道未开启,查询所有优惠券 + if (env('SUB_CHANNEL') == 1) { + $c_ids = CouponUserRecType::where('receive_type', $receiveType)->where($whereC)->pluck('system_coupon_user_id'); + } else { + $c_ids = Coupon::where($whereC)->pluck('id'); + } + + $couponReceive = CouponRec::where('user_id',$userId); + + // 渠道开启,查询该用户在此渠道领过的优惠券ID + if (env('SUB_CHANNEL') == 1) { + $couponReceive->where('receive_type', $receiveType); + } + $cr_ids = $couponReceive->pluck('system_coupon_user_id'); + + // 可领取的券ID + $c_ids = $c_ids->toArray(); + // 已经领取的券ID + $cr_ids = $cr_ids->toArray(); + + // 当前用户可领的优惠券ID + $couponIds = array_diff($c_ids, $cr_ids); + + // 转发型优惠券 + $couponReceiveIds = ($couponActivity === false || $this->commonService->empty($couponActivity['forward']) )? [] : explode(',',$couponActivity['forward']); + // 所有优惠券 + $couponIds = array_merge($couponIds,$couponReceiveIds); + + $whereC = [ + ['u.end_time','>',$nowTime], + ['u.start_time','<=',$nowTime], + ['u.status','=',1] + ]; + // 查询领取型1 和 转发型2 + $whereActiveType = [1,2]; + + if (env('SUB_CHANNEL') == 1) { + array_push($whereC, ['type.receive_type','=', $receiveType]); + } + + $coupons = Db::table('ims_system_coupon_user as u') + ->join('ims_system_coupon_user_receivetype as type', 'u.id', '=', 'type.system_coupon_user_id') + ->whereIn('u.id', $couponIds) + ->whereIn('u.active_type', $whereActiveType) + ->where($whereC) + ->whereRaw('u.inventory_use < u.inventory and u.inventory-u.inventory_use >= type.one_receive_number') + ->select('u.*','type.one_receive_number') + ->orderBy('u.weigh','desc') + ->get(); + + foreach ($coupons as $k => &$v){ + + if($v->active_type == 1 && count($result['not_receive']) < 4){ + $result['not_receive'][] = $v; + }else if($v->active_type == 2 && in_array($v->id,$couponReceiveIds)){ + $result['jump_data']['coupons'][] = $v->id; + } + + if($v->discount_type == 2){ + $v->discounts = floatval($v->discounts); + } + } + + $result['active_type'] = count($result['jump_data']['coupons']) > 0 ? 2 : $result['active_type'] ; + + return $result; + } + + //统计用户 + public function userCouponAccount() + { + + } + + /** + * 用户领取优惠卷 + */ + public function userReceiveCoupon() + { + + } + + /** + * 获取用户已经领取的优惠卷列表 + */ + public function getUserReceiveCouponList() + { + + } + + /** + * 获取用户当前订单可用的优惠券列表 + * 按分类(1订单 等优惠)分组返回 + */ + public function getUserAvailableCoupons() + { + + } + +} \ No newline at end of file diff --git a/app/Service/CouponServiceInterface.php b/app/Service/CouponServiceInterface.php new file mode 100644 index 0000000..b096ecd --- /dev/null +++ b/app/Service/CouponServiceInterface.php @@ -0,0 +1,18 @@ +get(SSDBTask::class); + + $kvs = []; + foreach ($params as $key => $value) { + $kvs[] = $key; + $kvs[] = $value; + } + + if(false === $ssdb->exec('multi_hset', SsdbKeysPrefix::PARAMS_TOKEN.$token, $kvs)) { + + $this->log->event( + LogLabel::SSDB_LOG, + ['method' => 'multi_hset', 'key' => SsdbKeysPrefix::PARAMS_TOKEN.$token, 'kvs' => $kvs] + ); + + throw new SsdbException(ErrorCode::SSDB_ERROR, 'token生成失败'); + } + + return $token; + } + + /** + * 解析token获取对应数据参数 + * @param $token + */ + public function analyze($token) + { + $ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); + $params = $ssdb->exec('hgetall', SsdbKeysPrefix::PARAMS_TOKEN.$token); + + if (false === $params) { + + $this->log->event( + LogLabel::SSDB_LOG, + ['method' => 'hgetall', 'key' => SsdbKeysPrefix::PARAMS_TOKEN.$token, 'params' => $params] + ); + + throw new SsdbException(ErrorCode::SSDB_ERROR, 'token解析失败'); + } + + if (empty($params)) { + + $this->log->event( + LogLabel::SSDB_LOG, + ['method' => 'hgetall', 'key' => SsdbKeysPrefix::PARAMS_TOKEN.$token, 'params' => $params] + ); + + throw new SsdbException(ErrorCode::SSDB_ERROR, 'token不存在'); + } + + return $params; + } + +} \ No newline at end of file diff --git a/app/TaskWorker/SSDBTask.php b/app/TaskWorker/SSDBTask.php new file mode 100644 index 0000000..fd4d451 --- /dev/null +++ b/app/TaskWorker/SSDBTask.php @@ -0,0 +1,46 @@ +client()->__call($method,$args); + + return $result; + } + + public function execWithoutTask($method,...$args) + { + $result = $this->client()->__call($method,$args); + + return $result; + } + + protected function client(){ + if ($this->ss instanceof SimpleSSDB) { + return $this->ss; + } + + $this->ss = new SimpleSSDB(env('SSDB_HOST'), env('SSDB_PORT')); + $this->ss->auth(env('SSDB_AUTH')); + + return $this->ss; + + } +} + diff --git a/composer.json b/composer.json index 1ac7889..5553ffb 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "hyperf/config": "~2.0.0", "hyperf/db-connection": "~2.0.0", "hyperf/framework": "~2.0.0", - "hyperf/guzzle": "~2.0.0", + "hyperf/guzzle": "^2.0", "hyperf/http-server": "~2.0.0", "hyperf/logger": "~2.0.0", "hyperf/memory": "~2.0.0", @@ -27,7 +27,10 @@ "hyperf/redis": "~2.0.0", "hyperf/constants": "~2.0.0", "hyperf/model-cache": "~2.0.0", - "hyperf/validation": "^2.0", + "hyperf/filesystem": "^2.0", + "xxtime/flysystem-aliyun-oss": "^1.5", + "hyperf/validation": "^2.0", + "hyperf/task": "^2.0", "hyperf/paginator": "^2.0" }, "require-dev": { diff --git a/config/autoload/amqp.php b/config/autoload/amqp.php new file mode 100644 index 0000000..e14780a --- /dev/null +++ b/config/autoload/amqp.php @@ -0,0 +1,33 @@ + [ + 'host' => env('RQM_HOST', 'localhost'), + 'port' => 5672, + 'user' => env('RQM_USER','guest'), + 'password' => env('RQM_PASSWORD','guest'), + 'vhost' => '/', + 'concurrent' => [ + 'limit' => 1, + ], + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + ], + 'params' => [ + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'connection_timeout' => 3.0, + 'read_write_timeout' => 6.0, + 'context' => null, + 'keepalive' => false, + 'heartbeat' => 3, + 'close_on_destruct' => false, + ], + ] +]; diff --git a/config/autoload/dependencies.php b/config/autoload/dependencies.php index cccee93..28a2970 100644 --- a/config/autoload/dependencies.php +++ b/config/autoload/dependencies.php @@ -10,5 +10,12 @@ declare(strict_types=1); * @license https://github.com/hyperf/hyperf/blob/master/LICENSE */ return [ - \App\Service\ServiceEvaluateServiceInterface::class => \App\Service\ServiceEvaluateService::class + \App\Service\ServiceEvaluateServiceInterface::class => \App\Service\ServiceEvaluateService::class, + \App\Service\AttachmentServiceInterface::class => \App\Service\AttachmentService::class, + \App\Service\ParamsTokenServiceInterface::class => \App\Service\ParamsTokenSsdbService::class, + \App\Service\AdServiceInterface::class => \App\Service\AdService::class, + \App\Commons\Log::class => \App\Commons\Log::class, + \App\Service\CouponRebateServiceInterface::class => \App\Service\CouponRebateService::class, + \App\Service\UserServiceInterface::class => \App\Service\UserService::class, + \App\Service\CouponServiceInterface::class => \App\Service\CouponService::class, ]; diff --git a/config/autoload/exceptions.php b/config/autoload/exceptions.php index cca06d6..0aa0812 100644 --- a/config/autoload/exceptions.php +++ b/config/autoload/exceptions.php @@ -14,7 +14,8 @@ return [ 'http' => [ Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class, App\Exception\Handler\AppExceptionHandler::class, - \App\Exception\Handler\ValidationExceptionHandler::class, + App\Exception\Handler\ValidationExceptionHandler::class, + App\Exception\Handler\SsdbExceptionHandler::class, ], ], ]; diff --git a/config/autoload/middlewares.php b/config/autoload/middlewares.php index 5269173..2befbcd 100644 --- a/config/autoload/middlewares.php +++ b/config/autoload/middlewares.php @@ -11,6 +11,7 @@ declare(strict_types=1); */ return [ 'http' => [ + \App\Middleware\CorsMiddleware::class, \App\Middleware\Auth\ApiMiddleware::class, \Hyperf\Validation\Middleware\ValidationMiddleware::class, ], diff --git a/config/autoload/server.php b/config/autoload/server.php index e0e6cd8..f44b083 100644 --- a/config/autoload/server.php +++ b/config/autoload/server.php @@ -36,16 +36,13 @@ return [ 'max_request' => 100000, 'socket_buffer_size' => 2 * 1024 * 1024, 'buffer_output_size' => 2 * 1024 * 1024, - // Task Worker 数量,根据您的服务器配置而配置适当的数量 'task_worker_num' => 8, - // 因为 `Task` 主要处理无法协程化的方法,所以这里推荐设为 `false`,避免协程下出现数据混淆的情况 'task_enable_coroutine' => false, ], 'callbacks' => [ SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], SwooleEvent::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'], - // Task callbacks SwooleEvent::ON_TASK => [Hyperf\Framework\Bootstrap\TaskCallback::class, 'onTask'], SwooleEvent::ON_FINISH => [Hyperf\Framework\Bootstrap\FinishCallback::class, 'onFinish'], ], diff --git a/config/routes.php b/config/routes.php index e75b7ce..e68c605 100644 --- a/config/routes.php +++ b/config/routes.php @@ -35,12 +35,12 @@ Router::addGroup('/v1/',function (){ Router::post('CouponRebate/tieCouponActive', 'App\Controller\CouponRebateController@tieCouponActive'); Router::post('CouponRebate/couponRebate', 'App\Controller\CouponRebateController@couponRebate'); Router::post('CouponRebate/clearSsdbReceive', 'App\Controller\CouponRebateController@clearSsdbCouponReceiveByName'); - //播报器相关 + // Router::post('Device/bind', 'App\Controller\DeviceController@bind'); Router::post('Device/list', 'App\Controller\DeviceController@list'); Router::post('Device/unbind', 'App\Controller\DeviceController@unbind'); - //测试路由 + //· Router::get('test/index1', 'App\Controller\TestController@index1'); Router::post('Store/applyEntry', 'App\Controller\StoreController@applyEntry');