= 在项目public/.htaccess里面添加以下内容
<IfModule mod_headers.c>
# 设置允许跨域请求的头部信息
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "*"
Header set Access-Control-Allow-Credentials "true"
</IfModule>
在Apache配置文件尾部添加以下代码
Listen 127.0.0.1:8081
<VirtualHost *:8081>
ServerName www.niunai.com
DocumentRoot D:/phpstudy_pro/WWW/niunai/public
# 设置允许跨域请求的头部信息
<IfModule headers_module>
# 设置响应头中的允许的跨域请求来源
Header set Access-Control-Allow-Origin "*"
# 设置允许的请求方法
Header set Access-Control-Allow-Methods "GET,POST,OPTIONS"
# 设置允许的请求头,包括 token
Header set Access-Control-Allow-Headers "*"
# 设置是否允许发送凭据(如 Cookie)
Header set Access-Control-Allow-Credentials "true"
</IfModule>
# 其他 Apache 配置项...
</VirtualHost>
设置全局账户 --global表示全局
git config --global user.name ""
git config --global user.email ""
git config --global credential.helper store
git clone 链接地址
比如:git clone https://codeup.aliyun.com/test_jiaoxue.git
git add . //提交所有文件
git add app/test.php 提交指定文件写发
git add app/dir 提交app下面的dir整个文件夹
git commit -m "我是描述文字"
将本地代码推送到云端
git push
composer self-update
composer clearcache
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
composer create-project l
aravel/laravel=7.* demo --prefer-dist
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql//数据库类型
DB_HOST=127.0.0.1//数据库地址
DB_PORT=3306//数据库端口号
DB_DATABASE=laravel_demo//数据库database名称
DB_USERNAME=root//数据库登录账户
DB_PASSWORD=root//数据库登录密码
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
routes //路由文件夹admin和api基本模块
app\Providers\RouteServiceProvider.php //新增路由文件方法
app\Http\Middleware\AdminToken.php //添加一个路由就添加一个(中间键)方便对每个路由的控制
app\Http\Middleware\Page.php //在添加一个额外的分页(中间键) 方便分页使用
app\Http\Kernel.php //内核文件
<?php
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
Route::prefix('v1')
->namespace('Admin\v1')
->name('admin.v1.')
->group(function () {
//--测试
Route::middleware('throttle:' . config('admin.rate_limits.access'))
->group(function (Router $router) {
$router->get('test', 'TestController@test')->name('admin.test');
});
//--后台管理
Route::middleware('throttle:' . config('admin.rate_limits.access'))
->group(function (Router $router) {
//--用户管理
$router->get('user/index', 'UserController@index')->name('admin.user.index');//用户列表接口
$router->post('user/create', 'UserController@create')->name('admin.user.create');//创建用户接口
$router->post('user/update', 'UserController@update')->name('admin.user.update');//修改用户接口
//addController
});
});
Route::prefix('v2')
->namespace('Admin\v2')
->name('admin.v2.')
->group(function () {
//--测试
Route::middleware('throttle:' . config('admin.rate_limits.access'))
->group(function (Router $router) {
$router->get('test', 'TestController@test')->name('admin.test');
});
//--后台管理
Route::middleware('throttle:' . config('admin.rate_limits.access'))
->group(function (Router $router) {
//addController
});
});
如果添加了一个(admin路由模块),就必须在这里面创建一个mapAdminRoutes()方法
如果添加了一个(wx路由模块),同样的在这里面创建一个mapWxRoutes()方法
创建好后在 map方法中使用
方法内容:
public function map()
{
//在这里使用自定义的路由模块
$this->mapWxRoutes();
$this->mapAdminRoutes();
//
}
protected function mapAdminRoutes()
{
Route::prefix('wx')
->middleware('wx')
->namespace($this->namespace)
->group(base_path('routes/wx.php'));
}
protected function mapWxRoutes()
{
Route::prefix('admin')
->middleware('admin')
->namespace($this->namespace)
->group(base_path('routes/admin.php'));
}
文件内容:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
class AdminToken
{
protected $except = [
'admin/v1/test',
];
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// if ($this->shouldPassThrough($request)) {
// return $next($request);
//}
//if (!$request->header('token')) {
// error(errorCode()::REQUIRED_TOKEN, __('api.required_login'));
//}
//$viif = jwtDeCode($request->header('token'), 'app.a_key');
//if (!$viif) {
// error(errorCode()::REQUIRED_TOKEN, __('api.login_time'));
//} else {
//$res['id']=$viif['id'];
//$res['iat'] = time();
//$res['exp'] = getTimeAdd(config('app.jwt_time'));
//$token = jwtEnCode($res, 'app.a_key');
//$request->offsetSet('key_uid', $viif['id']);
//session(['token' => $token]);
//}
return $next($request);
}
/**
* @param Request $request
* @return bool
*/
protected function shouldPassThrough(Request $request): bool
{
return collect($this->except)
->contains(function ($except) use ($request) {
if ($except !== '/') {
$except = trim($except, '/');
}
return $request->is($except);
});
}
}
文件内容
<?php
namespace App\Http\Middleware;
use Closure;
class Page
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$page = intval($request->input('page', 1));
$limit = intval($request->input('limit', 20));
$page < 1 && $page = 1;
($limit < 1 || $limit > 200) && $limit = 20;
$request->offsetSet('offset', ($page - 1) * $limit);
$request->offsetSet('limit', $limit);
$request->offsetSet('page', $page);
return $next($request);
}
}
文件内容:
在$middlewareGroups数组中添加一条admin模块
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
//下面是新增的一条
'admin' => [
'AdminToken',
'Page',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
在$routeMiddleware数组中添加上面创建的AdminToken和Page模块
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
//下面的是新增的
'Page' => \App\Http\Middleware\Page::class,
'AdminToken' => \App\Http\Middleware\AdminToken::class,
];
有多少个路由就添加多少个这种文件配置
内容:
<?php
return [
/*
* 接口频率限制
*/
'rate_limits' => [
// 访问频率限制,次数/分钟
'access' => env('RATE_LIMITS', '100'),
// 登录相关,次数/分钟
'sign' => env('SIGN_RATE_LIMITS', '100'),
'device' => env('DEVICE_RATE_LIMITS', '100'),
],
];
目前有以下文件需要自己创建
app\MyClass //自定义类存储地方
app\Support //自定义函数存储地方
app\Exceptions //自定义错误全局常量状态码文件存储地方
app\Logic //自定义逻辑层存储地方
app\Models //自定义model层文件存储地方
resources\lang //多语言文件配置存储地方
app\MyClass\Jwt.php //自定义jwt加密类
app\Support\Helper.php //自定义全局函数方法文件
app\Support\GetValueAttribute.php //自定义全局字段修饰符函数方法文件
app\Exceptions\ErrCode.php //自定义错误全局常量状态码类文件
resources\lang\zh\api.php //自定义中文全局错误语言提示
在autoload.files中添加以下内容
上面的文件都添加好的情况下
在项目根目录下,通过终端执行一下命令 composer dump-autoload
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
],
"files": [
//这是新添加的内容只添加这部分就可以了
"app/Support/Helper.php",
"app/Support/GetValueAttribute.php"
]
},
文件位置:app\MyClass\Jwt.php
<?php
/**
* PHP实现jwt
*/
namespace App\MyClass;
class Jwt
{
private static $key;
public function __construct($key = 'xygmilk!20210605')
{
self::$key = $key;
}
//头部
private static $header = array(
'alg' => 'HS256', //生成signature的算法
'typ' => 'JWT' //类型
);
//使用HMAC生成信息摘要时所使用的密钥
/**
* 获取jwt token
* @param array $payload jwt载荷 格式如下非必须
* [
* 'iss'=>'jwt_admin', //该JWT的签发者
* 'iat'=>time(), //签发时间
* 'exp'=>time()+7200, //过期时间
* 'nbf'=>time()+60, //该时间之前不接收处理该Token
* 'sub'=>'www.admin.com', //面向的用户
* 'jti'=>md5(uniqid('JWT').time()) //该Token唯一标识
* ]
* @return bool|string
*/
public static function getToken($payload)
{
if (is_array($payload)) {
$base64header = self::base64UrlEncode(json_encode(self::$header, JSON_UNESCAPED_UNICODE));
$base64payload = self::base64UrlEncode(json_encode($payload, JSON_UNESCAPED_UNICODE));
$token = $base64header . '.' . $base64payload . '.' . self::signature($base64header . '.' . $base64payload, self::$key, self::$header['alg']);
return $token;
} else {
return false;
}
}
/**
* 验证token是否有效,默认验证exp,nbf,iat时间
* @param string $Token 需要验证的token
* @return bool|string
*/
public static function verifyToken($Token)
{
$tokens = explode('.', $Token);
if (count($tokens) != 3)
return false;
list($base64header, $base64payload, $sign) = $tokens;
//获取jwt算法
$base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);
if (empty($base64decodeheader['alg']))
return false;
//签名验证
if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)
return false;
$payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);
//签发时间大于当前服务器时间验证失败
if (isset($payload['iat']) && $payload['iat'] > time())
return false;
//过期时间小宇当前服务器时间验证失败
if (isset($payload['exp']) && $payload['exp'] < time())
return false;
//该nbf时间之前不接收处理该Token
if (isset($payload['nbf']) && $payload['nbf'] > time())
return false;
return $payload;
}
/**
* base64UrlEncode https://jwt.io/ 中base64UrlEncode编码实现
* @param string $input 需要编码的字符串
* @return string
*/
private static function base64UrlEncode($input)
{
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}
/**
* base64UrlEncode https://jwt.io/ 中base64UrlEncode解码实现
* @param string $input 需要解码的字符串
* @return bool|string
*/
private static function base64UrlDecode($input)
{
$remainder = strlen($input) % 4;
if ($remainder) {
$addlen = 4 - $remainder;
$input .= str_repeat('=', $addlen);
}
return base64_decode(strtr($input, '-_', '+/'));
}
/**
* HMACSHA256签名 https://jwt.io/ 中HMACSHA256签名实现
* @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload)
* @param string $key
* @param string $alg 算法方式
* @return mixed
*/
private static function signature($input, $key, $alg = 'HS256')
{
$alg_config = array(
'HS256' => 'sha256',
);
return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key, true));
}
}
文件位置:app\Support\GetValueAttribute.php
<?php
/**
* 返回是否结果
*/
function getBaseIfAttribute($key = 0)
{
$arr = array('否', '是');
if (isset($arr[$key])) {
return $arr[$key];
} else {
return $arr[0];
}
}
文件位置:app\Support\Helper.php
<?php
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use App\Exceptions\ErrCode;
use App\MyClass\Jwt;
use App\Models;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\File;
/**
* 响应错误
* @param int $status 状态码
* @param string $message 错误消息
* @param array $attache 附加消息
*/
function error(int $status = 1001, string $message = 'error', array $attache = [])
{
header("Content-type:application/json;charset=utf-8");
$res = json_encode(array('status' => $status, 'message' => $message, 'data' => (object)[], 'attache' => $attache, 'token' => session('token', '')), JSON_UNESCAPED_UNICODE);
exit($res);
}
/**
* 正常响应接口
* @param array $data 接口返回数据
* @param string $message 消息
* @param array $attache 附加数据
*/
function success($data = [], string $message = 'ok', array $attache = [])
{
header("Content-type:application/json;charset=utf-8");
$res = json_encode(array('status' => 0, 'message' => $message, 'data' => $data, 'attache' => $attache, 'token' => session('token', '')), JSON_UNESCAPED_UNICODE);
exit($res);
}
//错误码
function errorCode()
{
$error = new ErrCode();
return $error;
}
//在已有的表中添加字段
function setTableForm($table_name, $data, $up = false)
{
if (count($data) > 0) {
foreach ($data as $k => $v) {
if ($up == true && Schema::hasColumn($table_name, $k)) {
if ($v['type'] == 'integer') {
Schema::table($table_name, function (Blueprint $table) use ($k, $v) {
$table->integer($k)->default($v['default'])->change();
});
} elseif ($v['type'] == 'char') {
Schema::table($table_name, function (Blueprint $table) use ($k, $v) {
$table->string($k, $v['leng'])->fixed(true)->default($v['default'])->change();
});
} else {
Schema::table($table_name, function (Blueprint $table) use ($k, $v) {
$type = $v['type'];
$table->$type($k, $v['leng'])->default($v['default'])->change();
});
}
}
if (!Schema::hasColumn($table_name, $k)) {
if ($v['type'] == 'integer') {
Schema::table($table_name, function (Blueprint $table) use ($k, $v) {
$table->integer($k)->default($v['default'])->comment($v['comment']);
});
} else {
Schema::table($table_name, function (Blueprint $table) use ($k, $v) {
$type = $v['type'];
$table->$type($k, $v['leng'])->default($v['default'])->comment($v['comment']);
});
}
}
}
}
}
文件位置:app\Exceptions\ErrCode.php
<?php
namespace App\Exceptions;
use Exception;
class ErrCode extends Exception
{
//
public const ERROR_LOGIN = 1002; //登录失败
public const REQUIRED_TOKEN = 1003; //token验证失败
public const DATA_YES = 1011;
public const SIGN_RES = 1010; //标识重复
public const ALREADY_EXISTS_NO = 1019;
public const Register = 1020; //已注册
public const password_no = 1021; //密码错误
public const telephone_no = 1022; //帐号信息不存在
public const USER_INFO_NO = 1023; //用户信息不存在
public const is_card = 1024; //身份证号码验证错误
public const UPDATED_NO = 1025; //更新失败
public const pay_catch = 1028; //支付异常
public const PAY_ERROR = 1029; //支付失败
public const GET_WX_ACCESS_TOKEN_NO = 1030; //获取微信access_token失败
public const FILE_SELECT = 1032; //请选择文件
public const FILE_UP = 1033; //上传方式有误
public const pwd_discord = 1034; //密码不一致
public const get_note_err = 1035; //获取失败
public const img_strlen = 1043; //图片上传有误
public const img_size_err = 1044; //图片上传大小不得超过5MB
public const file_size_err = 1045; //文件上传大小不得超过20MB
public const DELETE_NO = 1053; //删除失败
public const CREATE_NO = 1054; //创建失败
public const ERROR_CATCH = 1055; //处理异常
public const is_exists = 1056; //查询信息不存在
public const ALREADY_EXISTS = 1057; //没有权限
public const ERROR = 1059; //未知错误
public const img_is_array = 1062; //图片格式有误
public const file_name_not = 1061; //文件上传格式有误
public const weihu = 1063; //维护中
public const get_ticket_no = 1064;//获取ticket失败
public const user_name_state_no = 1065;//账号已禁用
}
文件位置:resources\lang\zh\api.php
<?php
return [
'data_yes' => '已存在使用禁止删除',
'repetition_sign' => '标识已存在不能重复使用',
'required_login' => 'token令牌验证失败',
'login_time' => '登录超时请重新登录',
'error_login' => '登录超时请重新登录',
'Register' => '已注册',
'password_no' => '密码错误',
'telephone_no' => '帐号信息不存在',
'user_info_no' => '用户信息不存在',
'is_card' => '身份证号码验证错误',
'updated_no' => '更新失败',
'age_min' => '兄弟毛长齐了在来',
'age_min_err' => '年龄不得低于18岁',
'age_max' => '大叔留点给我们,年龄超出',
'pay_catch' => '支付异常',
'get_wx_access_token_no' => '获取微信access_token失败',
'extract_error' => '抽取失败',
'select_file' => '请选择文件',
'uploading_file' => '上传方式有误',
'pay_error' => '支付失败',
'pwd_discord' => '密码不一致',
'get_note_err' => '获取失败',
'get_user_note_err' => '获取字条信息失败',
'yh_join' => '人员已满',
'yh_join_male' => '只限男性加入',
'yh_join_girl' => '只限女性加入',
'age_join_begin' => '加入年龄要求大于:',
'age_join_end' => '加入年龄要求小于:',
'yh_join_time' => '约会已结束',
'get_info_err' => '查询的信息已不存在',
'send_load' => '评论失败',
'img_strlen' => '文件上传有误',
'img_size_err' => '图片上传大小不得超过5MB',
'file_size_err' => '文件上传大小不得超过20MB',
'appintment_catch' => '参与人员状态更新异常',
'appintment_err' => '参与人员状态更新失败',
'yy_refund' => '参与人员拒绝操作失败',
'key_no' => '密码错误',
'send_report' => '已提交过举报',
'report_no' => '举报失败',
'price_no' => '超出可提现金额',
'wx_qr_no' => '获取二维码图片失败',
'delete_no' => '删除失败',
'create_no' => '创建失败',
'catch' => '处理异常',
'is_exists' => '查询信息不存在',
'verify_permissions' => '没有权限',
'Unregister' => '请先去小程序注册',
'error' => '未知错误',
'get_phone' => '获取手机号失败',
'get_qr_no' => '微信支付调用失败',
'img_is_array' => '图片格式有误',
'ver_begin_time' => '龟儿不按时间分配掌嘴',
'not_user' => '没有找到客户信息',
'user_is_yes'=>'已存在分配无须重复分配',
'xy_day_time'=>'分配时间不能小于当前时间',
'not_day_user'=>'没有可分配的日期',
'file_name_not'=>'文件上传格式有误',
'date_time_is'=>'此日期已有收集记录',
'cancel_success_no'=>'只能取消待配送的订单',
'get_ticket_no'=>'获取ticket失败',
'up_auc_info'=>'地址更新失败',
'create_order'=>'创建订单失败',
'weihu'=>'系统升级中...',
'user_name_state_no'=>'账号已禁用'
];