Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
58c8eecf88 | |||
8a3ab17b25 | |||
fb50096e66 |
@ -15,6 +15,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Amqp\Consumer;
|
||||
|
||||
use App\Context\ApiUrlContext;
|
||||
use Hyperf\Amqp\Message\ConsumerMessage;
|
||||
use App\Context\QueueContext;
|
||||
use Hyperf\Amqp\Result;
|
||||
@ -46,8 +47,8 @@ abstract class BaseConsumer extends ConsumerMessage
|
||||
if (!empty($data['user'])) {
|
||||
QueueContext::setUser($data['user']);
|
||||
}
|
||||
if (!empty($company = $data['company'])) {
|
||||
QueueContext::setCompanyInfo($company);
|
||||
if (!empty($this->data['api_url'])) {
|
||||
ApiUrlContext::setApiUrl($this->data['api_url']);
|
||||
}
|
||||
|
||||
Db::beginTransaction();
|
||||
|
@ -15,6 +15,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Amqp\Producer;
|
||||
|
||||
use App\Context\ApiUrlContext;
|
||||
use App\Context\UserContext;
|
||||
use Hyperf\Amqp\Message\ProducerMessage;
|
||||
|
||||
@ -38,6 +39,10 @@ abstract class BaseProducer extends ProducerMessage
|
||||
$data['user'] = UserContext::getCurrentUser();
|
||||
}
|
||||
|
||||
if (ApiUrlContext::hasApiUrl()) {
|
||||
$data['api_url'] = ApiUrlContext::getApiUrl();
|
||||
}
|
||||
|
||||
$this->payload = $data;
|
||||
$this->properties['delivery_mode'] = 2; // 消息持久化
|
||||
}
|
||||
|
17
app/Constants/ErrorCode.php
Normal file
17
app/Constants/ErrorCode.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Constants;
|
||||
|
||||
use Hyperf\Constants\AbstractConstants;
|
||||
use Hyperf\Constants\Annotation\Constants;
|
||||
|
||||
#[Constants]
|
||||
class ErrorCode extends AbstractConstants
|
||||
{
|
||||
/**
|
||||
* @Message("Server Error!")
|
||||
*/
|
||||
const int SERVER_ERROR = 500;
|
||||
}
|
54
app/Context/ApiUrlContext.php
Normal file
54
app/Context/ApiUrlContext.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/11
|
||||
* Time: 下午9:00
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Context;
|
||||
|
||||
use Hyperf\Context\Context;
|
||||
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/11
|
||||
* Time: 下午9:00
|
||||
* Description: ApiUrlContext. 请求url上下文
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
class ApiUrlContext
|
||||
{
|
||||
private const string API_URL_KEY = 'api_url';
|
||||
|
||||
public static function setApiUrl(string $apiUrl): void
|
||||
{
|
||||
Context::set(self::API_URL_KEY, $apiUrl);
|
||||
}
|
||||
|
||||
public static function getApiUrl(): ?string
|
||||
{
|
||||
return Context::get(self::API_URL_KEY);
|
||||
}
|
||||
|
||||
public static function clearApiUrl(): void
|
||||
{
|
||||
Context::set(self::API_URL_KEY, null);
|
||||
}
|
||||
|
||||
public static function hasApiUrl(): bool
|
||||
{
|
||||
return Context::has(self::API_URL_KEY);
|
||||
}
|
||||
}
|
@ -44,25 +44,6 @@ class QueueContext
|
||||
return Context::get(self::USER_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前公司信息
|
||||
* @param array $companyInfo
|
||||
* @return void
|
||||
*/
|
||||
public static function setCompanyInfo(array $companyInfo): void
|
||||
{
|
||||
Context::set(self::COMPANY_KEY, $companyInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前公司信息
|
||||
* @return array|null
|
||||
*/
|
||||
public static function getCompanyInfo(): ?array
|
||||
{
|
||||
return Context::get(self::COMPANY_KEY);
|
||||
}
|
||||
|
||||
public static function clear(): void
|
||||
{
|
||||
Context::destroy(self::USER_KEY);
|
||||
|
@ -35,7 +35,7 @@ class UserContext
|
||||
public static function setCurrentUser(array|string|int $user): void
|
||||
{
|
||||
$companyRepository = make(FirstCompanyRepository::class);
|
||||
if (!empty($companyInfo = $companyRepository->getCompanyByFullName($user['user']['full_name']))) {
|
||||
if (!empty($companyInfo = $companyRepository->getCompanyByFullName($user['full_name'], false))) {
|
||||
$user['company'] = $companyInfo;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ namespace App\Controller;
|
||||
|
||||
use App\Repository\Company\CompanyRepository;
|
||||
use App\Request\CompanyRequest;
|
||||
use Exception;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpMessage\Server\Response;
|
||||
use Hyperf\Validation\Annotation\Scene;
|
||||
@ -30,6 +31,7 @@ class CompanyController extends AbstractController
|
||||
* 添加公司.
|
||||
* @param CompanyRequest $request
|
||||
* @return Response
|
||||
* @throws Exception
|
||||
*/
|
||||
#[Scene(scene: 'addCompany', argument: 'request')]
|
||||
public function addCompany(CompanyRequest $request): Response
|
||||
|
@ -15,8 +15,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\JsonRpc\UserAuthServiceInterface;
|
||||
use App\Constants\ActiveStatusConst;
|
||||
use App\JsonRpc\RoleServiceInterface;
|
||||
use App\Repository\Company\CompanyModulesRepository;
|
||||
use App\Repository\Company\FirstCompanyRepository;
|
||||
use App\Request\RoleRequest;
|
||||
use App\Service\PermissionService;
|
||||
use Hyperf\Config\Annotation\Value;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpMessage\Server\Response;
|
||||
use Hyperf\Validation\Annotation\Scene;
|
||||
@ -24,7 +29,19 @@ use Hyperf\Validation\Annotation\Scene;
|
||||
class RoleController extends AbstractController
|
||||
{
|
||||
#[Inject]
|
||||
protected UserAuthServiceInterface $userAuthServiceInterface;
|
||||
protected RoleServiceInterface $roleServiceInterface;
|
||||
|
||||
#[Inject]
|
||||
protected PermissionService $permissionService;
|
||||
|
||||
#[Inject]
|
||||
protected CompanyModulesRepository $companyModulesRepository;
|
||||
|
||||
#[Inject]
|
||||
protected FirstCompanyRepository $firstCompanyRepository;
|
||||
|
||||
#[Value('menu.data_permissions')]
|
||||
protected array $menuDataPermissions;
|
||||
|
||||
/**
|
||||
* 添加角色.
|
||||
@ -37,15 +54,172 @@ class RoleController extends AbstractController
|
||||
$params = $request->all();
|
||||
|
||||
$data = [
|
||||
'companyInfo' => $this->company(),
|
||||
'token' => $this->token(),
|
||||
'id' => $params['id'] ?? null,
|
||||
'role_name' => $params['role_name'],
|
||||
'active_status' => $params['active_status'],
|
||||
'sort' => $params['sort'],
|
||||
];
|
||||
// 添加角色.
|
||||
$this->userAuthServiceInterface->addRole($data);
|
||||
$this->roleServiceInterface->addRole($data);
|
||||
|
||||
return $this->apiResponse->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色列表.
|
||||
* @return Response
|
||||
*/
|
||||
public function roleList(): Response
|
||||
{
|
||||
$params = $this->request->all();
|
||||
$data = [
|
||||
'token' => $this->token(),
|
||||
'getPage' => $this->getPage(),
|
||||
'params' => $params
|
||||
];
|
||||
|
||||
$roleList = $this->roleServiceInterface->roleList($data);
|
||||
|
||||
return $this->apiResponse->success($roleList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用角色.
|
||||
* @param RoleRequest $request
|
||||
* @return Response
|
||||
*/
|
||||
#[Scene(scene: 'disableRoles', argument: 'request')]
|
||||
public function disableRoles(RoleRequest $request): Response
|
||||
{
|
||||
$params = $request->all();
|
||||
$data = [
|
||||
'token' => $this->token(),
|
||||
'params' => $params,
|
||||
];
|
||||
$rpcResult = $this->roleServiceInterface->disableRoles($data);
|
||||
|
||||
$status = $params['status'] ?
|
||||
ActiveStatusConst::getMessage(ActiveStatusConst::ACTIVE_ENABLE) :
|
||||
ActiveStatusConst::getMessage(ActiveStatusConst::ACTIVE_DISABLE);
|
||||
|
||||
$res = $rpcResult['result'] ?? [];
|
||||
$this->opLogs('[' . $status . '角色]名称 ' . $res['role_name'] ?? '');
|
||||
return $this->apiResponse->success($rpcResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除角色.
|
||||
* @param RoleRequest $request
|
||||
* @return Response
|
||||
*/
|
||||
#[Scene(scene: 'delRoles', argument: 'request')]
|
||||
public function delRoles(RoleRequest $request): Response
|
||||
{
|
||||
$params = $request->all();
|
||||
$data = [
|
||||
'token' => $this->token(),
|
||||
'params' => $params,
|
||||
];
|
||||
$rpcResult = $this->roleServiceInterface->deletedRoles($data);
|
||||
|
||||
$res = $rpcResult['result'] ?? '';
|
||||
$this->opLogs('[删除角色]名称 ' . $res);
|
||||
return $this->apiResponse->success($rpcResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配用户角色.
|
||||
* @param RoleRequest $request
|
||||
* @return Response
|
||||
*/
|
||||
#[Scene(scene: 'assignUserRoles', argument: 'request')]
|
||||
public function assignUserRoles(RoleRequest $request): Response
|
||||
{
|
||||
$params = $request->all();
|
||||
$params['menu_data_permission'] = $this->menuDataPermissions;
|
||||
$data = [
|
||||
'token' => $this->token(),
|
||||
'params' => $params,
|
||||
];
|
||||
|
||||
$rpcResult = $this->roleServiceInterface->assignUserRoles($data);
|
||||
$res = $rpcResult['result'] ?? '';
|
||||
|
||||
$this->opLogs('[角色管理] 分配用户角色 ' . $res);
|
||||
return $this->apiResponse->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色授权
|
||||
*/
|
||||
#[Scene(scene: 'assignRolePermissions', argument: 'request')]
|
||||
public function assignRolePermissions(RoleRequest $request): Response
|
||||
{
|
||||
$params = $request->all();
|
||||
$data = [
|
||||
'token' => $this->token(),
|
||||
'params' => $params
|
||||
];
|
||||
$rpcResult = $this->roleServiceInterface->assignRolePermissions($data);
|
||||
$res = $rpcResult['result'] ?? [];
|
||||
|
||||
$this->opLogs('[角色授权]' . $res['role_name'] . ': 权限集 ' . implode(',', $res['actions']));
|
||||
return $this->apiResponse->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色权限列表
|
||||
* @param RoleRequest $request
|
||||
* @return Response
|
||||
*/
|
||||
#[Scene(scene: 'roleChecked', argument: 'request')]
|
||||
public function roleChecked(RoleRequest $request): Response
|
||||
{
|
||||
$params = [
|
||||
'token' => $this->token(),
|
||||
'params' => $request->all()
|
||||
];
|
||||
$rpcResult = $this->roleServiceInterface->getRolePermissionsByRoleId($params);
|
||||
|
||||
$res = $rpcResult['result'] ?? [];
|
||||
$menu = $this->permissionService->checkMenu($res);
|
||||
|
||||
return $this->apiResponse->success($menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公司功能模块授权.
|
||||
* @param RoleRequest $request
|
||||
* @return Response
|
||||
*/
|
||||
#[Scene(scene: 'addCompanyModule', argument: 'request')]
|
||||
public function addCompanyModule(RoleRequest $request): Response
|
||||
{
|
||||
$params = $request->all();
|
||||
|
||||
$companyInfo = $this->firstCompanyRepository->getCompanyById($params['company_id']);
|
||||
|
||||
$res = $this->companyModulesRepository->addModule($params);
|
||||
$menuName = array_column($res['module_data_permissions'] ?? [], 'title');
|
||||
|
||||
$this->opLogs('[授权公司功能模块]' . $companyInfo['full_name'] . ' : ' . implode(',', $menuName));
|
||||
return $this->apiResponse->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 公司功能模块列表.
|
||||
* @param RoleRequest $request
|
||||
* @return Response
|
||||
*/
|
||||
#[Scene(scene: 'companyChecked', argument: 'request')]
|
||||
public function companyChecked(RoleRequest $request): Response
|
||||
{
|
||||
$companyId = $request->input('company_id', 0);
|
||||
$moduleList = $this->companyModulesRepository->codeList($companyId);
|
||||
|
||||
$menu = $this->permissionService->checkMenu($moduleList);
|
||||
|
||||
return $this->apiResponse->success($menu);
|
||||
}
|
||||
}
|
39
app/Controller/SystemController.php
Normal file
39
app/Controller/SystemController.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/11
|
||||
* Time: 下午7:05
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Service\PermissionService;
|
||||
use Exception;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpMessage\Server\Response;
|
||||
|
||||
class SystemController extends AbstractController
|
||||
{
|
||||
#[Inject]
|
||||
protected PermissionService $permissionService;
|
||||
|
||||
/**
|
||||
* 菜单列表
|
||||
* @throws Exception
|
||||
*/
|
||||
public function menuList(): Response
|
||||
{
|
||||
$user = $this->user();
|
||||
$menu = $this->permissionService->getMenuByUserType($user);
|
||||
|
||||
return $this->apiResponse->success($menu);
|
||||
}
|
||||
}
|
@ -60,6 +60,26 @@ class UserController extends AbstractController
|
||||
return $this->apiResponse->success($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登出.
|
||||
* @param UserRequest $request
|
||||
* @return Response
|
||||
*/
|
||||
#[Scene(scene: 'userLogout', argument: 'request')]
|
||||
public function userLogout(UserRequest $request): Response
|
||||
{
|
||||
$user = $this->user();
|
||||
$token = $this->token();
|
||||
|
||||
$this->userAuthService->userLogout([
|
||||
'token' => $token,
|
||||
'refresh_token' => $request->input('refresh_token')
|
||||
]);
|
||||
|
||||
$this->opLogs('[PC端用户退出]' . $user['name']);
|
||||
return $this->apiResponse->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户.
|
||||
* @param UserRequest $request
|
||||
@ -88,8 +108,7 @@ class UserController extends AbstractController
|
||||
public function getUserList(UserRequest $request): Response
|
||||
{
|
||||
$data = [
|
||||
'companyInfo' => $this->company(),
|
||||
'userInfo' => UserContext::getCurrentUser(),
|
||||
'token' => $this->token(),
|
||||
'getPage' => $this->getPage(),
|
||||
'params' => $request->all()
|
||||
];
|
||||
|
@ -55,10 +55,28 @@ abstract class AbstractDao
|
||||
private array $queryResult;
|
||||
|
||||
/**
|
||||
* 获取模型
|
||||
* @return Model
|
||||
*/
|
||||
abstract protected function getModel(): string;
|
||||
|
||||
/**
|
||||
* 获取query selector 字段
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getFields(): array;
|
||||
|
||||
/**
|
||||
* 构建查询条件.
|
||||
* @throws Exception
|
||||
*/
|
||||
public function buildWhere(Builder $builder, array $params = []): Builder
|
||||
{
|
||||
// 根据字段查询数据库,params存在的条件进行查询
|
||||
$fields = $this->getFields();
|
||||
return self::daoBuildWhere($builder, $params, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据操作.
|
||||
*/
|
||||
|
@ -35,4 +35,9 @@ class CompanyDao extends AbstractDao
|
||||
{
|
||||
return Company::class;
|
||||
}
|
||||
|
||||
public function getFields(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
32
app/Dao/Company/CompanyModulesDao.php
Normal file
32
app/Dao/Company/CompanyModulesDao.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/10
|
||||
* Time: 下午8:59
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Dao\Company;
|
||||
|
||||
use App\Dao\AbstractDao;
|
||||
use App\Model\CompanyModules;
|
||||
|
||||
class CompanyModulesDao extends AbstractDao
|
||||
{
|
||||
public function getModel(): string
|
||||
{
|
||||
return CompanyModules::class;
|
||||
}
|
||||
|
||||
public function getFields(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -35,4 +35,9 @@ class PurchaseDao extends AbstractDao
|
||||
{
|
||||
return Purchase::class;
|
||||
}
|
||||
|
||||
public function getFields(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
125
app/Helpers/functions.php
Normal file
125
app/Helpers/functions.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/10
|
||||
* Time: 下午7:37
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Hyperf\Collection\Arr;
|
||||
|
||||
/**
|
||||
* 合并权限CODE为一维数组.
|
||||
*/
|
||||
function mergePermissions(array $permissions): array
|
||||
{
|
||||
$code_list = [];
|
||||
foreach ($permissions as $value) {
|
||||
foreach ($value as $permission) {
|
||||
$code_list[] = $permission;
|
||||
}
|
||||
}
|
||||
// 合并指定键下的值到一个二维数组中
|
||||
$mergedArray = [];
|
||||
foreach ($code_list as $item) {
|
||||
$values = array_values($item);
|
||||
$mergedArray = array_merge($mergedArray, $values);
|
||||
}
|
||||
return $mergedArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* 树形数据转换为线性数据(多维数组转为一维数组).
|
||||
*/
|
||||
function treeToList(mixed $menu): array
|
||||
{
|
||||
$mid = 1; # 初始主键ID
|
||||
$pid = 0; # 初始父ID
|
||||
return getFromChild($menu, $mid, $pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归计算自增ID.
|
||||
*/
|
||||
function getFromChild(mixed $data, mixed &$mid, mixed $pid, string $childField = 'children'): array
|
||||
{
|
||||
$res = [];
|
||||
foreach ($data as $v) {
|
||||
$vCopy = $v;
|
||||
unset($vCopy[$childField]);
|
||||
$vCopy['id'] = $mid++;
|
||||
$vCopy['parent_id'] = $pid;
|
||||
array_push($res, $vCopy);
|
||||
if (! empty($v[$childField])) {
|
||||
$res = Arr::collapse([$res, getFromChild($v[$childField], $mid, $vCopy['id'], $childField)]);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统菜单递归,无子集时不返回空子集.
|
||||
*/
|
||||
function listToTree(array $list, string $pk = 'id', string $pid = 'parent_id', string $child = 'children', int $root = 0): array
|
||||
{
|
||||
if (empty($list)) {
|
||||
return [];
|
||||
}
|
||||
$tree = [];
|
||||
# 创建基于主键的数组引用
|
||||
$refer = [];
|
||||
foreach ($list as $key => $data) {
|
||||
$refer[$data[$pk]] = &$list[$key];
|
||||
}
|
||||
foreach ($list as $key => $data) {
|
||||
# 判断是否存在parent
|
||||
$parentId = $data[$pid];
|
||||
if ($root == $parentId) {
|
||||
$tree[] = &$list[$key];
|
||||
} else {
|
||||
if (isset($refer[$parentId])) {
|
||||
$parent = &$refer[$parentId];
|
||||
$parent[$child][] = &$list[$key];
|
||||
} else {
|
||||
$tree[] = $list[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限选中数组处理.
|
||||
*/
|
||||
function checkPermissions(array &$menu, array $menuPermissions, array $dataPermissions): array
|
||||
{
|
||||
foreach ($menu as $key => $value) {
|
||||
$menu[$key]['checked'] = false;
|
||||
if (in_array($value['meta']['code'], $menuPermissions)) {
|
||||
$menu[$key]['checked'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理数组,为 "data_permission" 添加 "checked" 键值对
|
||||
foreach ($menu as &$item) {
|
||||
if (isset($item['meta']['data_permission'])) {
|
||||
$dataPermission = $item['meta']['data_permission'];
|
||||
|
||||
foreach ($dataPermission as &$permission) {
|
||||
$permission['checked'] = false;
|
||||
if (in_array($permission['actions'], $dataPermissions)) {
|
||||
$permission['checked'] = true;
|
||||
}
|
||||
}
|
||||
$item['meta']['data_permission'] = $dataPermission;
|
||||
}
|
||||
}
|
||||
return $menu;
|
||||
}
|
@ -15,6 +15,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Job;
|
||||
|
||||
use App\Context\ApiUrlContext;
|
||||
use App\Context\QueueContext;
|
||||
use App\Log\Log;
|
||||
use Exception;
|
||||
@ -45,8 +46,8 @@ abstract class BaseJob extends Job
|
||||
QueueContext::setUser($user);
|
||||
}
|
||||
|
||||
if (!empty($company = $this->data['company'])) {
|
||||
QueueContext::setCompanyInfo($company);
|
||||
if (!empty($this->data['api_url'])) {
|
||||
ApiUrlContext::setApiUrl($this->data['api_url']);
|
||||
}
|
||||
|
||||
// 运行业务逻辑, 总是在事务中执行,保证事务的原子性
|
||||
|
@ -38,10 +38,9 @@ class RequestWriteLogsJob extends BaseJob
|
||||
|
||||
$clientIPInfo = $rpcResult['result']['ip_info'] ?? '';
|
||||
|
||||
$logMessage = sprintf('%s %s %s',
|
||||
$logMessage = sprintf('%s %s',
|
||||
$this->data['client_ip'] . ' ' . $clientIPInfo,
|
||||
$this->data['method'],
|
||||
$this->data['uri']
|
||||
$this->data['method']
|
||||
);
|
||||
if (!empty($params)) {
|
||||
$logMessage .= ' params: ' . json_encode($params, JSON_UNESCAPED_UNICODE);
|
||||
|
125
app/JsonRpc/RoleServiceConsumer.php
Normal file
125
app/JsonRpc/RoleServiceConsumer.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/8
|
||||
* Time: 下午7:57
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\JsonRpc;
|
||||
|
||||
use Hyperf\RpcClient\AbstractServiceClient;
|
||||
|
||||
class RoleServiceConsumer extends AbstractServiceClient implements RoleServiceInterface
|
||||
{
|
||||
protected string $serviceName = 'RoleService';
|
||||
|
||||
protected string $protocol = 'jsonrpc-http';
|
||||
|
||||
/**
|
||||
* 添加角色.
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function addRole(array $data): void
|
||||
{
|
||||
$this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色列表.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function roleList(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用角色.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function disableRoles(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除角色.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function deletedRoles(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配用户角色.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function assignUserRoles(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色授权.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function assignRolePermissions(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户角色信息.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getUserRoleInfo(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色权限信息.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getRolePermissionsByRoleId(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色ID列表获取角色权限集合.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getRolePermissionSetByRoleIds(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户ID获取用户数据权限.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getUserDataPermissions(array $data): array
|
||||
{
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
}
|
89
app/JsonRpc/RoleServiceInterface.php
Normal file
89
app/JsonRpc/RoleServiceInterface.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/8
|
||||
* Time: 下午7:58
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\JsonRpc;
|
||||
|
||||
interface RoleServiceInterface
|
||||
{
|
||||
/**
|
||||
* 添加角色.
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function addRole(array $data): void;
|
||||
|
||||
/**
|
||||
* 获取角色列表.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function roleList(array $data): array;
|
||||
|
||||
/**
|
||||
* 禁用角色.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function disableRoles(array $data): array;
|
||||
|
||||
/**
|
||||
* 删除角色.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function deletedRoles(array $data): array;
|
||||
|
||||
/**
|
||||
* 分配用户角色.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function assignUserRoles(array $data): array;
|
||||
|
||||
/**
|
||||
* 角色授权
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function assignRolePermissions(array $data): array;
|
||||
|
||||
/**
|
||||
* 获取用户角色信息
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getUserRoleInfo(array $data): array;
|
||||
|
||||
/**
|
||||
* 获取角色权限信息
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getRolePermissionsByRoleId(array $data): array;
|
||||
|
||||
/**
|
||||
* 根据角色ID列表获取角色权限集合
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getRolePermissionSetByRoleIds(array $data): array;
|
||||
|
||||
/**
|
||||
* 获取用户数据权限信息
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function getUserDataPermissions(array $data): array;
|
||||
}
|
@ -44,6 +44,16 @@ class UserAuthServiceConsumer extends AbstractServiceClient implements UserAuthS
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登出
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function userLogout(array $data): void
|
||||
{
|
||||
$this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户.
|
||||
* @param array $data
|
||||
@ -64,16 +74,6 @@ class UserAuthServiceConsumer extends AbstractServiceClient implements UserAuthS
|
||||
return $this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加角色.
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function addRole(array $data): void
|
||||
{
|
||||
$this->__request(__FUNCTION__, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户列表.
|
||||
* @param array $data
|
||||
|
@ -24,6 +24,13 @@ interface UserAuthServiceInterface
|
||||
*/
|
||||
public function userLogin(array $data): array;
|
||||
|
||||
/**
|
||||
* 用户登出
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function userLogout(array $data): void;
|
||||
|
||||
/**
|
||||
* 新增用户.
|
||||
*/
|
||||
@ -36,13 +43,6 @@ interface UserAuthServiceInterface
|
||||
*/
|
||||
public function userInfoByToken(array $data): array;
|
||||
|
||||
/**
|
||||
* 添加角色.
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function addRole(array $data): void;
|
||||
|
||||
/**
|
||||
* 获取用户列表.
|
||||
* @param array $data
|
||||
|
@ -21,7 +21,9 @@ use Hyperf\AsyncQueue\Event\RetryHandle;
|
||||
use Hyperf\Event\Annotation\Listener;
|
||||
use Hyperf\Event\Contract\ListenerInterface;
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
#[Listener]
|
||||
@ -29,6 +31,10 @@ class QueueHandleListener implements ListenerInterface
|
||||
{
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->logger = $container->get(LoggerFactory::class)->get('queue');
|
||||
|
@ -15,6 +15,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Log;
|
||||
|
||||
use App\Context\ApiUrlContext;
|
||||
use Hyperf\Context\Context;
|
||||
use Hyperf\Coroutine\Coroutine;
|
||||
use Monolog\LogRecord;
|
||||
@ -37,6 +38,12 @@ class AppendRequestIdProcessor implements ProcessorInterface
|
||||
|
||||
public function __invoke(LogRecord $record): array|LogRecord
|
||||
{
|
||||
$contextData = ApiUrlContext::getApiUrl();
|
||||
|
||||
if ($contextData) {
|
||||
$record['extra']['api_url'] = $contextData;
|
||||
}
|
||||
|
||||
$record['extra']['request_id'] = Context::getOrSet(self::REQUEST_ID, uniqid('xw_cloud'));
|
||||
$record['extra']['coroutine_id'] = Coroutine::id();
|
||||
return $record;
|
||||
|
@ -18,7 +18,6 @@ namespace App\Middleware;
|
||||
use App\Context\UserContext;
|
||||
use App\Exception\ApiException;
|
||||
use App\JsonRpc\UserAuthServiceInterface;
|
||||
use App\Repository\Company\FirstCompanyRepository;
|
||||
use Exception;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Psr\Container\ContainerInterface;
|
||||
@ -56,11 +55,12 @@ class CheckTokenMiddleware implements MiddlewareInterface
|
||||
|
||||
$rpcResult = $this->userAuthServiceInterface->userInfoByToken(['token' => $token]);
|
||||
|
||||
$userInfo = $rpcResult['result']['user'] ?? [];
|
||||
$userInfo = $rpcResult['result'] ?? [];
|
||||
if (!$userInfo) {
|
||||
throw new ApiException('用户信息不存在', 401);
|
||||
}
|
||||
|
||||
UserContext::setCurrentToken($token);
|
||||
UserContext::setCurrentUser($userInfo);
|
||||
|
||||
return $handler->handle($request);
|
||||
|
23
app/Middleware/PermissionVerifyMiddleware.php
Normal file
23
app/Middleware/PermissionVerifyMiddleware.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
class PermissionVerifyMiddleware implements MiddlewareInterface
|
||||
{
|
||||
public function __construct(protected ContainerInterface $container)
|
||||
{
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware;
|
||||
|
||||
use App\Context\ApiUrlContext;
|
||||
use App\Service\QueueService;
|
||||
use App\Service\SysService;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
@ -51,6 +52,8 @@ class RequestLogsMiddleware implements MiddlewareInterface
|
||||
{
|
||||
$method = $request->getMethod(); // 请求方法
|
||||
$uri = $request->getUri()->getPath(); // 请求的URI路径
|
||||
ApiUrlContext::setApiUrl($uri);
|
||||
|
||||
$params = $request->getMethod() === 'POST' ? $request->getParsedBody() : $request->getQueryParams();
|
||||
|
||||
$clientIp = $this->sysService->getClientIpInfo($request);
|
||||
|
35
app/Model/CompanyModules.php
Normal file
35
app/Model/CompanyModules.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/10
|
||||
* Time: 下午8:54
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Model;
|
||||
|
||||
class CompanyModules extends Model
|
||||
{
|
||||
protected ?string $table = 'company_modules';
|
||||
|
||||
protected array $fillable = [
|
||||
'company_id',
|
||||
'module_code',
|
||||
'module_data_permissions',
|
||||
];
|
||||
|
||||
// 查询格式转换
|
||||
protected array $casts = [
|
||||
'created_at' => 'datetime:Y-m-d H:i:s',
|
||||
'updated_at' => 'datetime:Y-m-d H:i:s',
|
||||
'module_code' => 'json',
|
||||
'module_data_permissions' => 'json',
|
||||
];
|
||||
}
|
@ -24,4 +24,10 @@ abstract class Model extends BaseModel implements CacheableInterface
|
||||
protected ?string $dateFormat = 'U';
|
||||
|
||||
protected array $hidden = ['deleted_at', 'password'];
|
||||
|
||||
protected array $casts = [
|
||||
'created_at' => 'datetime:Y-m-d H:i:s',
|
||||
'updated_at' => 'datetime:Y-m-d H:i:s',
|
||||
'active_status' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
14
app/Process/WhfConsumerProcess.php
Normal file
14
app/Process/WhfConsumerProcess.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Process;
|
||||
|
||||
use Hyperf\AsyncQueue\Process\ConsumerProcess;
|
||||
use Hyperf\Process\Annotation\Process;
|
||||
|
||||
#[Process(name: 'async-queue')]
|
||||
class WhfConsumerProcess extends ConsumerProcess
|
||||
{
|
||||
protected string $queue = 'whf';
|
||||
}
|
64
app/Repository/Company/CompanyModulesRepository.php
Normal file
64
app/Repository/Company/CompanyModulesRepository.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/10
|
||||
* Time: 下午9:10
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository\Company;
|
||||
|
||||
use App\Dao\Company\CompanyModulesDao;
|
||||
use App\Repository\AbstractRepository;
|
||||
|
||||
class CompanyModulesRepository extends AbstractRepository
|
||||
{
|
||||
public function __construct(CompanyModulesDao $dao)
|
||||
{
|
||||
$this->dao = $dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* 公司功能模块列表.
|
||||
*/
|
||||
public function codeList(int $company_id): array
|
||||
{
|
||||
$query = $this->dao->builder()->where('company_id', '=', $company_id);
|
||||
$role_permission_code = [];
|
||||
$data_permission_code = [];
|
||||
if (!$query->exists()) {
|
||||
return compact('role_permission_code', 'data_permission_code');
|
||||
}
|
||||
$info = $query->first(['module_code', 'module_data_permissions'])->toArray();
|
||||
$role_permission_code = $info['module_code'];
|
||||
$data_permission_code = $info['module_data_permissions'];
|
||||
return compact('role_permission_code', 'data_permission_code');
|
||||
}
|
||||
|
||||
/**
|
||||
* 公司功能模块分配.
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function addModule(array $data): array
|
||||
{
|
||||
$query = $this->dao->builder();
|
||||
|
||||
$params = [];
|
||||
$params['company_id'] = $data['company_id'];
|
||||
$params['module_code'] = $data['menu_permission'];
|
||||
$params['module_data_permissions'] = mergePermissions($data['data_permission'] ?? []);
|
||||
$query->updateOrCreate([
|
||||
'company_id' => $params['company_id'],
|
||||
], $params);
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ declare(strict_types=1);
|
||||
namespace App\Repository\Company;
|
||||
|
||||
use App\Dao\Company\FirstCompanyDao;
|
||||
use App\Exception\ApiException;
|
||||
use App\Repository\AbstractRepository;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
@ -99,13 +100,31 @@ class FirstCompanyRepository extends AbstractRepository
|
||||
/**
|
||||
* 根据公司全称获取公司信息.
|
||||
* @param string $fullName
|
||||
* @param bool $isVerify
|
||||
* @return array|null
|
||||
*/
|
||||
public function getCompanyByFullName(string $fullName): ?array
|
||||
public function getCompanyByFullName(string $fullName, bool $isVerify = true): ?array
|
||||
{
|
||||
return $this->dao->builder()
|
||||
->select($this->dao->getFields())
|
||||
->where('full_name', '=', $fullName)
|
||||
->first()?->toArray();
|
||||
$fields = $this->dao->getFields();
|
||||
$query = $this->dao->builder()->select($fields)->where('full_name', '=', $fullName);
|
||||
$company = $query->first();
|
||||
if (!$company && $isVerify) {
|
||||
throw new ApiException('公司不存在');
|
||||
}
|
||||
return $company?->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据公司ID查询公司信息.
|
||||
*/
|
||||
public function getCompanyById(int $companyId, bool $isVerify = true): array
|
||||
{
|
||||
$fields = $this->dao->getFields();
|
||||
$query = $this->dao->builder()->select($fields)->where('id', $companyId);
|
||||
$company = $query->first()?->toArray();
|
||||
if (!$company && $isVerify) {
|
||||
throw new ApiException('公司不存在');
|
||||
}
|
||||
return $company ?? [];
|
||||
}
|
||||
}
|
@ -24,6 +24,26 @@ class RoleRequest extends AbstractRequest
|
||||
'active_status',
|
||||
'sort',
|
||||
],
|
||||
'disableRoles' => ['id' => 'required|integer|min:1', 'status'],
|
||||
'delRoles' => ['ids'],
|
||||
'assignUserRoles' => ['user_id', 'role_ids', 'role_ids.*'],
|
||||
'assignRolePermissions' => [
|
||||
'role_id',
|
||||
'menu_permission',
|
||||
'menu_permission.*',
|
||||
'data_permission',
|
||||
'data_permission.*',
|
||||
'data_permission.*.*',
|
||||
],
|
||||
'roleChecked' => ['role_id'],
|
||||
'addCompanyModule' => [
|
||||
'company_id',
|
||||
'menu_permission',
|
||||
'menu_permission.*',
|
||||
'data_permission',
|
||||
'data_permission.*',
|
||||
],
|
||||
'companyChecked' => ['company_id']
|
||||
];
|
||||
|
||||
public function rules(): array
|
||||
@ -33,6 +53,19 @@ class RoleRequest extends AbstractRequest
|
||||
'role_name' => 'required|string',
|
||||
'active_status' => 'required|integer',
|
||||
'sort' => 'required|integer',
|
||||
'status' => 'required|boolean',
|
||||
'ids' => 'required|array|min:1',
|
||||
'ids.*' => 'required|integer|min:1|distinct',
|
||||
'user_id' => 'required|integer|min:1',
|
||||
'role_ids' => 'required|array|min:1',
|
||||
'role_ids.*' => 'required|integer|min:1|distinct',
|
||||
'role_id' => 'required|integer|min:1',
|
||||
'menu_permission' => 'required|array|min:1',
|
||||
'menu_permission.*' => 'required|string|max:128|distinct',
|
||||
'data_permission' => 'array|min:1',
|
||||
'data_permission.*' => 'required|array|min:1',
|
||||
'data_permission.*.*' => 'required|array|min:1|distinct',
|
||||
'company_id' => 'required|integer|integer|min:1',
|
||||
];
|
||||
}
|
||||
|
||||
@ -43,6 +76,18 @@ class RoleRequest extends AbstractRequest
|
||||
'role_name' => '角色名称',
|
||||
'active_status' => '角色状态',
|
||||
'sort' => '排序',
|
||||
'status' => '状态',
|
||||
'ids' => '角色列表',
|
||||
'ids.*' => '角色列表ID',
|
||||
'role_ids' => '角色列表',
|
||||
'role_ids.*' => '角色列表ID',
|
||||
'user_id' => '用户ID',
|
||||
'menu_permission' => '菜单权限集',
|
||||
'menu_permission.*' => '菜单权限',
|
||||
'data_permission' => '数据权限',
|
||||
'data_permission.*' => '数据菜单权限',
|
||||
'data_permission.*.*' => '数据权限集',
|
||||
'company_id' => '公司ID',
|
||||
];
|
||||
}
|
||||
}
|
@ -37,7 +37,8 @@ class UserRequest extends AbstractRequest
|
||||
'getUserList' => [
|
||||
'page', // 页码
|
||||
'pageSize', // 页大小
|
||||
]
|
||||
],
|
||||
'userLogout' => ['refresh_token']
|
||||
];
|
||||
|
||||
public function rules(): array
|
||||
@ -58,6 +59,7 @@ class UserRequest extends AbstractRequest
|
||||
'role_ids.*' => 'integer|min:1|distinct',
|
||||
'page' => 'integer|min:1',
|
||||
'pageSize' => 'integer|min:1',
|
||||
'refresh_token' => 'required|string|max:1024'
|
||||
];
|
||||
}
|
||||
|
||||
@ -79,6 +81,7 @@ class UserRequest extends AbstractRequest
|
||||
'role_ids.*' => '角色ID',
|
||||
'page' => '页码',
|
||||
'pageSize' => '页大小',
|
||||
'refresh_token' => '刷新令牌',
|
||||
];
|
||||
}
|
||||
}
|
288
app/Service/PermissionService.php
Normal file
288
app/Service/PermissionService.php
Normal file
@ -0,0 +1,288 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/7/10
|
||||
* Time: 下午5:17
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Constants\RoleTypeConst;
|
||||
use App\Context\UserContext;
|
||||
use App\Exception\ApiException;
|
||||
use App\Repository\Company\CompanyModulesRepository;
|
||||
use Exception;
|
||||
use Hyperf\Config\Annotation\Value;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use function Hyperf\Collection\collect;
|
||||
|
||||
class PermissionService
|
||||
{
|
||||
#[Value('menu.data_permissions')]
|
||||
protected array $dataPermissions;
|
||||
|
||||
// 跳过验证的菜单
|
||||
#[Value('menu.ignore_menu')]
|
||||
protected array $ignoreMenu;
|
||||
|
||||
#[Inject]
|
||||
protected CompanyModulesRepository $companyModulesRepository;
|
||||
|
||||
#[Inject]
|
||||
protected SysService $sysService;
|
||||
|
||||
#[Inject]
|
||||
protected RelatedInfo $relatedInfo;
|
||||
|
||||
/**
|
||||
* 验证用户是否有权限执行当前操作.
|
||||
*
|
||||
* @param ServerRequestInterface $request 表示当前的服务器请求
|
||||
* @return bool 如果用户有权限,则返回true;否则返回false
|
||||
* @throws Exception 如果用户没有登录,则抛出一个异常
|
||||
*/
|
||||
public function verifyUserPermission(ServerRequestInterface $request): bool
|
||||
{
|
||||
$user = UserContext::getCurrentUser();
|
||||
|
||||
return match ($user['role_type']) {
|
||||
RoleTypeConst::SUPER_ADMIN => true,
|
||||
RoleTypeConst::ADMIN => $this->sysService->verifyPlatformAdmin($user, $request),
|
||||
default => $this->checkUserRequestPermission($user, $request),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $user
|
||||
* @param ServerRequestInterface $request
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function checkUserRequestPermission(array $user, ServerRequestInterface $request): bool
|
||||
{
|
||||
$method = $this->sysService->method($request);
|
||||
if (!$method) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dataPermissions = $this->sysService->dataPermissions($user);
|
||||
$actions = array_column($dataPermissions, 'actions');
|
||||
$roleActions = $this->sysService->roleAction($user);
|
||||
|
||||
return in_array($method, $roleActions, true) || in_array($method, $actions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回权限选中列表。
|
||||
* 根据提供的权限码和菜单数据,检查并返回用户有权限访问的菜单树。
|
||||
*
|
||||
* @param array $permissionCode 包含角色权限码和数据权限码的数组。
|
||||
* 'role_permission_code' 键包含角色的权限码,
|
||||
* 'data_permission_code' 键包含数据权限的详情(如果有的话)。
|
||||
* @return array 返回经过权限检查后的菜单树
|
||||
*/
|
||||
public function checkMenu(array $permissionCode): array
|
||||
{
|
||||
$user = UserContext::getCurrentUser();
|
||||
|
||||
$menu = match ($user['role_type']) {
|
||||
RoleTypeConst::SUPER_ADMIN => $this->adminMenu()['menu'],
|
||||
RoleTypeConst::ADMIN => $this->platformAdminMenu()['menu'],
|
||||
default => $this->userMenu($user)['menu'],
|
||||
};
|
||||
|
||||
$menuList = treeToList($menu);
|
||||
|
||||
$menuPermissions = $permissionCode['role_permission_code'] ?? [];
|
||||
$dataPermissions = collect($permissionCode['data_permission_code'] ?? [])
|
||||
->pluck('actions')
|
||||
->toArray();
|
||||
|
||||
checkPermissions($menuList, $menuPermissions, $dataPermissions);
|
||||
|
||||
return listToTree($menuList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户的权限列表。
|
||||
*
|
||||
* @param mixed $user 用户信息,预期包含is_admin和is_platform字段来区分用户类型
|
||||
* @return array 返回一个包含菜单权限 menu_permissions 和数据权限 data_permissions 的数组
|
||||
*/
|
||||
public function myPermissions(mixed $user): array
|
||||
{
|
||||
return match ($user['role_type']) {
|
||||
RoleTypeConst::SUPER_ADMIN => $this->formatPermissions($this->adminMenu()['permissions']),
|
||||
RoleTypeConst::ADMIN => $this->formatPermissions($this->platformAdminMenu()['permissions']),
|
||||
default => [
|
||||
'menu_permissions' => $this->sysService->menuPermissions($user),
|
||||
'data_permissions' => $this->sysService->dataPermissions($user),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
protected function formatPermissions(array $permissions): array
|
||||
{
|
||||
return [
|
||||
'menu_permissions' => $permissions['menu_permissions'],
|
||||
'data_permissions' => mergePermissions($permissions['data_permissions']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取超级管理员的菜单和权限配置。
|
||||
* 该函数不接受任何参数。
|
||||
*
|
||||
* @return array 返回一个包含菜单结构和权限信息的数组。
|
||||
* 其中' menu'键包含经过树化处理的菜单结构,
|
||||
* 'permissions'键包含两个子项:'menu_permissions'和'data_permissions'。
|
||||
* 'menu_permissions'表示菜单权限代码数组,
|
||||
* 'data_permissions'表示数据权限数组。
|
||||
*/
|
||||
public function adminMenu(): array
|
||||
{
|
||||
$menu = (new SysService())->getDefaultMenu();
|
||||
$menu_permissions = collect($menu)->pluck('meta.code')->toArray();
|
||||
$data_permissions = array_values($this->dataPermissions);
|
||||
|
||||
return [
|
||||
'menu' => listToTree($menu),
|
||||
'permissions' => compact('menu_permissions', 'data_permissions'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成公司管理员的功能菜单模块.
|
||||
*
|
||||
* 根据提供的模块代码数组,筛选出对应菜单项,并将其转换为树状结构,同时返回菜单项的权限信息。
|
||||
*
|
||||
* @return array 返回一个包含菜单树结构和权限信息的数组
|
||||
*/
|
||||
public function platformAdminMenu(): array
|
||||
{
|
||||
$user = UserContext::getCurrentUser();
|
||||
if (empty($user)) {
|
||||
throw new ApiException('当前用户信息获取失败');
|
||||
}
|
||||
|
||||
$companyModule = $this->companyModulesRepository->codeList($user['company']['id']);
|
||||
$moduleCode = $companyModule['role_permission_code'];
|
||||
$company_data_permissions = array_column($companyModule['data_permission_code'] ?? [], 'actions');
|
||||
|
||||
// 获取系统默认菜单
|
||||
$menu = (new SysService())->getDefaultMenu();
|
||||
$filteredMenu = $this->checkSysMenu($menu, $moduleCode);
|
||||
|
||||
// 筛选出当前模块代码对应的菜单项,并提取出菜单代码
|
||||
$menu_permissions = collect($filteredMenu)->pluck('meta.code')->toArray();
|
||||
|
||||
// 获取数据权限
|
||||
$data_permission = $this->dataPermissions;
|
||||
|
||||
// 将数据权限整理为键值对形式的数组
|
||||
$data_permissions = [];
|
||||
foreach ($data_permission as $value) {
|
||||
$value = collect($value)->whereIn('actions', $company_data_permissions)->values()->toArray();
|
||||
if (empty($value)) {
|
||||
continue;
|
||||
}
|
||||
$data_permissions[] = $value;
|
||||
}
|
||||
|
||||
// 返回处理后的菜单树和权限信息
|
||||
return [
|
||||
'menu' => listToTree($filteredMenu), // 转换菜单项为树状结构
|
||||
'permissions' => compact('menu_permissions', 'data_permissions'), // 权限信息
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户角色获取普通用户菜单权限。
|
||||
*
|
||||
* @param mixed $user 用户信息,预期为包含角色权限信息的对象
|
||||
* @return array 返回包含菜单结构和权限信息的数组。
|
||||
* 其中:
|
||||
* - 'menu' 键包含经过树化处理的菜单结构。
|
||||
* - 'permissions' 键包含两个子项:
|
||||
* - 'menu_permissions' 用户的角色菜单权限代码集合。
|
||||
* - 'data_permissions' 用户的数据权限信息。
|
||||
*/
|
||||
public function userMenu(mixed $user): array
|
||||
{
|
||||
$rolePermissions = $this->relatedInfo->getRolePermissions($user['id']);
|
||||
$data_permissions = collect($this->relatedInfo->dataPermissions($user['id']))->pluck('data_permissions')->toArray();
|
||||
|
||||
$menu_permissions = array_unique(array_merge(
|
||||
collect($rolePermissions)->pluck('role_permission_code')->collapse()->unique()->values()->toArray(),
|
||||
$this->ignoreMenu
|
||||
));
|
||||
|
||||
$menu = (new SysService())->getDefaultMenu();
|
||||
$filteredMenu = $this->checkSysMenu($menu, $menu_permissions);
|
||||
|
||||
return [
|
||||
'menu' => listToTree($filteredMenu),
|
||||
'permissions' => compact('menu_permissions', 'data_permissions'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并处理权限CODE。
|
||||
* 该函数接收一个包含菜单信息的参数,并从中提取权限码,然后合并这些权限码。
|
||||
*
|
||||
* @param mixed $menu 包含菜单权限和数据权限信息的数组或对象
|
||||
* @return array 返回一个包含角色权限码和数据权限码的关联数组
|
||||
*/
|
||||
public function mergeCode(mixed $menu): array
|
||||
{
|
||||
// 提取菜单权限码
|
||||
$role_permission_code = $menu['menu_permissions'] ?? [];
|
||||
// 提取数据权限码
|
||||
$data_permissions = $menu['data_permissions'] ?? [];
|
||||
$data_permission_code = [];
|
||||
foreach ($data_permissions as $value) {
|
||||
$data_permission_code[] = $value; // 将数据权限码添加到数组中
|
||||
}
|
||||
// 合并数据权限码
|
||||
$data_permission_code = mergePermissions($data_permission_code);
|
||||
// 返回合并后的权限码
|
||||
return compact('role_permission_code', 'data_permission_code');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的菜单权限。
|
||||
* 该函数接收一个用户信息数组作为参数,并返回该用户的菜单权限。
|
||||
*
|
||||
* @param array $user 用户信息数组
|
||||
* @return array 返回用户的菜单权限。
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getMenuByUserType(array $user): array
|
||||
{
|
||||
return match (true) {
|
||||
$user['role_type'] === RoleTypeConst::SUPER_ADMIN => $this->adminMenu(),
|
||||
$user['role_type'] === RoleTypeConst::ADMIN => $this->platformAdminMenu(),
|
||||
default => $this->userMenu($user),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 筛选出当前模块代码对应的菜单项,转换为数组。
|
||||
*/
|
||||
public function checkSysMenu(array $menu, array $module_code): array
|
||||
{
|
||||
// 非平台用户的菜单筛选
|
||||
return collect($menu)
|
||||
->whereIn('meta.code', $module_code)
|
||||
->toArray();
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Context\ApiUrlContext;
|
||||
use App\Context\UserContext;
|
||||
use App\Job\ColumnConfigJob;
|
||||
use App\Job\OpLogsJob;
|
||||
@ -60,6 +61,10 @@ class QueueService
|
||||
// 将当前用户信息添加到参数中
|
||||
$params['user'] = UserContext::getCurrentUser();
|
||||
|
||||
if (ApiUrlContext::hasApiUrl()) {
|
||||
$params['api_url'] = ApiUrlContext::getApiUrl();
|
||||
}
|
||||
|
||||
$this->params = $params;
|
||||
return $this;
|
||||
}
|
||||
|
104
app/Service/RelatedInfo.php
Normal file
104
app/Service/RelatedInfo.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* Author: ykxiao
|
||||
* Date: 2025/6/8
|
||||
* Time: 上午11:01
|
||||
* Description:
|
||||
*
|
||||
* (c) ykxiao <yk_9001@hotmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\JsonRpc\RoleServiceInterface;
|
||||
use App\Repository\Company\FirstCompanyRepository;
|
||||
use Hyperf\Collection\Collection;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use function Hyperf\Collection\collect;
|
||||
|
||||
class RelatedInfo
|
||||
{
|
||||
#[Inject]
|
||||
protected RoleServiceInterface $roleServiceInterface;
|
||||
|
||||
#[Inject]
|
||||
protected FirstCompanyRepository $firstCompanyRepository;
|
||||
|
||||
/**
|
||||
* 用户角色关联.
|
||||
* @param int $uid 用户ID
|
||||
* @return array 用户角色关联信息
|
||||
*/
|
||||
public function userRoles(int $uid): array
|
||||
{
|
||||
$data = [
|
||||
'user_id' => $uid,
|
||||
];
|
||||
|
||||
$rpcResult = $this->roleServiceInterface->getUserRoleInfo($data);
|
||||
return $rpcResult['result'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 公司信息关联.
|
||||
* @param string $companyName 公司名称
|
||||
* @return array|null 公司信息关联信息
|
||||
*/
|
||||
public function companyInfo(string $companyName): ?array
|
||||
{
|
||||
return $this->firstCompanyRepository->getCompanyByFullName($companyName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 公司信息关联.
|
||||
* @param int $companyId
|
||||
* @return array
|
||||
*/
|
||||
public function companyInfoById(int $companyId): array
|
||||
{
|
||||
return $this->firstCompanyRepository->getCompanyById($companyId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户角色权限.
|
||||
* @param int $uid 用户ID
|
||||
* @return Collection 角色权限集合
|
||||
*/
|
||||
public function getRolePermissions(int $uid): Collection
|
||||
{
|
||||
// 获取用户角色表中的 role_ids 数组
|
||||
$roleIds = static::userRoles($uid)['role_ids_info'] ?? [];
|
||||
$userRolesIds = array_keys($roleIds);
|
||||
|
||||
$data = [
|
||||
'role_ids' => $userRolesIds
|
||||
];
|
||||
// 通过数组中的 role_id 查找对应的角色权限
|
||||
|
||||
$rpcResult = $this->roleServiceInterface->getRolePermissionSetByRoleIds($data);
|
||||
$res = $rpcResult['result'] ?? [];
|
||||
|
||||
return collect($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户数据权限关联.
|
||||
* @param int $uid 用户ID
|
||||
* @return array 数据权限信息
|
||||
* @return array
|
||||
*/
|
||||
public function dataPermissions(int $uid): array
|
||||
{
|
||||
$data = [
|
||||
'user_id' => $uid,
|
||||
];
|
||||
|
||||
$rpcResult = $this->roleServiceInterface->getUserDataPermissions($data);
|
||||
return $rpcResult['result'] ?? [];
|
||||
}
|
||||
}
|
@ -15,7 +15,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Repository\Company\CompanyModulesRepository;
|
||||
use Hyperf\Config\Annotation\Value;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Router\Dispatched;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use function Hyperf\Collection\collect;
|
||||
|
||||
/**
|
||||
* Author: ykxiao
|
||||
@ -30,6 +35,104 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
*/
|
||||
class SysService
|
||||
{
|
||||
#[Inject]
|
||||
protected RelatedInfo $relatedInfo;
|
||||
|
||||
#[Inject]
|
||||
protected CompanyModulesRepository $companyModulesRepository;
|
||||
|
||||
#[Value('menu.menu')]
|
||||
protected array $menu;
|
||||
|
||||
#[Value('menu.data_permissions')]
|
||||
protected array $dataPermissions;
|
||||
|
||||
public function getDefaultMenu(): array
|
||||
{
|
||||
$list = treeToList($this->menu);
|
||||
foreach ($list as $item => $value) {
|
||||
$code = $value['meta']['code'];
|
||||
$value['meta']['data_permission'] = [];
|
||||
if (array_key_exists($code, $this->dataPermissions)) {
|
||||
$value['meta']['data_permission'] = $this->dataPermissions[$code];
|
||||
}
|
||||
$list[$item] = $value;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前方法名
|
||||
* @param ServerRequestInterface $request
|
||||
* @return string
|
||||
*/
|
||||
public function method(ServerRequestInterface $request): string
|
||||
{
|
||||
$dispatched = $request->getAttribute(Dispatched::class);
|
||||
|
||||
$method = null;
|
||||
if ($dispatched instanceof Dispatched) {
|
||||
$handler = $dispatched->handler->callback ?? null;
|
||||
if ($handler) {
|
||||
$method = $handler[1];
|
||||
}
|
||||
}
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的角色权限。
|
||||
* @param array $user
|
||||
* @return array
|
||||
*/
|
||||
public function roleAction(array $user): array
|
||||
{
|
||||
// 获取用户角色拥有的菜单权限
|
||||
$default_menu = (new SysService())->getDefaultMenu();
|
||||
return collect($default_menu)
|
||||
->whereIn('meta.code', $this->menuPermissions($user))
|
||||
->pluck('actions')
|
||||
->collapse()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的菜单权限。
|
||||
*
|
||||
* @param mixed $user 用户信息,预期包含用户ID
|
||||
* @return array 返回一个包含用户所有菜单权限的数组
|
||||
*/
|
||||
public function menuPermissions(mixed $user): array
|
||||
{
|
||||
// 获取用户角色的所有权限
|
||||
$role_permissions = $this->relatedInfo->getRolePermissions($user['id']);
|
||||
|
||||
// 收集角色权限码,去除重复,转换为数组格式后返回
|
||||
return $role_permissions
|
||||
->pluck('role_permission_code')
|
||||
->collapse()
|
||||
->unique()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单权限。
|
||||
* 该函数用于获取指定用户的菜单权限。
|
||||
*
|
||||
* @param mixed $user 用户信息,预期为包含用户ID的数组或对象
|
||||
* @return array 返回一个包含用户菜单权限动作的数组
|
||||
*/
|
||||
public function dataPermissions(mixed $user): array
|
||||
{
|
||||
$dataPermissions = $this->relatedInfo->dataPermissions($user['id']);
|
||||
|
||||
// 获取并转换用户的所有数据权限
|
||||
return collect($dataPermissions)
|
||||
->pluck('data_permissions')
|
||||
->collapse()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端IP信息
|
||||
* @param ServerRequestInterface $request
|
||||
@ -45,4 +148,31 @@ class SysService
|
||||
|
||||
return $clientIP ?: '127.0.0.1';
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证平台管理员权限。
|
||||
*/
|
||||
public function verifyPlatformAdmin(mixed $user, mixed $request): bool
|
||||
{
|
||||
$companyInfo = $user['company_info'];
|
||||
$module = $this->companyModulesRepository->codeList($companyInfo['id']);
|
||||
|
||||
// 菜单权限
|
||||
$default_menu = (new SysService())->getDefaultMenu();
|
||||
$role_permissions_result = collect($default_menu)
|
||||
->whereIn('meta.code', $module['role_permission_code'])
|
||||
->flatMap(fn($item) => $item['actions'])
|
||||
->toArray();
|
||||
|
||||
$data_permissions_result = collect($module['data_permission_code'])
|
||||
->pluck('actions')
|
||||
->toArray();
|
||||
|
||||
$method = $this->method($request);
|
||||
if ($method) {
|
||||
return in_array($method, $role_permissions_result, true) || in_array($method, $data_permissions_result, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -57,7 +57,9 @@
|
||||
"psr-4": {
|
||||
"App\\": "app/"
|
||||
},
|
||||
"files": []
|
||||
"files": [
|
||||
"app/Helpers/functions.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
|
651
composer.lock
generated
651
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@ return [
|
||||
'redis' => [
|
||||
'pool' => 'default',
|
||||
],
|
||||
'channel' => '{queue}',
|
||||
'channel' => '{default}',
|
||||
'timeout' => 2,
|
||||
'retry_seconds' => 5,
|
||||
'handle_timeout' => 10,
|
||||
@ -33,7 +33,7 @@ return [
|
||||
'redis' => [
|
||||
'pool' => 'default',
|
||||
],
|
||||
'channel' => '{drp.custom}',
|
||||
'channel' => '{queue:whf}',
|
||||
'timeout' => 2,
|
||||
'retry_seconds' => 5,
|
||||
'handle_timeout' => 10,
|
||||
|
@ -14,6 +14,8 @@ use App\JsonRpc\EasyAppServiceConsumer;
|
||||
use App\JsonRpc\EasyAppServiceInterface;
|
||||
use App\JsonRpc\InventoryServiceConsumer;
|
||||
use App\JsonRpc\InventoryServiceInterface;
|
||||
use App\JsonRpc\RoleServiceConsumer;
|
||||
use App\JsonRpc\RoleServiceInterface;
|
||||
use App\JsonRpc\UserAuthServiceConsumer;
|
||||
use App\JsonRpc\UserAuthServiceInterface;
|
||||
use App\Log\StdoutLoggerFactory;
|
||||
@ -24,4 +26,5 @@ return [
|
||||
UserAuthServiceInterface::class => UserAuthServiceConsumer::class,
|
||||
EasyAppServiceInterface::class => EasyAppServiceConsumer::class,
|
||||
InventoryServiceInterface::class => InventoryServiceConsumer::class,
|
||||
RoleServiceInterface::class => RoleServiceConsumer::class,
|
||||
];
|
||||
|
@ -18,5 +18,30 @@ return [
|
||||
'id' => 1,
|
||||
'action' => 'UserController@userLogin',
|
||||
'name' => '用户登录',
|
||||
]
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'action' => 'UserController@userLogout',
|
||||
'name' => '用户登出',
|
||||
],
|
||||
[
|
||||
'id' => 3,
|
||||
'action' => 'RoleController@disableRoles',
|
||||
'name' => '禁用|启用角色',
|
||||
],
|
||||
[
|
||||
'id' => 4,
|
||||
'action' => 'RoleController@delRoles',
|
||||
'name' => '删除角色',
|
||||
],
|
||||
[
|
||||
'id' => 5,
|
||||
'action' => 'RoleController@addCompanyModule',
|
||||
'name' => '公司授权',
|
||||
],
|
||||
[
|
||||
'id' => 6,
|
||||
'action' => 'RoleController@assignRolePermissions',
|
||||
'name' => '角色授权',
|
||||
],
|
||||
];
|
@ -14,6 +14,7 @@ use Hyperf\HttpServer\Server;
|
||||
use Hyperf\Server\Event;
|
||||
use Hyperf\Server\ServerInterface;
|
||||
use Swoole\Constant;
|
||||
use function Hyperf\Support\env;
|
||||
|
||||
return [
|
||||
'mode' => SWOOLE_PROCESS,
|
||||
@ -22,7 +23,7 @@ return [
|
||||
'name' => 'http',
|
||||
'type' => ServerInterface::SERVER_HTTP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9501,
|
||||
'port' => intval(env('HTTP_PORT', 9501)),
|
||||
'sock_type' => SWOOLE_SOCK_TCP,
|
||||
'callbacks' => [
|
||||
Event::ON_REQUEST => [Server::class, 'onRequest'],
|
||||
|
@ -13,6 +13,7 @@ declare(strict_types=1);
|
||||
|
||||
use App\JsonRpc\EasyAppServiceInterface;
|
||||
use App\JsonRpc\InventoryServiceInterface;
|
||||
use App\JsonRpc\RoleServiceInterface;
|
||||
use App\JsonRpc\UserAuthServiceInterface;
|
||||
use function Hyperf\Support\value;
|
||||
|
||||
@ -23,6 +24,7 @@ return [
|
||||
'UserAuthService' => UserAuthServiceInterface::class,
|
||||
'EasyAppService' => EasyAppServiceInterface::class,
|
||||
'InventoryService' => InventoryServiceInterface::class,
|
||||
'RoleService' => RoleServiceInterface::class,
|
||||
];
|
||||
foreach ($services as $name => $interface) {
|
||||
$consumers[] = [
|
||||
|
@ -15,8 +15,10 @@ use App\Controller\CompanyController;
|
||||
use App\Controller\FirstCompanyController;
|
||||
use App\Controller\PurchaseController;
|
||||
use App\Controller\RoleController;
|
||||
use App\Controller\SystemController;
|
||||
use App\Controller\UserController;
|
||||
use App\Middleware\CheckTokenMiddleware;
|
||||
use App\Middleware\PermissionVerifyMiddleware;
|
||||
use Hyperf\HttpServer\Router\Router;
|
||||
|
||||
Router::get('/favicon.ico', function () {
|
||||
@ -29,6 +31,14 @@ Router::addGroup('/api/v1/', function () {
|
||||
});
|
||||
|
||||
Router::addGroup('/api/v1', function () {
|
||||
// 需携带 Token 接口
|
||||
Router::addGroup('/', function () {
|
||||
Router::post('user.logout', [UserController::class, 'userLogout']); # 用户登出
|
||||
|
||||
Router::get('menu.list', [SystemController::class, 'menuList']); # 系统菜单列表
|
||||
});
|
||||
|
||||
// 需携带 Token 接口且需验证权限
|
||||
Router::addGroup('/', function () {
|
||||
/**
|
||||
* 用户管理
|
||||
@ -40,7 +50,17 @@ Router::addGroup('/api/v1', function () {
|
||||
/**
|
||||
* 角色管理
|
||||
*/
|
||||
Router::post('role.add', [RoleController::class, 'addRole']); # 获取用户信息
|
||||
Router::post('role.add', [RoleController::class, 'addRole']); # 新增角色
|
||||
Router::post('role.list', [RoleController::class, 'roleList']); # 获取角色列表
|
||||
Router::post('roles.status', [RoleController::class, 'disableRoles']); # 禁用&启用角色
|
||||
Router::post('roles.delete', [RoleController::class, 'delRoles']); # 删除角色
|
||||
Router::post('assign.user.role', [RoleController::class, 'assignUserRoles']); # 分配用户角色
|
||||
Router::post('assign.role.auth', [RoleController::class, 'assignRolePermissions']); # 角色授权
|
||||
Router::post('role.permission.checked', [RoleController::class, 'roleChecked']); # 角色权限选择列表
|
||||
|
||||
// 平台公司管理
|
||||
Router::post('company.module.add', [RoleController::class, 'addCompanyModule']); # 公司模块授权
|
||||
Router::post('company.permission.checked', [RoleController::class, 'companyChecked']); # 公司模块选择列表
|
||||
|
||||
/**
|
||||
* 采购入库管理
|
||||
@ -48,9 +68,13 @@ Router::addGroup('/api/v1', function () {
|
||||
Router::post('purchase.add', [PurchaseController::class, 'addPurchase']); # 新增采购入库单
|
||||
|
||||
/**
|
||||
* 公司管理
|
||||
* 平台管理
|
||||
*/
|
||||
Router::post('company.add.first', [FirstCompanyController::class, 'addFirstCompany']); # 新增平台公司
|
||||
|
||||
/**
|
||||
* 供应商&客户管理
|
||||
*/
|
||||
Router::post('company.add', [CompanyController::class, 'addCompany']); # 新增公司
|
||||
Router::post('company.add.first', [FirstCompanyController::class, 'addFirstCompany']); # 新增平台公司
|
||||
});
|
||||
}, ['middleware' => [PermissionVerifyMiddleware::class]]);
|
||||
}, ['middleware' => [CheckTokenMiddleware::class]]);
|
34
migrations/2025_07_10_154954_create_company_modules_table.php
Executable file
34
migrations/2025_07_10_154954_create_company_modules_table.php
Executable file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use App\Service\MigrateService;
|
||||
use Hyperf\Database\Schema\Schema;
|
||||
use Hyperf\Database\Schema\Blueprint;
|
||||
use Hyperf\Database\Migrations\Migration;
|
||||
|
||||
class CreateCompanyModulesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('company_modules', function (Blueprint $table) {
|
||||
$table->unsignedInteger('id', true);
|
||||
$table->integer('company_id')->default(0)->unsigned()->comment('公司ID');
|
||||
$table->json('module_code')->comment('公司功能模块CODE列表');
|
||||
$table->json('module_data_permissions')->comment('数据权限');
|
||||
MigrateService::migrateCreateInfo($table);
|
||||
$table->comment('公司功能模块管理表');
|
||||
|
||||
$table->index(['company_id'], 'idx_company_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('company_modules');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user