Commit a1a1a7a9 authored by hangjun83's avatar hangjun83

openapi 震坤行

parent 5ba70637
...@@ -11,8 +11,11 @@ ...@@ -11,8 +11,11 @@
namespace App\Http\Controllers\Middleware; namespace App\Http\Controllers\Middleware;
use App\Repositories\Contracts\ThirdApiPlatformRepository;
use App\Repositories\Enums\ResponseCodeEnum; use App\Repositories\Enums\ResponseCodeEnum;
use App\Services\RoleAndPermissionsService; use App\Services\RoleAndPermissionsService;
use App\Services\ZhenKhService;
use Carbon\Exceptions\UnitNotConfiguredException;
use Closure; use Closure;
use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Auth\Factory as Auth; use Illuminate\Contracts\Auth\Factory as Auth;
...@@ -32,13 +35,6 @@ class Authenticate ...@@ -32,13 +35,6 @@ class Authenticate
*/ */
protected $auth; protected $auth;
protected $whiteList = [
'/adminapi/user/info',
'/adminapi/auth/logout',
'/adminapi/permission/dictData/defaultButtonPermission',
'/adminapi/permission/menu/userRoleMenuList'
];
/** /**
* Create a new middleware instance. * Create a new middleware instance.
* *
...@@ -61,133 +57,24 @@ class Authenticate ...@@ -61,133 +57,24 @@ class Authenticate
*/ */
public function handle($request, Closure $next, $guard = null) public function handle($request, Closure $next, $guard = null)
{ {
/** $token = trim(str_ireplace('bearer', '', $request->header('authorization')));
* 如果路由是登出或者是修改密码的时候,需要对token进行处理,否则jwt处理时会出错 $decodeToken = $this->decodeToken($token);
*/
if(
Str::endsWith(strtolower((string) $request->getPathInfo()), 'logout') ||
Str::endsWith(strtolower((string) $request->getPathInfo()), 'resetpassword')
)
{
$token = trim(str_ireplace('bearer', '', $request->header('authorization')));
$decodeToken = $this->decodeToken($token);
if(empty($decodeToken) || (!is_array($decodeToken) && !$decodeToken['hash'])){
throw new UnauthorizedHttpException('JWTAuth', 'Unable to authenticate with invalid token.');
}
/*$chains = app('tymon.jwt.parser')->getChain();
$chains[0]->setHeaderName($decodeToken['hash']);
app('tymon.jwt.parser')->setChain($chains);*/
$request->headers->set('authorization','bearer'.$decodeToken['hash']); $params = $request->all();
if(!isset($params['platform']) || empty($params['platform'])){
throw new UnauthorizedHttpException('JWTAuth','平台参数错误');
} }
else{ switch($params['platform']){
case 'zkh' : $platformToken = app(ZhenKhService::class)->apiService->getPlatformInfo('platform_token');break;
//对用户权限进行判断验证
$currentUser = auth()->user();
if(!$currentUser->isSuperAdmin()){
if(!$this->userHasPermission($currentUser, $request)){
throw new \LogicException('你无权访问或使用该功能',ResponseCodeEnum::SYSTEM_ERROR);
}
return $next($request);
}
}
return $next($request);
}
/**
* 判断用户是否有访问当前路由的权限
* @param $user
* @param $request
* @return bool
*/
protected function userHasPermission($user, $request)
{
$userPermissions = [];
$routeParams = $request->route()[1];
if(!isset($routeParams['permission'])){
return true;
} }
$routePermissions = explode(',',$routeParams['permission']); if(empty($platformToken) || $decodeToken['hash'] !== $platformToken){
// 如果该路由不存在权限,或者在白名单中,直接不做权限验证 throw new UnauthorizedHttpException('JWTAuth','无效的平台token');
if(empty($routePermissions) || count($routePermissions) == 0){
return true;
} }
// 获取用户的所有角色组对应的权限 if(empty($decodeToken) || (!is_array($decodeToken) && !$decodeToken['hash'])){
$roles = $user->roles; throw new UnauthorizedHttpException('JWTAuth', 'Unable to authenticate with invalid token.');
collect($roles)->map(function($role) use (&$userPermissions){ }
$permissions = $role->permissions;
collect($permissions)->map(function($permission) use (&$userPermissions){
$userPermissions[] = $permission->toArray()['action'];
});
});
$userPermissions = array_values(array_filter($userPermissions));
$hasPermission = false;
// 获取 dingo 对应的版本的路由列表
$routeList = [];
collect(app('Dingo\Api\Contract\Routing\Adapter')->getIterableRoutes())->map(function($routes,$version) use ($request, $userPermissions, $routeParams, &$hasPermission){
if($version != config('api.version')){
return ;
}
// 此逻辑是,可能页面搜索和列表使用的是同一个request请求,如果用搜索来做请求的话,必须把权限设置为搜索权限,否则权限将出现漏洞
// 支持泛权限 如果最后是*号结束,代表只要是前缀相同的都有访问资格
if(
!Str::endsWith(strtolower((string) $routeParams['permission']), '*'))
{
if(
$request->has('buttonAction') &&
$action = $request->input('buttonAction'))
{
$uriPermission = explode(',',$routeParams['permission']);
$permission = explode('.',current($uriPermission));
$permission[count($permission) - 1] = $action;
$requestPermission = implode('.',$permission);
foreach($userPermissions as &$permission){
if(in_array($permission,$uriPermission)){
$permission = $requestPermission;
}
}
}
}
$filterRoute = [];
foreach($routes as $route){
foreach($userPermissions as $permission){
if(isset($route['permission']) &&
Str::endsWith(strtolower((string) $route['permission']), '*'))
{
$uriPermission = explode('.',$route['permission']);
unset($uriPermission[count($uriPermission) - 1]);
if(
Str::startsWith($permission,strtolower((string) implode('.',$uriPermission)))
){
$filterRoute[] = $route['uri'];
}
}else{
if(isset($route['permission']) && in_array($permission,explode(',',$route['permission']))){
$filterRoute[] = $route['uri'];
}
}
}
}
// 找到角色权限对应的路由
if(count($filterRoute) > 0 && in_array($routeParams['uri'],$filterRoute)){
$hasPermission = true;
}
});
return $hasPermission; return $next($request);
} }
} }
...@@ -48,6 +48,9 @@ class ZhenkhJob extends Job ...@@ -48,6 +48,9 @@ class ZhenkhJob extends Job
case 'orderNoRollBack' : case 'orderNoRollBack' :
$service->orderNoRollBack(); $service->orderNoRollBack();
break; break;
case 'createJwtToken' :
$service->createJwtToken();
break;
default: default:
} }
} }
......
<?php
/*
* This file is part of the Jiannei/lumen-api-starter.
*
* (c) Jiannei <longjian.huang@foxmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace App\Services;
use App\Repositories\Contracts\UsersRepository;
use App\Repositories\Criteria\UserCriteria;
use App\Repositories\Presenters\UserPresenter;
use App\Repositories\Enums\ResponseCodeEnum;
use App\Support\Traits\Helpers;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Spatie\Permission\Models\Role;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use App\Repositories\Models\AdminUsers;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
class AuthService
{
use Helpers;
protected $userRepository = null;
public function __construct(UsersRepository $usersRepository)
{
$this->userRepository = $usersRepository;
}
/**
* @param Request $request
*/
public function login(Request $request)
{
$username = $request->input('username');
$password = $request->input('password');
$requestCriteria = [
'username' => $username,
'password' => $password
];
try{
if( !$user = auth()->attempt($requestCriteria) ){
throw new UnauthorizedHttpException('authroization error','用户登陆授权失败,用户名或密码错误',null,ResponseCodeEnum::CLIENT_PARAMETER_ERROR);
}
if(auth()->user()->toArray()['status'] == 0){
throw new UnauthorizedHttpException('authroization error','用户登陆授权失败,该用户已被冻结',null,ResponseCodeEnum::CLIENT_PARAMETER_ERROR);
}
return $this->generateToken($user);
}catch(\Exception $exception){
throw new UnauthorizedHttpException('authroization error',$exception->getMessage(),null,ResponseCodeEnum::SERVICE_LOGIN_ERROR);
}
}
/**
* 获取登陆用户信息
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function getUserInfo()
{
$user = auth()->user();
//除去敏感信息
if(isset($user['password'])){
unset($user['password']);
}
if(isset($user['token'])){
unset($user['token']);
}
return $user;
}
/**
* 用户列表
* @param $request
* @return array
*/
public function listByPage($request)
{
$params = $this->formatKeysfromArray($request->all(),'toUnderScore');
if(!$params['page_size'] || $params['page_size'] == 0){
$params['page_size'] = 10;
}
$this->userRepository->pushCriteria(new UserCriteria($request));
$users = $this->userRepository->paginate($params['page_size'],['id','username','nickname','email','token','is_admin','status','lastlogin','created_at','updated_at']);
$returnRecord = [];
if($users){
$allItems = $users->items();
$allItems = collect($allItems)->map(function($item){
$rolesName = [];
$roles = collect($item->roles->toArray())->map(function($role) use (&$rolesName){
$rolesName[] = $role['name'];
unset($role['pivot']);
return $role;
});
$item = $item->toArray();
unset($item['roles']);
$item['roles'] = $roles->toArray();
$item['type'] = $item['is_admin'];
$item['belongTo'] = implode(',',$rolesName);
return $item;
});
// 获取当前角色的所有权限
$returnRecord['data'] = $this->formatKeysfromArray($allItems);
$returnRecord['current_page'] = $users->currentPage();
$returnRecord['total'] = $users->total();
}
return $returnRecord;
}
/**
* 用户登出
* @param Request $request
*/
public function logout(Request $request)
{
auth()->logout();
}
/**
* 刷新token
* @return mixed
* @throws TokenInvalidException
*/
public function refreshToken()
{
$token = auth()->refresh();
if(!$token){
throw new TokenInvalidException('token刷新失败',ResponseCodeEnum::SERVICE_TOKEN_REFRESH_ERROR);
}
return $this->generateToken($token);
}
/**
* 更新或创建新用户
* @param $request
* @return bool
*/
public function saveOrUpdateUser($request)
{
$params = $this->formatKeysfromArray($request->all(),'toUnderScore');
$rule = $this->userRepository->rules['create'];
$filterRuleParams = [];
if(isset($params['id']) && !empty($params['id'])){
$rule = $this->userRepository->rules['update'];
$filterRuleParams['id'] = $params['id'];
}
//整理请求过来的数据参数
collect($rule)->map(function($r,$key) use ($params, &$filterRuleParams){
if(isset($params[$key]) && !empty($params[$key])){
$filterRuleParams[$key] = $params[$key];
}else{
$filterRuleParams[$key] = '';
}
});
if($user = $this->userRepository->createOrUpdateUser($filterRuleParams)){
// 如果编辑用户时选择了所属角色
if(isset($params['role_ids']) && !empty($params['role_ids'])){
$ids = explode(',',$params['role_ids']);
//获取需要分配的角色
$toBeAssignRoles = Role::query()->whereIn('id',$ids)->get();
if(!$toBeAssignRoles){
throw new \LogicException('角色不存在');
}
//判断当前用户是否有相应的角色权限
//如果有,先取消。然后在进行新的角色权限分配
$belongRoles = $user->roles;
//角色
if(count($belongRoles->toArray()) > 0){
$this->removeUserRoleAndPermission($user, $belongRoles);
}
$this->authroizeUserRoleAndPermission($user, $toBeAssignRoles);
}else{
$belongRoles = $user->roles;
if(count($belongRoles->toArray()) > 0){
$this->removeUserRoleAndPermission($user,$belongRoles);
}
// 设置默认角色
$defaultRole = Role::query()->where('is_default', 1)->get();
$this->authroizeUserRoleAndPermission($user,$defaultRole);
}
}
return true;
}
/**
* 移除当前用户所在的角色及角色权限
* @param $user
* @param $roles
*/
public function removeUserRoleAndPermission($user,$roles)
{
collect($roles)->map(function($role) use ($user){
$permissions = $role->permissions;
$user->removeRole($role);
collect($permissions)->map(function($permission) use ($user){
$user->revokePermissionTo($permission);
});
});
}
/**
* 授权当前用户所在的角色及角色权限
* @param $user
* @param $roles
*/
public function authroizeUserRoleAndPermission($user, $roles)
{
collect($roles)->map(function($role) use ($user){
$user->assignRole($role);
$permissions = $role->permissions;
collect($permissions)->map(function($permission) use ($user){
$user->givePermissionTo($permission);
});
});
}
/**
* 更新用户状态
* @param $request
* @param $id
*/
public function updateUserStatus($request, $id)
{
$status = 0;
if(Str::contains(strtolower((string) $request->getPathInfo()), 'disable')){
$status = 0;
}elseif(Str::contains(strtolower((string) $request->getPathInfo()), 'enable')){
$status = 1;
}
$this->userRepository->updateUserStatus($id,$status);
}
/**
* 物理删除用户
* @param $request
*/
public function deleteUser($request)
{
$params = $this->formatKeysfromArray($request->all(),'toUnderScore');
$ids = explode(',',$params['ids']);
$users = $this->userRepository->whereIn('id',$ids)->get();
if(count($users->toArray()) != count($ids)){
throw new \LogicException('部分用户不存在');
}
if($this->userRepository->deleteUser($ids)){
//将用户的角色收回
collect($users)->map(function($user){
$roles = $user->roles;
collect($roles)->map(function($role) use ($user){
$user->removeRole($role);
});
});
}
}
/**
* 重置密码
* @param Request $request
* @return bool
*/
public function resetPassword(Request $request)
{
// 判断旧密码是否正确
$oldPassword = $request->input('oldpassword');
$newPassword = $request->input('newpassword');
$adminModel = app(AdminUsers::class);
$user = $this->userRepository->where('id',auth()->user()->id)->first();
if(!$user){
throw new UnauthorizedHttpException('user not exist. ','不存在该用户',null,ResponseCodeEnum::SERVICE_USER_NOT_EXIST_ERROR);
}
$encodeOldPassword = $adminModel->encryptPassword($oldPassword);
if($encodeOldPassword != $user->password){
throw new UnauthorizedHttpException('password is error. ','密码更新失败:旧密码不正确',null,ResponseCodeEnum::SERVICE_PASSWORD_ERROR);
}
$user->password = $adminModel->encryptPassword($newPassword);
if($encodeOldPassword == $user->password){
throw new UnauthorizedHttpException('password is error. ','新密码不能和旧密码一致',null,ResponseCodeEnum::SERVICE_PASSWORD_ERROR);
}
// 根据role规则重组 user
$updateUser = collect($this->userRepository->rules['update'])->map(function($rule,$key) use ($user){
return $user[$key];
});
$result = $this->userRepository->update($updateUser->toArray(),$user->id);
return true;
}
}
...@@ -287,11 +287,6 @@ class ZhenkhApiService extends PlatformAbstractService ...@@ -287,11 +287,6 @@ class ZhenkhApiService extends PlatformAbstractService
} }
} }
public function getDeliveryOrder($token)
{
}
public function getDeliveryOrderDetailForPDF($deliveryCode, $token) public function getDeliveryOrderDetailForPDF($deliveryCode, $token)
{ {
try{ try{
......
...@@ -7,9 +7,12 @@ use App\Services\Kafka\KafkaService; ...@@ -7,9 +7,12 @@ use App\Services\Kafka\KafkaService;
use App\Services\ThirdPlatform\Api\ZhenkhApiService; use App\Services\ThirdPlatform\Api\ZhenkhApiService;
use App\Support\Facades\SimpleKafka; use App\Support\Facades\SimpleKafka;
use App\Support\Facades\SimpleLogs; use App\Support\Facades\SimpleLogs;
use App\Support\Traits\Helpers;
class ZhenKhService class ZhenKhService
{ {
use Helpers;
public function __construct() public function __construct()
{ {
$this->apiService = (new ZhenkhApiService(app(ThirdApiPlatformRepository::class))); $this->apiService = (new ZhenkhApiService(app(ThirdApiPlatformRepository::class)));
...@@ -28,6 +31,14 @@ class ZhenKhService ...@@ -28,6 +31,14 @@ class ZhenKhService
} }
} }
public function createJwtToken()
{
$token = $this->apiService->getPlatformInfo('platform_token');
$jwtToken = $this->generateToken($token);
var_dump($jwtToken);
exit;
}
/** /**
* @上报商品的价格及库存 * @上报商品的价格及库存
* @param $params * @param $params
...@@ -272,7 +283,6 @@ class ZhenKhService ...@@ -272,7 +283,6 @@ class ZhenKhService
$deliveryPost['logisticsName'] = $zkhDelivery['expressName']; $deliveryPost['logisticsName'] = $zkhDelivery['expressName'];
$deliveryPost['logisticsCode'] = $zkhDelivery['expressCode']; $deliveryPost['logisticsCode'] = $zkhDelivery['expressCode'];
} }
$pids = [];
$itemList = []; $itemList = [];
foreach($orderDelivery as $delivery){ foreach($orderDelivery as $delivery){
$zkhGoods = $this->rhawnService->getZkhGoodsSku($delivery->p_id); $zkhGoods = $this->rhawnService->getZkhGoodsSku($delivery->p_id);
...@@ -303,12 +313,13 @@ class ZhenKhService ...@@ -303,12 +313,13 @@ class ZhenKhService
} }
$deliveryPost['itemList'] = $resetItemList; $deliveryPost['itemList'] = $resetItemList;
//确认发货 //确认发货
$this->apiService->ackDeliveryOrder($deliveryPost,$this->getToken()); $deliveryResult = $this->apiService->ackDeliveryOrder($deliveryPost,$this->getToken());
if($deliveryResult){
$this->apiService->storePlatformDataEntries('zkh_delivery_code_'.$deliveryCode,['code' => $deliveryResult['data']]);
}
} }
}catch(\Throwable $exception){ }catch(\Throwable $exception){
var_dump($exception->getMessage());
exit;
SimpleLogs::writeLog($exception->getMessage(),'sendDeliveryOrder', 'error'); SimpleLogs::writeLog($exception->getMessage(),'sendDeliveryOrder', 'error');
} }
} }
...@@ -320,11 +331,12 @@ class ZhenKhService ...@@ -320,11 +331,12 @@ class ZhenKhService
*/ */
public function getDeliveryOrderPdf($deliveryCode) public function getDeliveryOrderPdf($deliveryCode)
{ {
$pdf = $this->apiService->getPlatformDataEntries('zkh_order_delivery_pdf','data_values'); $pdf = $this->apiService->getPlatformDataEntries('zkh_order_delivery_pdf_'.$deliveryCode,'data_values');
if(!$pdf || empty($pdf)){ if(!$pdf || empty($pdf)){
$deliveryInfo = $this->apiService->getDeliveryOrderDetailForPDF($deliveryCode,$this->getToken()); $zkhDeliveryCode = $this->apiService->getPlatformDataEntries('zkh_delivery_code_'.$deliveryCode,'data_values');
$deliveryInfo = $this->apiService->getDeliveryOrderDetailForPDF($zkhDeliveryCode,$this->getToken());
if($deliveryInfo){ if($deliveryInfo){
$this->apiService->storePlatformDataEntries('zkh_order_delivery_pdf',['pdf' => $deliveryInfo]); $this->apiService->storePlatformDataEntries('zkh_order_delivery_pdf_'.$deliveryCode,['pdf' => $deliveryInfo]);
return $deliveryInfo; return $deliveryInfo;
} }
} }
......
...@@ -99,6 +99,7 @@ $app->middleware([ ...@@ -99,6 +99,7 @@ $app->middleware([
]); ]);
$app->routeMiddleware([ $app->routeMiddleware([
'apiAuth' => App\Http\Controllers\Middleware\Authenticate::class,
'syslog' => App\Http\Controllers\Middleware\SysLog::class, 'syslog' => App\Http\Controllers\Middleware\SysLog::class,
//'enum' => \Jiannei\Enum\Laravel\Http\Middleware\TransformEnums::class, //'enum' => \Jiannei\Enum\Laravel\Http\Middleware\TransformEnums::class,
//'throttle' => \Jiannei\Response\Laravel\Http\Middleware\ThrottleRequests::class, //'throttle' => \Jiannei\Response\Laravel\Http\Middleware\ThrottleRequests::class,
......
...@@ -13,33 +13,10 @@ ...@@ -13,33 +13,10 @@
$api->version('v1', function($api) { $api->version('v1', function($api) {
$api->group(['namespace'=>'App\Http\Controllers\V1','middleware' => ['api.auth','permissions'], 'providers' => 'jwt'], function($api) { $api->group(['namespace'=>'App\Http\Controllers\V1','middleware' => ['apiAuth'], 'providers' => 'jwt'], function($api) {
// 百化采购订单
$api->get('/adminapi/tools/bh/searchBhPorders', ['permission' => 'tools.bh.order.search', 'uses'=>'BhOrdersController@searchPorders']);
$api->post('/adminapi/tools/bh/editBhPorders', ['permission' => 'tools.bh.order.edit', 'uses'=>'BhOrdersController@editBhPorders']);
// 百化销售订单
$api->post('/adminapi/tools/bh/addSorderRefundTask', ['permission' => 'tools.bh.order.add', 'uses'=>'BhOrdersController@addSorderRefundTask']);
$api->post('/adminapi/tools/bh/editSorderRefundTask', ['permission' => 'tools.bh.order.add', 'uses'=>'BhOrdersController@editSorderRefundTask']);
$api->post('/adminapi/tools/bh/getBhSordersDetail', ['permission' => 'tools.bh.order.search', 'uses'=>'BhOrdersController@getBhSordersDetail']);
$api->get('/adminapi/tools/bh/getBhSorderRefundTask', ['permission' => 'tools.bh.order.search', 'uses'=>'BhOrdersController@getBhSorderRefundTaskToPage']);
$api->post('/adminapi/tools/bh/execBhSorderRefundTask', ['permission' => 'tools.bh.order.search', 'uses'=>'BhOrdersController@execBhSorderRefundTask']);
$api->get('/adminapi/tools/bh/getSorderRefundTaskLogs', ['permission' => 'tools.bh.order.search', 'uses'=>'BhOrdersController@getSorderRefundTaskLogsToPage']);
$api->post('/adminapi/tools/bh/delSorderRefundTask', ['permission' => 'tools.bh.order.search', 'uses'=>'BhOrdersController@delSorderRefundTask']);
$api->post('/adminapi/tools/bh/getSorderDetailByTaskId', ['permission' => 'tools.bh.order.search', 'uses'=>'BhOrdersController@getSorderDetailByTaskId']);
// 罗恩销售订单
$api->post('/adminapi/tools/rhawn/addSorderRefundTask', ['permission' => 'tools.rhawn.order.add', 'uses'=>'RhawnOrdersController@addSorderRefundTask']);
$api->post('/adminapi/tools/rhawn/editSorderRefundTask', ['permission' => 'tools.rhawn.order.add', 'uses'=>'RhawnOrdersController@editSorderRefundTask']);
$api->post('/adminapi/tools/rhawn/getSordersDetail', ['permission' => 'tools.rhawn.order.search', 'uses'=>'RhawnOrdersController@getSordersDetail']);
$api->get('/adminapi/tools/rhawn/getRhawnSordersStock', ['permission' => 'tools.rhawn.order.search', 'uses'=>'RhawnOrdersController@getRhawnSordersStock']);
$api->get('/adminapi/tools/rhawn/getSorderRefundTask', ['permission' => 'tools.rhawn.order.search', 'uses'=>'RhawnOrdersController@getSorderRefundTaskToPage']);
$api->post('/adminapi/tools/rhawn/execRhawnSorderRefundTask', ['permission' => 'tools.rhawn.order.search', 'uses'=>'RhawnOrdersController@execRhawnSorderRefundTask']);
$api->get('/adminapi/tools/rhawn/getSorderRefundTaskLogs', ['permission' => 'tools.rhawn.order.search', 'uses'=>'RhawnOrdersController@getSorderRefundTaskLogsToPage']);
$api->post('/adminapi/tools/rhawn/delSorderRefundTask', ['permission' => 'tools.rhawn.order.search', 'uses'=>'RhawnOrdersController@delSorderRefundTask']);
$api->post('/adminapi/tools/rhawn/getSorderDetailByTaskId', ['permission' => 'tools.rhawn.order.search', 'uses'=>'RhawnOrdersController@getSorderDetailByTaskId']);
$api->post('/openapi/zkh/orderDelivery', ['permission' => 'openapi.zkh.orderDelivery', 'uses'=>'ZhenkhController@orderDelivery']);
$api->post('/openapi/zkh/getOrderDeliveryPdf', ['permission' => 'openapi.zkh.getOrderDeliveryPdf', 'uses'=>'ZhenkhController@getOrderDeliveryPdf']);
}); });
}); });
......
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