Commit ccc31497 authored by zazaname's avatar zazaname

聚合服务端api1.0

parents
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
APP_NAME=Lumen
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_TIMEZONE=Asia/Shanghai
LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
/vendor
/.idea
Homestead.json
Homestead.yaml
.env
.phpunit.result.cache
.DS_Store
php:
preset: laravel
disabled:
- unused_use
js: true
css: true
# Lumen PHP Framework
[![Build Status](https://travis-ci.org/laravel/lumen-framework.svg)](https://travis-ci.org/laravel/lumen-framework)
[![Total Downloads](https://poser.pugx.org/laravel/lumen-framework/d/total.svg)](https://packagist.org/packages/laravel/lumen-framework)
[![Latest Stable Version](https://poser.pugx.org/laravel/lumen-framework/v/stable.svg)](https://packagist.org/packages/laravel/lumen-framework)
[![License](https://poser.pugx.org/laravel/lumen-framework/license.svg)](https://packagist.org/packages/laravel/lumen-framework)
Laravel Lumen is a stunningly fast PHP micro-framework for building web applications with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Lumen attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as routing, database abstraction, queueing, and caching.
## Official Documentation
Documentation for the framework can be found on the [Lumen website](https://lumen.laravel.com/docs).
## Contributing
Thank you for considering contributing to Lumen! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Security Vulnerabilities
If you discover a security vulnerability within Lumen, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.
## License
The Lumen framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Laravel\Lumen\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
//
}
}
<?php
namespace App\Events;
use Illuminate\Queue\SerializesModels;
abstract class Event
{
use SerializesModels;
}
<?php
namespace App\Events;
class ExampleEvent extends Event
{
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
}
<?php
namespace App\Exceptions;
use App\Utils\Response;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Throwable $exception
* @return void
*
* @throws \Exception
*/
public function report(Throwable $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $e
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*
* @throws \Throwable
*/
public function render($request, Throwable $e)
{
Log::info('MyInfo:' . $e->getMessage());
Log::error('MyError:' . $e->getTraceAsString());
//验证器异常
if ($e instanceof ValidateException) {
return response()->json([
'status' => $e->getCode(),
'msg' => $e->getMessage()
])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
$code = 0 === $e->getCode() ? Response::SERVER_ERROR : $e->getCode();
//其它异常
return response()->json([
'status' => $code,
'msg' => Response::$errMsg[$code] . ':' . $e->getMessage()
])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
// return parent::render($request, $e);
}
}
<?php
namespace App\Exceptions;
use Exception;
use Throwable;
class ValidateException extends Exception
{
public function __construct($message = "", $code = 40010, Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Log;
use Laravel\Lumen\Routing\Controller as BaseController;
class Controller extends BaseController
{
//请求的参数
public $requestData;
//请求者IP
public $clientIp = '';
public function __construct()
{
header("Content-type: text/html; charset=utf-8");
header('Access-Control-Allow-Origin:*');
$this->requestData = request()->all();
$this->clientIp = request()->ip();
}
/**
* 检查必要参数
* @param array $paramConf 指定必要参数
* @param str $all 是否全配置
*/
public function checkParam($paramConf, $all = '')
{
if (!empty($all)) {
//对待匹配
if (count(array_diff(array_keys($this->requestData), $paramConf)) >= 1)
echo json(error('必须按指定参数来传参'));
return ;
} else {
//检查指定参数是否存在
if (count($paramConf) != count(array_intersect($paramConf, array_keys($this->requestData))))
echo json(error('缺少必须参数'));
return ;
}
}
/**
* 成功格式化返回
*
* @param $data
* @return \Illuminate\Http\JsonResponse
*/
protected function success($data = [])
{
$res = [
'status' => $data['code'] ?? 200,
'msg' => $data['message'] ?? 'success',
'data' => $data['data'] ?? []
];
echo response()->json($res)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
exit();
}
/**
* 失败格式化返回
*
* @param $message
* @param $code
* @return \Illuminate\Http\JsonResponse
*/
protected function fail($message = 'fail', $code = 500)
{
$res = [
'status' => $code,
'msg' => $message,
'data' => []
];
Log::error(json_encode($res, JSON_UNESCAPED_UNICODE));
echo response()->json($res)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
exit();
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
class ExampleController
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//
}
public function test(Request $request){
// dingdingLog($request->all());
return json(['code'=>200,'message'=>'发货成功']);
}
}
<?php
namespace App\Http\Controllers;
use App\Http\Service\LoginService;
use Illuminate\Http\JsonResponse;
class LoginController extends Controller
{
private $loginService;
public function __construct()
{
parent::__construct();
$this->loginService = new LoginService();
}
/**
* 融合登录
* @return JsonResponse
*/
public function createToken()
{
$this->checkParam(['app_id','ver_info','ctype']);
$data = $this->loginService->createToken($this->requestData);
return json($data);
}
/**
* 接收token,校验是否正确并返回聚合户信息
*/
public function checkToken(){
$this->checkParam(['token','uid']);
$data = $this->loginService->getTokenInfo($this->requestData);
return json($data);
}
}
<?php
namespace App\Http\Controllers;
use App\Http\Service\PayService;
use Illuminate\Http\JsonResponse;
class PayController extends Controller
{
private $paySv;
public function __construct()
{
parent::__construct();
$this->paySv = new PayService();
}
/**
* 创建订单,返回订单ID
* @return JsonResponse
*/
public function createOrder()
{
$this->checkParam(['app_id','ctype','uid','cp_order_id','role_id','role_name','server_id','money']);
$data = $this->paySv->createOrder($this->requestData);
return json($data);
}
/**
* 确认下单,二次校验订单金额等,返回订单状态
* @return JsonResponse
*/
public function confirmOrder(){
$this->checkParam(['app_id','ctype','uid','order_id','money']);
$data = $this->paySv->confirmOrder($this->requestData);
return json($data);
}
/**
* 渠道支付回调,平台标识找sdk配置,验签,通过则向CP发起发货通知
*/
public function verBack(){
$this->checkParam(['app_id','ver']);
$data = $this->paySv->verBack($this->requestData);
return is_array($data) ? json($data) : $data;
}
}
<?php
namespace App\Http\Controllers;
use App\Http\Service\InitService;
use App\Http\Service\RoleService;
class ReportController extends Controller
{
/**
* 设备初始化
*
* @return \Illuminate\Http\JsonResponse
*/
public function init()
{
$this->checkParam(['app_id','ctype']);
$indexSv = new InitService();
$data = $indexSv->storeInitData($this->requestData);
return json($data);
}
/**
* 角色上报
* @return \Illuminate\Http\JsonResponse
*/
public function role()
{
$this->checkParam(['uid','app_id','ctype','role_id','role_name','role_level','server_id','server_name']);
$roleSv = new RoleService();
$data = $roleSv->storeRoleData($this->requestData);
return json($data);
}
}
<?php
namespace App\Http\Dao;
use App\Models\ChannelConfig;
class ChannelConfigDao extends ChannelConfig
{
/**
* 获取单条记录
* @param array $where
* @return mixed
*/
public function getFirstRecord(array $where)
{
return self::where($where)
->first();
}
}
<?php
namespace App\Http\Dao;
use App\Models\Channel;
class ChannelDao extends Channel
{
/**
* 根据id获取渠道记录
*
* @param int $id
* @return mixed
*/
public function getRecordById(int $id)
{
return self::where('id', $id)->first();
}
}
<?php
namespace App\Http\Dao;
use App\Models\ChannelMaster;
class ChannelMasterDao extends ChannelMaster
{
/**
* 根据id获取渠道商记录
*
* @param int $id
* @return mixed
*/
public function getRecordById(int $id)
{
return self::where('id', $id)->first();
}
}
<?php
namespace App\Http\Dao;
use App\Models\DeviceRegister;
class DeviceRegisterDao extends DeviceRegister
{
/**
* 通过单个字段名及字段值查询单条数据
*
* @param string $fieldName
* @param $fieldVal
* @return mixed
*/
public function getRecordFromFieldAndVal(string $fieldName, $fieldVal)
{
return self::where($fieldName, '=', $fieldVal)->first();
}
/**
* 插入单条记录
*
* @param array $data
* @return mixed
*/
public function insertRecord(array $data)
{
return self::insert($data);
}
}
<?php
namespace App\Http\Dao;
use App\Models\Game;
class GameDao extends Game
{
/**
* 根据id获取游戏记录
*
* @param int $id
* @return mixed
*/
public function getRecordById(int $id)
{
return self::where('id',$id)->first();
}
}
<?php
namespace App\Http\Dao;
use App\Models\GameRole;
class GameRoleDao extends GameRole
{
/**
* 插入记录
*
* @param array $data
* @return mixed
*/
public function insertData(array $data)
{
return self::insert($data);
}
/**
* 通过id进行记录更新
*
* @param int $id
* @param array $updateData
* @return mixed
*/
public function updateById(int $id,array $updateData)
{
return self::where('id', $id)->update($updateData);
}
}
<?php
namespace App\Http\Dao;
use App\Models\GameRoleLog;
class GameRoleLogDao extends GameRoleLog
{
/**
* 插入记录
*
* @param array $data
* @return mixed
*/
public function insertData(array $data)
{
return self::insert($data);
}
}
<?php
namespace App\Http\Dao;
use App\Models\GameUser;
use App\Utils\CommonFunc;
class GameUserDao extends GameUser
{
public function addUserInfo(array $params,array $userInfo)
{
$gameUserObj = $this->getFirstRecord(['app_id'=>$params['app_id'],'channel_id'=>$params['channel_id'],channel_user_id=>$userInfo['user_id']]);
//生成token
$token = CommonFunc::generateToken((int)$userInfo['user_id'], (int)$params['app_id'], (int)$params['channel_id']);
if (!$gameUserObj) {
$gameUserArr = [
'name' => '',
'app_id' => $params['app_id'],
'channel_id' => $params['channel_id'],
'channel_user_id' => $userInfo['user_id'],
'channel_user_name' => '',
'channel_user_nick' => '',
'token' => $token,
'last_login_time' => date('Y-m-d H:i:s'),
'created_at' => date('Y-m-d H:i:s'),
];
$this->insertDataGetId($gameUserArr);
} else {
//存在用户记录则更新最后一次登录时间
$this->updateById(['app_id'=>$params,'channel_id'=>$params['channel_id'],'channel_user_id'=>$userInfo['user_id']], ['last_login_time' => date('Y-m-d H:i:s'),'token'=>$token]);
}
return $token;
}
/**
* 获取单条数据
* @return mixed
*/
public function getFirstRecord(array $where)
{
return self::where($where)
->first();
}
/**
* 插入记录并获取插入记录的id
*
* @param array $insertData
* @return mixed
*/
public function insertDataGetId(array $insertData)
{
return self::insertGetId($insertData);
}
/**
* 通过id进行记录更新
*
* @param int $id
* @param array $updateData
* @return mixed
*/
public function updateById(array $where,array $updateData)
{
return self::where($where)->update($updateData);
}
}
<?php
namespace App\Http\Dao;
use App\Models\LoginLog;
use App\Utils\CommonFunc;
class LoginLogDao extends LoginLog
{
/**
* 保存日志
* @param $params
* @param $userInfo
* @return mixed
*/
public function saveData($params,$userInfo)
{
$data = [
'app_id' => $params['app_id'],
'channel_id' => $params['channel_id'],
'user_id' => $userInfo['user_id'],
'imei' => $params['imei'] ?: '',
'oaid' => $params['oaid'] ?: '',
'sdk_version' => $params['sdk_version'] ?: '',
'ip' => CommonFunc::getTrustedProxiesIp(),
'log_date' => date("Y-m-d"),
'created_at' => date("Y-m-d H:i:s"),
];
return self::insert($data);
}
}
<?php
namespace App\Http\Dao;
use App\Models\Order;
class OrderDao extends Order
{
/**
* 查找订单号的单条记录
* @param array $where
* @return mixed
*/
public function getFirstRecord(array $where)
{
return Order::where($where)
->first();
}
/**
* 查找订单号的单条记录
* @param array $where
* @return mixed
*/
public function getFirstRecordByStr(string $where)
{
return Order::where($where)
->first();
}
/**
* 插入单条记录
*
* @param array $data
* @return mixed
*/
public function insertData(array $data)
{
return self::insert($data);
}
/**
* 通过id进行记录更新
*
* @param int $id
* @param array $updateData
* @return mixed
*/
public function updateById(int $id, array $updateData)
{
return self::where('id', $id)->update($updateData);
}
}
<?php
namespace App\Http\Dao;
use App\Models\RegisterLog;
class RegisterLogDao extends RegisterLog
{
/**
* 插入记录
*
* @param array $data
* @return mixed
*/
public function insertData(array $data)
{
return self::insert($data);
}
}
<?php
namespace App\Http\Dao;
use App\Models\Channel;
class SdkDao extends Channel
{
/**
* 根据id获取渠道记录
*
* @param int $id
* @return mixed
*/
public function getRecordById(int $id)
{
return self::where('id', $id)->first();
}
}
<?php
namespace App\Http\Dto;
use App\Exceptions\ValidateException;
use App\Utils\Response;
use Illuminate\Support\Facades\Validator;
class BaseDto
{
protected $rules = [];
protected $message = [];
public $requestData;
protected $validator;
/**
* 数据校验
*
* @param array $data
* @throws ValidateException
*/
public function dataValidate(array $data)
{
//基础校验器取数据方法
$this->validator = Validator::make($data, $this->rules, $this->message);
$this->requestData = $this->validator->getData();
if ($this->validator->fails()) {
throw new ValidateException($this->validator->errors()->first());
}
$this->validator->after(function () {
$bool = $this->customValidate();
if (!$bool) {
throw new ValidateException($this->validator->errors()->first(),Response::PARAM_ERROR);
}
});
}
/**
* 自定义验证(如有需要,子类进行重写)
*/
protected function customValidate(): bool
{
return true;
}
}
<?php
namespace App\Http\Dto;
class IndexInitDto extends BaseDto
{
protected $rules = [
'appID' => 'required',
'channelID' => 'required',
'version' => 'required',
];
protected $message = [
'appID.required' => 'appId不能为空',
'channelID.required' => '渠道id不能为空',
'version.required' => 'SDK版本号不能为空!',
];
}
<?php
namespace App\Http\Dto;
class OrderStateDto extends BaseDto
{
protected $rules;
public function __construct()
{
$this->rules = [
'orderID' => 'required|integer|min:1',
'productName' => 'required|string|max:255',
'serverID' => 'required|string|max:255',
'money' => 'required|numeric|min:0',
'extension' => 'required',
'sign' => 'required',
'roleID' => 'string|max:255',
];
}
}
<?php
namespace App\Http\Dto;
class PayOrderIdDto extends BaseDto
{
protected $rules;
public function __construct()
{
$this->rules = [
'userID' => 'required|integer|min:1',
'productID' => 'required|string|max:64',
'productName' => 'required|string|max:255',
'productDesc' => 'required|string|max:255',
'money' => 'required|numeric|min:0',
'roleID' => 'required|string|max:255',
'roleName' => 'required|string|max:255',
'serverID' => 'required|string|max:255',
'serverName' => 'required|string|max:255',
'extension' => 'required',
'sign' => 'required',
];
}
}
<?php
namespace App\Http\Dto;
use Illuminate\Validation\Rule;
class RoleSubmitDataDto extends BaseDto
{
protected $rules;
public function __construct()
{
$this->rules = [
'appID' => 'required|integer|min:1',
'roleID' => 'required|string|max:255',
'roleName' => 'required|string|max:255',
'vipLevel' => 'required|integer|min:0',
'serverID' => 'required|string|max:255',
'serverName' => 'required|string|max:255',
'guild' => ['required', Rule::in([1, 2, 3, 4, 5])],
'roleLevel' => 'integer|min:0',
'onlineLength' => 'integer|min:0',
'moneyNum' => 'integer|min:0',
'userID' => 'integer|min:0',
'channelID' => 'integer|min:0',
];
}
}
<?php
namespace App\Http\Dto;
class UserLoginDto extends BaseDto
{
protected $rules = [
'appID' => 'required',
'channelID' => 'required',
'sdkVersionCode' => 'required',
'extension' => 'required',
];
protected $message = [
'appID.required' => 'appId不能为空',
'channelID.required' => '渠道Id不能为空',
'sdkVersionCode.required' => 'SDK版本号不能为空!',
'extension.required' => 'extension不能为空!',
];
}
<?php
namespace App\Http\Dto;
class UserVerifyAccountDto extends BaseDto
{
protected $rules = [
'userId' => 'required|integer|min:1',
'token' => 'required',
'sign' => 'required',
];
protected $message = [
'userId.required' => '用户id不能为空',
'userId.min' => '用户id参数有误',
'token.required' => 'token不能为空',
'sign.required' => '签名不能为空!',
];
}
<?php
namespace App\Http\InterfaceClass;
interface ISdkFactory
{
// 登录
public function login( $verInfo, $gameInfo, $request): array;
// 支付
public function pay( $verInfo, $gameInfo, $request): array;
}
<?php
namespace App\Http\InterfaceClass\SdkImpl;
use App\Http\InterfaceClass\ISdkFactory;
use Illuminate\Support\Facades\Log;
use WpOrg\Requests\Requests;
class Jiuzi implements ISdkFactory
{
// 登录接口
protected $login_url = "https://h5sdk.snkad.com.cn/auth/checktoken";
/**
* 登录
* @param $verInfo 渠道表信息
* @param $gameInfo 游戏表信息
* @param $request request 参数
* @return array
*/
public function login($verInfo,$gameInfo, $request): array
{
$ver_info = json_decode($request['ver_info'],true);
//获取请求参数
$postParam = [
'uid' => $ver_info['unionId'],
'access_token' => $ver_info['access_token'],
'gid' => $verInfo->ver_appid,
'version' => $request['unionId'] ?? 1,
];
//请求url,获取返回值
//$response = Requests::post($this->login_url,[],$postParam)->body;
$response = '{"message":"ok","statusCode":200,"data":{"partnerid":"own","user_id":34,"openid":"qwewqqwe","age":0}}';
//是否验证成功
$response_arr = json_decode($response,true);
if ($response_arr['statusCode'] === 200) {
// 用类标识_渠道userid 标识为融合账号
$uname = $verInfo->ver."_".$response_arr['data']['openid'];
return ['ver_user_id' => $response_arr['data']['openid'],'uname'=>$uname];
} else {
return [];
}
}
/**
* 支付验签,返回订单号等信息
* @param $gameInfo
* @param array $params
* @return array
*/
public function pay($verInfo,$gameInfo, $request): array
{
// 先验签
$str = "order_num={$request['order_num']}&partnerid={$request['partnerid']}&user_id={$request['user_id']}&gid={$gameInfo->ver_appid}&sid={$request['sid']}&money={$request['money']}&order_ip={$request['order_ip']}&is_test={$request['is_test']}&game_other={{$request['game_other']}}&payts={{$request['payts']}}&pay_key={$gameInfo->ver_paykey}";
Log::info("签名明文:".$str);
$mySign = strtolower(md5($str));
if($mySign !== $request['sign']){
Log::info("签名失败,我方签名:{$mySign},渠道签名:{$request['sign']},渠道request参数:".var_export(request()->post(), true));
return $this->result(300,'发货失败',$request['order_num']);
}
Log::info("签名通过");
// 通过则返回订单号,金额[单位元]
return [
'order_id' => $request['order_num'],
'money' => $request['money'],
'result' => $this->result('200','发货成功',$request['order_num'])
];
}
/**
* 按渠道的格式返回
* @param $statusCode
* @param $message
* @param $order_id
* @return array
*/
protected function result($statusCode,$message,$order_id){
return [
'message' => $message,
'statusCode' => $statusCode,
'data' => [
'order_num' => $order_id
],
];
}
}
<?php
namespace App\Http\Manager;
use App\Utils\HttpRequestTool;
use RuntimeException;
class HttpChannelSdkManager
{
/** @var HttpRequestTool */
private $httpMg;
public function __construct()
{
$channelSdkHost = '';
$this->httpMg = new HttpRequestTool($channelSdkHost);
}
/**
* 获取用户信息
*
* @return mixed
*/
public function getUserInfo()
{
$uri = '/api/TemporaryQrCode/statisticsByToken';
// $data = ['link' => $idAndToken, 'wxh' => $serviceName, 'start_at' => $beginTime, 'end_at' => $endTime];
$data = [];
$responseData = $this->httpMg->requestByJson('POST', $uri, $data);
if (0 !== (int)$responseData['code']) {
throw new RuntimeException($responseData['msg']);
}
return $responseData['data'];
}
}
<?php
namespace App\Http\Manager;
use App\Http\InterfaceClass\ISdkFactory;
use App\Models\ChannelGame;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\App;
use RuntimeException;
class SdkManager
{
/**
* 登录
* @param $verInfo
* @param $gameInfo
* @param $params
* @return array
*/
public function login( $verInfo, $gameInfo, $params): array
{
$channelClass = ucfirst($verInfo->ver_class);
try {
/** @var ISdkFactory $sdkObj */
$sdkFileClass = "App\\Http\\InterfaceClass\\SdkImpl\\{$channelClass}";
$sdkObj = new $sdkFileClass;
if (!$sdkObj instanceof ISdkFactory) {
throw new RuntimeException($channelClass . '不是ISdkFactory子类!');
}
} catch (Exception $e) {
$msg = '创建' . $channelClass . '类失败!';
throw new RuntimeException($msg);
}
return $sdkObj->login($verInfo,$gameInfo, $params);
}
/**
* 支付
* @param $verInfo
* @param $gameInfo
* @param $params
* @return array
*/
public function pay($verInfo, $gameInfo, $params): array
{
$channelClass = ucfirst($verInfo->ver_class);
try {
/** @var ISdkFactory $sdkObj */
$sdkFileClass = "App\\Http\\InterfaceClass\\SdkImpl\\{$channelClass}";
$sdkObj = new $sdkFileClass;
if (!$sdkObj instanceof ISdkFactory) {
throw new RuntimeException($channelClass . '不是ISdkFactory子类!');
}
} catch (Exception $e) {
$msg = '创建' . $channelClass . '类失败!';
throw new RuntimeException($msg);
}
return $sdkObj->pay($verInfo,$gameInfo, $params);
}
}
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
class Authenticate
{
/**
* The authentication guard factory instance.
*
* @var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* @param \Illuminate\Contracts\Auth\Factory $auth
* @return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ($this->auth->guard($guard)->guest()) {
return response('Unauthorized.', 401);
}
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use Closure;
class ExampleMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
<?php
namespace App\Http\Service;
use App\Utils\CommonFunc;
use App\Utils\Response;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
class InitService
{
/**
* 存储设备初始化数据
* @param array $params
* @return bool
*/
public function storeInitData(array $params)
{
//查询设备号
if (isset($params['oaid']) && $params['oaid']) {
$fieldName = 'oaid';
$fieldVal = $params['oaid'];
} elseif (isset($params['imei']) && $params['imei']) {
$fieldName = 'imei';
$fieldVal = $params['imei'];
} elseif (isset($params['androidID']) && $params['androidID']) {
$fieldName = 'android_id';
$fieldVal = $params['androidID'];
} else {
$fieldName = $fieldVal = '';
}
// 查询设备是否存在
if ($fieldName && $fieldVal) {
//查询设备标识号看是否已存在该记录
$deviceObj = DB::table('app_device')->where([$fieldName => $fieldVal])->first();
if (is_null($deviceObj)) {
$params['created_at'] = time();
$params['type'] = $params['type'] ?? 'nvandroid';
Db::name('app_device')->strict(false)->insert($params);
}
}
return success("初始化成功");
}
}
<?php
namespace App\Http\Service;
use App\Http\Manager\SdkManager;
use App\Models\ChannelConfig;
use App\Models\GameConfig;
use App\Utils\CommonFunc;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use RuntimeException;
class LoginService
{
// 游戏配置
private $gameConfig;
// 渠道配置
private $channelConfig;
public function __construct()
{
$this->gameConfig = new GameConfig();
$this->channelConfig = new ChannelConfig();
}
/**
* 登录sdk并返回一个token
* @param array $params
* @return array[]
*/
public function createToken(array $params): array
{
$sdkManager = new SdkManager();
//获取游戏表配置
$gameInfo = DB::table("app_games_config")
->where(['app_id' => $params['app_id']])->first();
if (is_null($gameInfo)) {
return error('该游戏配置不存在,app_id:' . $params['app_id']);
}
// 获取渠道表配置
$verInfo = DB::table("app_ver_game as avg")
->leftJoin('app_ver as av', 'avg.ver', '=', 'av.ver_class')
->where(['app_id' => $params['app_id'], 'ver_code' => $params['ctype']])->first();
if (is_null($verInfo)) {
return error('该游戏渠道没配置,app_id:' . $params['app_id']);
}
//登录成功则返回userinfo
$loginInfo = $sdkManager->login($verInfo, $gameInfo, $params);
if (!$loginInfo) {
return error('渠道登录失败!');
}
// 判断用户是否存在,appid为CP的appid
$userInfo = DB::table('app_member')->where(['app_id' => $params['app_id'], 'uname' => $loginInfo['uname']])->first();
if (is_null($userInfo)) {
//保存聚合用户的信息并返回token
$uid = DB::table('app_member')->insertGetId([
'uname' => $loginInfo['uname'],
'veruniqid' => $loginInfo['ver_user_id'],
'app_id' => $params['app_id'],
'ver' => $params['ctype'] ?? '',
'reg_ip' => CommonFunc::getTrustedProxiesIp(),
'reg_time' => date('Y-m-d H:i:s'),
'login_time' => date('Y-m-d H:i:s'),
'login_ip' => CommonFunc::getTrustedProxiesIp(),
'add_time' => date('Y-m-d H:i:s')
]);
} else {
// 更新登录信息
DB::table('app_member')->where(['uname' => $loginInfo['uname'], 'app_id' => $gameInfo->app_id])->update([
'login_time' => date('Y-m-d H:i:s'),
'login_ip' => CommonFunc::getTrustedProxiesIp()
]);
}
// 保存登录日志
DB::table('app_memberloginlog')->insert([
'uid' => $uid ?? $userInfo->uid,
'uname' => $loginInfo['uname'],
'reg_ver' => $params['ctype'] ?? '',
'reg_time' => date('Y-m-d H:i:s'),
'appid' => $params['app_id'],
'login_ver' => $params['ctype'] ?? '',
'login_time' => date('Y-m-d H:i:s'),
'login_ip' => CommonFunc::getTrustedProxiesIp()
]);
// 产生一个token ,存redis ,有效期5分钟
$uid = $uid ?? $userInfo->uid;
$time = date('Y-m-d H:i:s');
$value = $uid . '|' . $gameInfo->app_id . '|' . $gameInfo->appkey . '|' . $time;
$key = md5($value);
Redis::setex($key, 60 * 60, $value);
return success("第三方登录成功!", ['token' => $key, 'uid' => $uid]);
}
/**
* 根据token获取用户信息
* @param array $params
* @return array
*/
public function getTokenInfo(array $params): array
{
$tokenInfo = Redis::get($params['token']);
if (!$tokenInfo) {
return error('token已过期,请重新获取!');
}
list($uid, $app_id, $appkey, $login_time) = explode('|', $tokenInfo);
// 签名 MD5(appid=appid&token=token&uid=uid&appkey=appkey)
$mysign = md5('appid=' . $app_id . '&token=' . $params['token'] . '&uid=' . $uid . '&appkey=' . $appkey);
if ($mysign !== $params['sign']) {
return error("签名失败!");
}
// 查找用户信息,判断是否正常
$userInfo = DB::table('app_member')->where(['uid' => $uid, 'app_id' => $app_id])->first();
if (is_null($userInfo)) {
return error('用户信息异常!');
}
return success('success', ['uid' => $uid]);
}
}
<?php
namespace App\Http\Service;
use App\Http\Dao\GameDao;
use App\Http\Dao\OrderDao;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class OrderService
{
/**
* 修改支付状态
*
* @param array $params
* @return array
*/
public function changeStatus(array $params): array
{
try {
$orderDao = new OrderDao();
$gameDao = new GameDao();
DB::beginTransaction();
$orderObj = $orderDao->getRecordByOrderId((int)$params['orderID']);
if (!$orderObj) {
Log::info(__CLASS__ . '/' . __FUNCTION__ . ':order_id = ' . $params['orderID']);
throw new \RuntimeException('订单不存在!');
}
if ((int)$orderObj->state !== 1) {
Log::info(__CLASS__ . '/' . __FUNCTION__ . ':order_id = ' . $params['orderID']);
throw new \RuntimeException('订单状态不是未支付!');
}
$gameObj = $gameDao->getRecordById((int)$orderObj->app_id);
if (!$gameObj) {
Log::info(__CLASS__ . '/' . __FUNCTION__ . ':app_id = ' . $orderObj->app_id);
throw new \RuntimeException('订单不存在!');
}
//签名验证
$mdStr = "orderID={$params['orderID']}money={$params['money']}roleID={$params['roleID']}serverID={$params['serverID']}" .
"extension={$params['extension']}$gameObj->appkey";
if (md5($mdStr) !== $params['sign']) {
throw new \RuntimeException('签名验证失败!');
}
//将支付状态从"1-未支付"改为"2-支付中"。
$affectRows = $orderDao->updateById((int)$orderObj->id,['state' => 2, 'updated_at' => date('Y-m-d H:i:s')]);
if (!$affectRows) {
Log::info(__CLASS__ . '/' . __FUNCTION__ . ':order_id = ' . $orderObj->order_id);
throw new \RuntimeException('更新订单状态失败!');
}
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw new \RuntimeException($e->getMessage());
}
return [
'channelID' => $orderObj->channel_id,
'state' => 2,
'money' => $params['money'],
'productName' => $params['productName'],
'roleID' => $orderObj->role_id,
'appID' => $orderObj->app_id,
];
}
}
<?php
namespace App\Http\Service;
use App\Http\Dao\GameDao;
use App\Http\Dao\GameUserDao;
use App\Http\Dao\OrderDao;
use App\Http\Manager\SdkManager;
use App\Utils\Rsa;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use RuntimeException;
class PayService
{
private $orderDao;
public function __construct()
{
$this->orderDao = new OrderDao();
}
/**
* 创建订单,返回订单号
* @param array $params
* @return array
*/
public function createOrder(array $params): array
{
$model = DB::table("app_order");
// 查询cp订单号是否有重复情况
$orderInfo = $model->where(['cp_order_id' => $params['cp_order_id'], 'appid' => $params['app_id']])->first();
if ($orderInfo) {
return error("禁止重复下单");
}
// 检查参数
if (!is_numeric($params['money']) || $params['money'] < 1) {
return error("订单金额的格式类型不正确");
}
if (empty($params['app_id']) || empty($params['ctype']) || empty($params['money']) || empty($params['uid'])) {
return error("提交参数异常!");
}
// 查找融合用户信息
$userInfo = DB::table('app_member')->where(['uid' => $params['uid']])->first();
// 入库
$orderId = $this->createOrderId();
$insertData = [
'uid' => $params['uid'],
'order_id' => $orderId,
'cp_order_id' => $params['cp_order_id'],
'veruniqid' => $userInfo->veruniqid,
'ver' => $params['ctype'],
'appid' => $params['app_id'],
'server_id' => $params['server_id'],
'server_name' => $params['server_name'],
'role_id' => $params['role_id'],
'money' => $params['money'],
'role_name' => htmlspecialchars($params['role_name']),
'role_level' => $params['role_level'],
'subject' => $params['pname'],
'extra_info' => $params['extend'] ?? '',
'currency_type' => $params['currency_type'] ?? 'CNY',
'create_time' => date('Y-m-d H:i:s')
];
$model->insert($insertData);
return success('success',['order_id' => $orderId]);
}
/**
* 生成订单号
* @return int
*/
private function createOrderId(): string
{
$datestr = date('YmdHis');
list($usec, $sec) = explode(" ", microtime());
$ustr = (float)$usec*1000000;
$ustr = (string)$ustr;
$datestr .= $ustr;
$pfix = env('APIORDER_FIX','');
return $pfix.$datestr;
}
/**
* 二次确认订单,通过则返回订单状态
* @param array $params
* @return array
*/
public function confirmOrder(array $params)
{
$orderInfo = DB::table('app_order')->where(['order_id' => $params['order_id'], 'status' => 0])->first();
if (is_null($orderInfo)) {
return error('订单状态异常,请重新下单!');
}
// 参数校验
if ($orderInfo->money != $params['money'] || $orderInfo->uid != $params['uid']) {
return error('订单金额异常!');
}
return success('success',['order_id' => $orderInfo->order_id,'status'=>$orderInfo->status]);
}
/**
* 渠道回调,带 appid + 渠道号 参数
* @param array $params
* @return array
*/
public function verBack(array $params)
{
//获取游戏表配置
$gameInfo = DB::table("app_games_config")
->where(['app_id' => $params['app_id']])->first();
if (is_null($gameInfo)) {
return error('该游戏配置不存在,app_id:' . $params['app_id']);
}
// 获取渠道表配置
$verInfo = DB::table("app_ver_game as avg")
->leftJoin('app_ver as av', 'avg.ver', '=', 'av.ver_class')
->where(['app_id' => $params['app_id'], 'ver_code' => $params['ver']])->first();
if (is_null($verInfo)) {
return error('该游戏渠道没配置,ver_code:' . $params['ver']);
}
// 渠道标识就是类名称
$sdkManager = new SdkManager();
// 返回渠道订单号+订单金额[单位元]
$payInfo = $sdkManager->pay($verInfo, $gameInfo, $params);
if (!isset($params['order_id']) && !isset($params['money'])) {
return $payInfo['result'];
}
// 更新回调时间+金额
DB::table('app_order')->where(['order_id' => $payInfo['order_id']])->update(['status' => 1, 'amount'=>$payInfo['money'],'dateline' => time()]);
// 保存回调日志
DB::table('app_callback_log')->insert([
'order_id' => $payInfo['order_id'],
'requrl' => request()->fullUrl(),
'reqparams' => var_export(request()->post(),true),
'reqresult' => var_export($payInfo,true),
'reqtime' => time(),
]);
// 通知CP发货,redis队列,后台发货, 订单号|appid|渠道号
$list = "{$payInfo['order_id']}|{$params['app_id']}|{$params['ver']}";
Redis::lpush('send_order_list', $list);
// 返回渠道要求返回的提示 成功|失败
return $payInfo['result'];
}
}
<?php
namespace App\Http\Service;
use RuntimeException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class RoleService
{
/**
* 存储角色上报数据
*
* @param array $params
*/
public function storeRoleData(array $params)
{
// 判断用户是否存在
$userInfo = DB::table('app_member')->where(['uid' => $params['uid']])->first();
if (is_null($userInfo)) {
return error('uid不存在!');
}
// 上报入库
$logData = [
'app_id' => $params['app_id'],
'uid' => $params['uid'],
'ctype' => $params['ctype'] ?? 0,
'role_id' => $params['role_id'] ?? 0,
'role_name' => $params['role_name'] ?? '',
'vip_level' => $params['vip_level'] ?? 0,
'server_id' => $params['server_id'] ?? 0,
'server_name' => $params['server_name'] ?? '',
'reported_type' => $params['reported_type'] ?? 1,
'role_level' => $params['roleLevel'] ?? 0,
'online_length' => $params['onlineLength'] ?? 0,
'money_num' => $params['moneyNum'] ?? 0,
'created_at' => date('Y-m-d H:i:s'),
];
DB::table('app_game_rolelog')->insert($logData);
return success('上报成功');
}
}
<?php
use \Illuminate\Support\Facades;
/**
* @dsec 返回成功的json数组
* @param string $msg
* @return mixed
*/
function success($msg = 'success', $data = [])
{
return [
'message' => $msg,
'data' => $data,
'statusCode' => 200,
];
}
/**
* @dsec 返回成功的json数组
* @param string $msg
* @return mixed
*/
function error($msg = 'error', $data = [])
{
return [
'message' => $msg,
'data' => $data,
'statusCode' => 300,
];
}
/**
* @dsec 返回成功的json数组
* @param string $msg
* @return mixed
*/
function json($data = [])
{
return response()->json($data);
}
/**
* 钉钉打印日志
* @param $message
* @return array|bool|string
*/
function dingdingLog($message)
{
if (is_array($message)) {
$message = "该参数是数组:" . var_export($message, true);
}
$data = array('msgtype' => 'text', 'text' => array('content' => '[ ' . date("Y-m-d H:i:s") . ' ] - 日志:' . $message));
$post_string = json_encode($data);
$ch = curl_init();
$access_token = 'b74a7e686873baaed443c4d4bf6c68e3f58debc79324c4d3ea14549dc43586f2';
curl_setopt($ch, CURLOPT_URL, 'https://oapi.dingtalk.com/robot/send?access_token=' . $access_token);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function p($obj)
{
if (is_string($obj)) {
echo $obj;
} else if (is_array($obj)) {
echo '<pre>';
var_export($obj);
} else {
var_dump($obj);
}
exit();
}
/**
* 获取最后一条sql语句 待测试
* @param string $connection
* @return mixed
*/
function get_sql($connection = 'mysql')
{
//\DB::connection($connection)->enableQueryLog(); // 开启查询日志
$sql = Facades\DB::connection($connection)->getQueryLog();
$query = end($sql);
$tmp = str_replace('?', '"'.'%s'.'"', $query['query']);
$tmp = vsprintf($tmp, $query['bindings']);
$tmp = str_replace("\\","",$tmp);
$query['sql'] = $tmp;
return $query;
}
<?php
namespace App\Jobs;
class ExampleJob extends Job
{
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
abstract class Job implements ShouldQueue
{
/*
|--------------------------------------------------------------------------
| Queueable Jobs
|--------------------------------------------------------------------------
|
| This job base class provides a central location to place any logic that
| is shared across all of your jobs. The trait included with the class
| provides access to the "queueOn" and "delay" queue helper methods.
|
*/
use InteractsWithQueue, Queueable, SerializesModels;
}
<?php
namespace App\Listeners;
use App\Events\ExampleEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class ExampleListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param \App\Events\ExampleEvent $event
* @return void
*/
public function handle(ExampleEvent $event)
{
//
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ChannelConfig extends Model
{
protected $table = 'app_channel_config';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ChannelMaster extends Model
{
protected $table = 'channel_master';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DeviceRegister extends Model
{
protected $table = 'device_register';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Game extends Model
{
protected $table = 'game';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class GameConfig extends Model
{
protected $table = 'app_game_config';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class GameRole extends Model
{
protected $table = 'game_role';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class GameRoleLog extends Model
{
protected $table = 'game_role_log';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class GameUser extends Model
{
protected $table = 'game_user';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class LoginLog extends Model
{
protected $table = 'log_login';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Member extends Model
{
protected $table = 'app_member';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $table = 'order';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class RegisterLog extends Model
{
protected $table = 'register_log';
//关闭created_at和updated_at的自动更新。
public $timestamps = false;
protected $guarded = [];
}
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
<?php
namespace App\Providers;
use App\User;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Boot the authentication services for the application.
*
* @return void
*/
public function boot()
{
// Here you may define how you wish users to be authenticated for your Lumen
// application. The callback which receives the incoming request instance
// should return either a User instance or null. You're free to obtain
// the User instance via an API token or any other method necessary.
$this->app['auth']->viaRequest('api', function ($request) {
if ($request->input('api_token')) {
return User::where('api_token', $request->input('api_token'))->first();
}
});
}
}
<?php
namespace App\Providers;
use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
\App\Events\ExampleEvent::class => [
\App\Listeners\ExampleListener::class,
],
];
}
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Model;
use Laravel\Lumen\Auth\Authorizable;
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email',
];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'password',
];
}
<?php
namespace App\Utils;
use Illuminate\Http\Request;
class CommonFunc
{
/**
* 生成Token
*/
public static function generateToken(int $userId, int $channelId, int $appId): string
{
$str = $userId . $channelId . $appId . time() . rand(1000000, 9999999);
return md5($str);
}
/**
* 获取客户端ip地址
*
* @return string|null
*/
public static function getTrustedProxiesIp(){
\request()->setTrustedProxies(\request()->getClientIps(),Request::HEADER_X_FORWARDED_FOR);
return \request()->getClientIp();
}
}
<?php
namespace App\Utils;
class Enum
{
// 数据库dateTime类型默认存储时间
const DEFAULT_DATE_TIME = '1970-01-01 00:00:00';
// 数据库date类型默认存储时间
const DEFAULT_DATE = '1970-01-01';
//重置后的默认密码
const DEFAULT_PASSWORD = 'jz123456';
}
<?php
namespace App\Utils;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
use RuntimeException;
class HttpRequestTool
{
/** @var Client */
private $client;
public function __construct($baseUri = '', $timeOut = 60)
{
$config = ['base_uri' => $baseUri, 'timeout' => $timeOut];
$this->client = new Client($config);
}
/**
* 通过发送json数据的方式进行请求
*
* @param $method string GET/POST/PUT...
* @param $uri string 可以是完整的请求地址。也可以是基于base_uri参数后的补充链接
* @param $data array 请求的数据内容
* @return array
*/
public function requestByJson($method, $uri, $data)
{
try {
$response = $this->client->request($method, $uri, ['json' => $data]);
return json_decode($response->getBody()->getContents(), true);
} catch (GuzzleException $e) {
$msg = __FUNCTION__ . '请求异常:';
Log::info($msg . $e->getMessage());
throw new RuntimeException($e->getMessage());
}
}
/**
* 通过表单的方式进行请求
*
* @param $method
* @param $uri
* @param $data
* @return array|mixed|\stdClass
*/
public function requestByFormParams($method, $uri, $data)
{
try {
$response = $this->client->request($method, $uri, ['form_params' => $data]);
return json_decode($response->getBody()->getContents(), true);
} catch (GuzzleException $e) {
$msg = __FUNCTION__ . '请求异常:';
Log::info($msg . $e->getMessage());
throw new RuntimeException($e->getMessage());
}
}
/**
* GET方式进行请求
*
* @param $uri
* @param array $headers
* @return array
*/
public function requestGet($uri, $headers = [])
{
try {
if ($headers) {
$response = $this->client->request('GET', $uri, ['headers' => $headers]);
} else {
$response = $this->client->request('GET', $uri);
}
return json_decode($response->getBody()->getContents(), true);
} catch (GuzzleException $e) {
$msg = __FUNCTION__ . '请求异常:';
Log::info($msg . $e->getMessage());
throw new RuntimeException($e->getMessage());
}
}
}
<?php
namespace App\Utils;
class Response
{
const OK = 0;
const PARAM_ERROR = 40010;
const BAD_REQUEST = 50000;
const SERVER_ERROR = 50010;
const SQL_ERROR = 50020;
const FORBIDDEN = 50030;
public static $errMsg = [
self::OK => 'success',
self::BAD_REQUEST => '请求错误',
self::PARAM_ERROR => '参数错误',
self::SQL_ERROR => '数据库执行错误',
self::SERVER_ERROR => 'Error',
];
public static function response(array $params = [])
{
$data = $params['data'] ?? [];
if (env('APP_DEBUG') && array_key_exists('e', $params) && $params['e'] instanceof \Exception) {
$code = $params['e']->getCode();
$msg = $params['e']->getMessage();
} else {
$code = $params['code'] ?? 0;
$msg = $params['msg'] ?? (array_key_exists($code, self::$errMsg) ? self::$errMsg[$code] : '未知错误');
}
return response(['code' => $code, 'msg' => $msg, 'data' => $data]);
}
}
<?php
namespace App\Utils;
use App\Models\Game;
/**
* Rsa密钥处理类
*
* Class Rsa
* @package App\Utils
*/
class Rsa
{
private $_config = [
'public_key' => '',
'private_key' => '',
];
// public function __construct($private_key_filepath, $public_key_filepath)
// {
// $this->_config['private_key'] = $this->_getContents($private_key_filepath);
// $this->_config['public_key'] = $this->_getContents($public_key_filepath);
// }
public function __construct($appId)
{
[$this->_config['public_key'], $this->_config['private_key']] = $this->_getKeyData($appId);
}
/**
* 获取密钥文件内容
*
* @param $file_path
* @return false|string|void
*/
private function _getKeyContents($file_path)
{
file_exists($file_path) or die ('密钥或公钥的文件路径错误');
return file_get_contents($file_path);
}
/**
* 获取密钥数据
*
* @param $appId
* @return array
*/
private function _getKeyData($appId): array
{
$gameObj = Game::select('id', 'app_rsa_pub_key', 'app_rsa_pri_key')
->where('id', $appId)
->first();
if (!$gameObj) {
throw new \RuntimeException('获取游戏信息失败!');
}
return [$gameObj->app_rsa_pub_key, $gameObj->app_rsa_pri_key];
}
/**
* 获取私钥
*
* @return resource
*/
private function _getPrivateKey()
{
$privateKey = $this->_config['private_key'];
$resource = openssl_pkey_get_private($privateKey);
if (!$resource) {
throw new \RuntimeException('私钥不可用!');
}
return $resource;
}
/**
* 获取公钥
*
* @return resource
*/
private function _getPublicKey()
{
$publicKey = $this->_config['public_key'];
$resource = openssl_pkey_get_public($publicKey);
if (!$resource) {
throw new \RuntimeException('公钥不可用!');
}
return $resource;
}
/**
* 公钥加密
*
* @param string $data
* @return string
*/
public function publicEncrypt(string $data = ''): string
{
$splitArr = str_split($data, 117);
$encrypted = '';
foreach ($splitArr as $item) {
$bool = openssl_public_encrypt($item, $encryptedData, $this->_getPublicKey());
if (!$bool) {
throw new \RuntimeException('公钥加密失败!');
}
//每次加密后的字符长度为128
$encrypted .= $encryptedData;
}
return base64_encode($encrypted);
}
/**
* 私钥加密
*
* @param string $data
* @return string
*/
public function privateEncrypt(string $data = ''): string
{
$splitArr = str_split($data, 117);
$encryptedStr = '';
foreach ($splitArr as $item) {
$bool = openssl_private_encrypt($item, $encryptedData, $this->_getPrivateKey());
if (!$bool) {
throw new \RuntimeException('私钥加密失败!');
}
//每次加密后的字符长度为128
$encryptedStr .= $encryptedData;
}
return base64_encode($encryptedStr);
}
/**
* 公钥解密
*
* @param string $data
* @return string
*/
public function publicDecrypt(string $data = ''): string
{
//密钥每次加密后的长度是128,所以base64_decode后分割长度为128
$split = str_split(base64_decode($data), 128);
$crypto = '';
foreach ($split as $chunk) {
$bool = openssl_public_decrypt($chunk, $decryptData, $this->_getPublicKey());
if (!$bool) {
throw new \RuntimeException('公钥解密失败!');
}
$crypto .= $decryptData;
}
return $crypto;
}
/**
* 私钥解密
*
* @param string $data
* @return string
*/
public function privateDecrypt(string $data = ''): string
{
//密钥每次加密后的长度是128,所以base64_decode后分割长度为128
$split = str_split(base64_decode($data), 128);
$crypto = '';
foreach ($split as $chunk) {
$bool = openssl_private_decrypt($chunk, $decryptData, $this->_getPrivateKey());
if (!$bool) {
throw new \RuntimeException('私钥解密失败!');
}
$crypto .= $decryptData;
}
return $crypto;
}
}
#!/usr/bin/env php
<?php
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| First we need to get an application instance. This creates an instance
| of the application / container and bootstraps the application so it
| is ready to receive HTTP / Console requests from the environment.
|
*/
$app = require __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(
'Illuminate\Contracts\Console\Kernel'
);
exit($kernel->handle(new ArgvInput, new ConsoleOutput));
<?php
require_once __DIR__.'/../vendor/autoload.php';
(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
dirname(__DIR__)
))->bootstrap();
date_default_timezone_set(env('APP_TIMEZONE', 'UTC'));
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| Here we will load the environment and create the application instance
| that serves as the central piece of this framework. We'll use this
| application as an "IoC" container and router for this framework.
|
*/
$app = new Laravel\Lumen\Application(
dirname(__DIR__)
);
// 新增
$app->register(Illuminate\Redis\RedisServiceProvider::class);
$app->withFacades();
$app->withEloquent();
/*
|--------------------------------------------------------------------------
| Register Container Bindings
|--------------------------------------------------------------------------
|
| Now we will register a few bindings in the service container. We will
| register the exception handler and the console kernel. You may add
| your own bindings here if you like or you can make another file.
|
*/
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
/*
|--------------------------------------------------------------------------
| Register Config Files
|--------------------------------------------------------------------------
|
| Now we will register the "app" configuration file. If the file exists in
| your configuration directory it will be loaded; otherwise, we'll load
| the default version. You may register other files below as needed.
|
*/
$app->configure('app');
/*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/
// $app->middleware([
// App\Http\Middleware\ExampleMiddleware::class
// ]);
// $app->routeMiddleware([
// 'auth' => App\Http\Middleware\Authenticate::class,
// ]);
/*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/
// $app->register(App\Providers\AppServiceProvider::class);
// $app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
/*
|--------------------------------------------------------------------------
| Load The Application Routes
|--------------------------------------------------------------------------
|
| Next we will include the routes file so that they can all be added to
| the application. This will provide all of the URLs the application
| can respond to, as well as the controllers that may handle them.
|
*/
$app->router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) {
require __DIR__.'/../routes/web.php';
});
return $app;
{
"name": "laravel/lumen",
"description": "The Laravel Lumen Framework.",
"keywords": ["framework", "laravel", "lumen"],
"license": "MIT",
"type": "project",
"require": {
"php": "^7.2.5",
"guzzlehttp/guzzle": "^7.5",
"illuminate/redis": "~7.0",
"laravel/lumen-framework": "^7.0",
"predis/predis": "^2.1",
"rmccue/requests": "^2.0"
},
"require-dev": {
"fzaninotto/faker": "^1.9.1",
"mockery/mockery": "^1.3.1",
"phpunit/phpunit": "^8.5"
},
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
},
"files": [
"app/Http/helper.php"
]
},
"autoload-dev": {
"classmap": [
"tests/"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
]
}
}
This diff is collapsed.
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\User;
use Faker\Generator as Faker;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->email,
];
});
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// $this->call('UsersTableSeeder');
}
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Application Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
</php>
</phpunit>
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| First we need to get an application instance. This creates an instance
| of the application / container and bootstraps the application so it
| is ready to receive HTTP / Console requests from the environment.
|
*/
$app = require __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$app->run();
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/
/** @var \Laravel\Lumen\Concerns\RoutesRequests $router */
$router->get('/', function () use ($router) {
return $router->app->version();
});
//测试
$router->get('/example/test','ExampleController@test');
$router->post('/example/test','ExampleController@test');
// 上报相关
$router->group(['prefix' => 'report'],function () use ($router){
// 设备初始化
$router->post('init','ReportController@init');
// 角色上报
$router->post('role','ReportController@role');
});
// 登录相关
$router->group(['prefix' => 'login'],function () use ($router){
// 创建token
$router->post('createToken','LoginController@createToken');
// 检查token
$router->post('checkToken','LoginController@checkToken');
});
//支付相关
$router->group(['prefix' => 'pay'],function () use ($router){
// 创建订单
$router->post('createOrder','PayController@createOrder');
// 确认订单
$router->post('confirmOrder','PayController@confirmOrder');
// 渠道支付回调
$router->post('verBack','PayController@verBack');
});
<?php
use Laravel\Lumen\Testing\DatabaseMigrations;
use Laravel\Lumen\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testExample()
{
$this->get('/');
$this->assertEquals(
$this->app->version(), $this->response->getContent()
);
}
}
<?php
use Laravel\Lumen\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
/**
* Creates the application.
*
* @return \Laravel\Lumen\Application
*/
public function createApplication()
{
return require __DIR__.'/../bootstrap/app.php';
}
}
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 to comment