初始化本地仓库

This commit is contained in:
2026-08-31 11:33:59 +08:00
commit 663f74b633
2390 changed files with 402918 additions and 0 deletions
+382
View File
@@ -0,0 +1,382 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\Admin;
use core\base\BaseDao;
use InvalidArgumentException;
class AdminDao extends BaseDao
{
protected function setModel(): string
{
return Admin::class;
}
/**
* 用户详情
*
* @param $id
* @param array|null $field
* @param array|null $with
* @param string $order
* @param array|null $withoutScopes
*
* @return Admin|null
* @throws \Exception
*/
public function get($id, ?array $field = null, ?array $with = [], string $order = '', ?array $withoutScopes = null): Admin|null
{
$query = $this->getModel()->where('id', $id);
// 应用withoutScopes参数
if (!empty($withoutScopes)) {
$this->applyScopeRemoval($query, $withoutScopes);
}
// 添加with关联
$query->with([
'depts' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
},
'posts' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
},
'roles' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
},
]);
// 先获取结果,检查是否为null
$result = $query->first();
// 如果结果为空,直接返回null
if (!$result) {
return null;
}
// 隐藏密码字段
$result->makeHidden(['password']);
// 初始化属性
$result->role_id_list = [];
$result->post_id_list = [];
$result->dept_id = '';
// 处理角色关系
if (!empty($result->roles)) {
$result->role_id_list = $result->roles->pluck('id')->all();
}
// 处理posts关系
if (!empty($result->posts)) {
$result->post_id_list = $result->posts->pluck('id')->all();
}
// 处理depts关系
if (!empty($result->depts) && $result->depts->isNotEmpty()) {
$result->dept_id = $result->depts->first()->id;
}
return $result;
}
/**
* 获取用户列表
*
* @param array $where 查询条件数组(标准格式或三元素数组)
* @param string $field
* @param int $page
* @param int $limit
* @param string $order
* @param array $with
* @param bool $search
* @param array|null $withoutScopes
*
* @return array
* @throws \Exception
*/
public function getList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): array
{
// 初始化部门ID
$deptId = null;
// 兼容两种格式: 标准格式 ['filters' => [...]] 和三元素数组
if (isset($where['filters']) && is_array($where['filters'])) {
// 标准格式: 从filters中查找并移除dept_id条件
foreach ($where['filters'] as $key => $value) {
if ($key === 'dept_id') {
// 解析 dept_id 值
$parts = explode(':', $value, 2);
$deptId = $parts[1] ?? $value;
// 移除这个条件
unset($where['filters'][$key]);
break;
}
}
} else {
// 三元素数组格式: 遍历查找 dept_id 条件
foreach ($where as $index => $condition) {
if (is_array($condition) && count($condition) >= 2) {
$fieldName = $condition[0];
if ($fieldName === 'dept_id') {
$deptId = $condition[count($condition) - 1];
// 移除这个条件
unset($where[$index]);
break;
}
}
}
// 重新索引数组
$where = array_values($where);
}
if (empty($with)) {
$with = ['depts', 'posts', 'roles'];
}
$query = parent::selectModel($where, $field, $page, $limit, $order, $with, $search, $withoutScopes);
// 如果存在deptId条件,则添加关联条件
if (!is_null($deptId)) {
$query->whereHas('depts', function ($q) use ($deptId) {
$q->where('id', $deptId);
});
}
$total = $query->count();
$items = $query->get()->makeHidden(['password', 'backend_setting']);
return [$total, $items];
}
/**
* 获取用户列表-角色id
*
* @param array $where
* @param string $field
* @param int $page
* @param int $limit
* @param array|null $withoutScopes
*
* @return array
* @throws \Exception
*/
public function getUsersListByRoleId(array $where, string $field, int $page, int $limit, ?array $withoutScopes = null): array
{
$roleId = $where['role_id'] ?? null;
if (!$roleId) {
throw new InvalidArgumentException("Role ID is required.");
}
$where['enabled'] = 1;//有效用户
$where['is_super'] = 0;//非顶级管理员
$query = $this->getModel()->with(['roles' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}])
->whereHas('roles', function ($query) use ($roleId) {
$query->where('id', $roleId);
});
$this->applyScopeRemoval($query, $withoutScopes);
if (!empty($where)) {
unset($where['role_id']);
$query->where($where);
}
$total = $query->count();
$items = $query->when($page > 0 && $limit > 0, function ($query) use ($page, $limit) {
return $query->skip(($page - 1) * $limit)->take($limit);
})
->select($field)
->get()
->toArray();
return compact('total', 'items');
}
/**
* 排除角色ID-用户列表
*
* @param array $where
* @param string $field
* @param int $page
* @param int $limit
* @param array|null $withoutScopes
*
* @return array
* @throws \ReflectionException
*/
public function getUsersExcludingRole(array $where, string $field, int $page, int $limit, ?array $withoutScopes = null): array
{
$roleId = $where['role_id'] ?? null;
if (!$roleId) {
throw new InvalidArgumentException("Role ID is required.");
}
$where['enabled'] = 1;//有效用户
$where['is_super'] = 0;//非顶级管理员
// 获取排除的用户ID列表
$sysAdminRoleDao = new AdminRoleDao();
$excludedAdminIds = $sysAdminRoleDao->getColumn(['role_id' => $roleId], 'admin_id');
// 查询构建器
$query = $this->getModel()->whereNotIn('id', $excludedAdminIds)
->with(['roles' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}]);
$this->applyScopeRemoval($query, $withoutScopes);
// 如果有额外的条件,则添加到查询中
if (!empty($where)) {
unset($where['role_id']);
$query->where($where);
}
$total = $query->count();
// 如果没有用户,则返回空结果
if ($total === 0) {
return ['total' => 0, 'items' => []];
}
$items = $query->when($page > 0 && $limit > 0, function ($query) use ($page, $limit) {
return $query->skip(($page - 1) * $limit)->take($limit);
})->select($field)->get()->toArray();
return compact('total', 'items');
}
/**
* @param string|int $id
*
* @return \app\model\system\Admin|null
* @throws \Exception
*/
// public function getAdminById(string|int $id): ?Admin
// {
// $result = $this->getModel()
// ->where('id', $id)
// ->with(['depts', 'posts', 'casbin.roles', 'roles'])
// ->first()
// ->makeHidden(['password', 'backend_setting']);
//
// if ($result) {
// $result->role_id_list = [];
// $result->post_id_list = [];
// $result->dept_id = '';
//
// // 处理 casbin 关系
// if ($result->casbin) {
// $roleIds = $result->casbin->flatMap(function ($item) {
// return $item->roles->pluck('id');
// })->unique()->values()->all();
//
// $result->role_id_list = $roleIds;
// }
//
// // 处理 posts 关系
// if ($result->posts) {
// $result->post_id_list = $result->posts->pluck('id')->all();
// }
//
// // 处理 depts 关系
// if ($result->depts && $result->depts->isNotEmpty()) {
// $result->dept_id = $result->depts->first()->id;
// }
// }
//
// return $result;
// }
/**
* @param string|int $id
* @param array|null $withoutScopes
*
* @return \app\model\system\Admin|null
* @throws \Exception
*/
public function getAdminById(string|int $id, ?array $withoutScopes = null): ?Admin
{
$query = $this->getModel()
->where('id', $id)
->with(['depts' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}, 'posts' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}, 'roles' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}, 'mainInfo']);
// 应用作用域移除
$this->applyScopeRemoval($query, $withoutScopes);
$result = $query->first();
if ($result) {
$result->makeHidden(['password', 'backend_setting']);
$result->role_id_list = [];
$result->post_id_list = [];
$result->dept_id_list = [];
$result->main_dept_id = null;
$result->main_post_id = null;
if (!empty($result->roles)) {
$result->role_id_list = $result->roles->pluck('id')->all();
}
if ($result->posts) {
$result->post_id_list = $result->posts->pluck('id')->all();
}
if ($result->depts && $result->depts->isNotEmpty()) {
$result->dept_id_list = $result->depts->pluck('id')->all();
}
if ($result->mainInfo) {
$result->main_dept_id = $result->mainInfo->main_dept_id;
$result->main_post_id = $result->mainInfo->main_post_id;
}
}
return $result;
}
/**
* 获取用户详情
*
* @param string $name
* @param array|null $withoutScopes
*
* @return \app\model\system\Admin|null
* @throws \Exception
*/
public function getAdminByName(string $name, ?array $withoutScopes = null): ?Admin
{
$query = $this->getModel()
->where('user_name', $name)
->with(['depts' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}, 'posts' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}, 'roles' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}]);
// 应用作用域移除
$this->applyScopeRemoval($query, $withoutScopes);
return $query->first();
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\AdminPost;
use core\base\BaseDao;
class AdminPostDao extends BaseDao
{
protected function setModel(): string
{
return AdminPost::class;
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\AdminRole;
use core\base\BaseDao;
class AdminRoleDao extends BaseDao
{
protected function setModel(): string
{
return AdminRole::class;
}
}
+48
View File
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\Config;
use app\scope\global\AccessPermissionScope;
use core\base\BaseDao;
use Illuminate\Database\Eloquent\Collection;
class ConfigDao extends BaseDao
{
protected function setModel(): string
{
return Config::class;
}
/**
* 获取配置列表
*
* @param array $where
* @param string|array $field
* @param int $page
* @param int $limit
* @param string $order
* @param array $with
* @param bool $search
* @param array|null $withoutScopes
*
* @return Collection|null
* @throws \Exception
*/
public function getList(array $where = [], string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes =null): ?Collection
{
return $this->selectList($where, $field, $page, $limit, $order, $with, $search, $withoutScopes);
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace app\dao\system;
use app\model\system\Feedback;
use core\base\BaseDao;
class FeedbackDao extends BaseDao
{
protected function setModel(): string
{
return Feedback::class;
}
public function getKeywordFields(): array
{
return ['content', 'contact'];
}
public function selectModel(
array $where,
array|string $field = '*',
int $page = 0,
int $limit = 0,
string $order = '',
array $with = [],
bool $search = false,
?array $withoutScopes = null
): \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Pagination\LengthAwarePaginator|null {
return parent::selectModel($where, $field, $page, $limit, $order, ['createds', 'replyAdmin'], $search, $withoutScopes);
}
public function get($id, ?array $field = null, ?array $with = [], string $order = '', ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Model
{
return parent::get($id, $field, ['createds', 'replyAdmin'], $order, $withoutScopes);
}
}
+112
View File
@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\Menu;
use core\base\BaseDao;
use core\exception\handler\BaseException;
use core\exception\handler\CommonException;
/**
* 平台菜单
*
* @author Mr.April
* @since 1.0
*/
class MenuDao extends BaseDao
{
protected function setModel(): string
{
return Menu::class;
}
public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
$order = 'sort';
return parent::selectList($where, $field, $page, $limit, $order, [], $search, $withoutScopes);
}
/**
* @param string $name
* @param bool $force
*
* @return mixed
* @throws \Exception
*/
public function deleteByPlugin(string $name, bool $force = true): mixed
{
$query = $this->getModel()->query();
$query->where('plugin', $name);
if (!$force) {
$query->where('source', 'system');
}
return $query->delete();
}
/**
* 安装菜单项
*
* @param array $menuItems
* @param string $pluginName
* @param string $parentId
* @param string $menuType
*
* @throws \Throwable
*/
public function installMenuItems(array $menuItems, string $pluginName, string $parentId = '', string $menuType = 'admin'): void
{
try {
foreach ($menuItems as $menuItem) {
// 准备菜单数据
$menuData = [
'pid' => $parentId,
'app' => $menuItem['app'] ?? $menuType,
'title' => $menuItem['title'],
'code' => $menuItem['code'],
'level' => $menuItem['level'] ?? null,
'type' => $menuItem['type'],
'sort' => $menuItem['sort'] ?? 0,
'path' => $menuItem['path'] ?? '',
'component' => $menuItem['component'] ?? '',
'redirect' => $menuItem['redirect'] ?? '',
'icon' => $menuItem['icon'] ?? '',
'is_show' => $menuItem['is_show'] ?? 1,
'is_link' => $menuItem['is_link'] ?? 0,
'link_url' => $menuItem['link_url'] ?? null,
'open_type' => $menuItem['open_type'] ?? 0,
'is_cache' => $menuItem['is_cache'] ?? 0,
'is_sync' => $menuItem['is_sync'] ?? 1,
'is_affix' => $menuItem['is_affix'] ?? 0,
'methods' => $menuItem['methods'] ?? 'GET',
'plugin' => $pluginName, // 记录插件名称
'source' => 'system', // 标记为系统源
'created_at' => time(),
'updated_at' => time(),
];
// 创建菜单模型
$menu = new Menu($menuData);
$menu->save();
// 如果有子菜单,递归安装
if (isset($menuItem['children']) && is_array($menuItem['children'])) {
$this->installMenuItems($menuItem['children'], $pluginName, $menu->id, $menuType);
}
}
} catch (\Throwable $e) {
throw new CommonException($e->getMessage(), ['errorCode' => $e->getCode() ?: -1]);
}
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\RecycleBin;
use core\base\BaseDao;
/**
* 回收站
*
* @author Mr.April
* @since 1.0
*/
class RecycleBinDao extends BaseDao
{
protected function setModel(): string
{
return RecycleBin::class;
}
public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
return parent::selectList($where, $field, $page, $limit, $order, ['operate'], $search, $withoutScopes);
}
public function get($id, ?array $field = null, ?array $with = [], string $order = '', ?array $withoutScopes = null): RecycleBin
{
return parent::get($id, ['*'], ['operate'], '', $withoutScopes);
}
}
+180
View File
@@ -0,0 +1,180 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\Role;
use core\base\BaseDao;
/**
*
* 角色
* @author Mr.April
* @since 1.0
*/
class RoleDao extends BaseDao
{
protected function setModel(): string
{
return Role::class;
}
/**
* 通过角色获取菜单
*
* @param array $ids
*
* @return array
* @throws \Exception
*/
public function getMenuIdsByRoleIds(array $ids = []): array
{
if (empty($ids)) {
return [];
}
$where = ['id' => $ids];
return $this->selectList($where, '*', 0, 0, '', ['menus' => function ($query) {
$query->where('enabled', 1);
}], true)->toArray();
}
/**
* 获取角色权限集合-
*
* @return array
* @throws \Exception
* /* 最终结果
* [
* 'roleId1' => [
* 'menu' => [101, 102],
* 'button => [201],
* 'api' => [301, 302]
* ],
* 'roleId2' => [
* 'menu' => [103],
* 'button' => [],
* 'api' => [303]
* ]
* ]
*/
public function getRolePermissions(): array
{
$result = $this->getModel()
->withoutGlobalScope('TenantScope')
->where('enabled', 1)
->with(['menus'])
->orderBy('sort', 'asc')
->get([
"id",
"tenant_id",
"pid",
"name",
"code",
"is_super_admin",
"role_type",
"data_scope",
"enabled",
"sort",
])
->toArray();
// 初始化结构化数组
$rolePermissions = [];
foreach ($result as $role) {
$roleId = $role['id'];
// 初始化当前角色的权限集合
$rolePermissions[$roleId] = [
'id' => $role['id'] ?? '',
'name' => $role['name'] ?? '',
'tenant_id' => $role['tenant_id'] ?? '',
'data_scope' => $role['data_scope'] ?? 1,
'menu' => [],
'button' => [],
'api' => [],
];
// 遍历关联的 menus 数据
if (!empty($role['menus'])) {
foreach ($role['menus'] as $menu) {
switch ($menu['type']) {
case 1:
case 2:
// 类型 1 或 2 是菜单,添加到 menu
$rolePermissions[$roleId]['menu'][] = $menu['id'];
break;
case 3:
// 类型 3 是按钮,添加到 button
$rolePermissions[$roleId]['button'][] = $menu['id'];
break;
case 4:
// 类型 4 是接口,添加到 api
$rolePermissions[$roleId]['api'][] = $menu['id'];
break;
default:
// 未知类型,忽略或记录日志
break;
}
}
}
}
return $rolePermissions ?? [];
}
/**
* 角色列表
*
* @param array $where
* @param string $field
* @param int $page
* @param int $limit
* @param string $order
* @param array $with
* @param bool $search
* @param array|null $withoutScopes
*
* @return \Illuminate\Database\Eloquent\Collection|null
* @throws \Exception
*/
public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
// 不再加载 casbin 关联,使用默认的 with 参数
return parent::selectList($where, $field, $page, $limit, $order, $with, $search, $withoutScopes);
}
/**
* @param int|string $id
* @param string|null $tenantId
*
* @return \app\model\system\Role|null
* @throws \Exception
*/
public function getImplicitPermissionsForRole(int|string $id, string|null $tenantId = null): ?Role
{
// 获取 tenantId,如果未提供且租户功能启用,则从上下文中获取
if (config('tenant.enabled', false) && empty($tenantId)) {
$tenantId = TenantContext::getTenantId();
}
// 构建查询
return $this->getModel()->query()
->withoutGlobalScope('TenantScope')
->where('enabled', 1)
->when($tenantId, function ($query) use ($tenantId) {
$query->where('tenant_id', $tenantId);
})
->with(['permissions'])
->orderBy('sort')
->first();
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\RoleMenu;
use core\base\BaseDao;
/**
*
* 角色菜单
* @author Mr.April
* @since 1.0
*/
class RoleMenuDao extends BaseDao
{
protected function setModel(): string
{
return RoleMenu::class;
}
}
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\RoleScopeDept;
use core\base\BaseDao;
/**
*
* 角色数据权限
* @author Mr.April
* @since 1.0
*/
class RoleScopeDeptDao extends BaseDao
{
protected function setModel(): string
{
return RoleScopeDept::class;
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: http://www.madong.tech
*/
namespace app\dao\system;
use app\model\system\Upload;
use core\base\BaseDao;
/**
* 上传
*
* @author Mr.April
* @since 1.0
*/
class UploadDao extends BaseDao
{
protected function setModel(): string
{
return Upload::class;
}
public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
//重写追加两个关联模型
return parent::selectList($where, $field, $page, $limit, $order, ['createds', 'updateds'], $search, $withoutScopes);
}
}