diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 80bc06d..cbc6484 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -15,6 +15,7 @@ class DatabaseSeeder extends Seeder SysUserSeeder::class, SysDataSeeder::class, SysAgentSeeder::class, + PermissionSeeder::class, ]); } } diff --git a/database/seeders/PermissionSeeder.php b/database/seeders/PermissionSeeder.php new file mode 100644 index 0000000..f999068 --- /dev/null +++ b/database/seeders/PermissionSeeder.php @@ -0,0 +1,501 @@ +delete(); + DB::table('sys_rule')->delete(); + + // 2. 重新填充系统菜单与业务菜单 + $ruleIds = []; + $this->insertNodes($this->menus(), 0, $ruleIds); + + // 3. 全部授权给超级管理员角色(role_id=1) + DB::table('sys_role_rule')->insert(array_map( + static fn (int $ruleId) => ['role_id' => 1, 'rule_id' => $ruleId], + $ruleIds + )); + + $this->command?->info('权限已重建,共 ' . count($ruleIds) . ' 个权限点,已全部授权给超级管理员'); + }); + } + + /** + * 系统框架菜单(仪表盘、示例页面、AI、系统管理等) + */ + private function menus(): array + { + return [ + [ + 'type' => 'menu', + 'name' => '仪表盘', + 'key' => 'dashboard', + 'icon' => 'PieChartOutlined', + 'local' => 'menu.dashboard', + 'children' => [ + [ + 'type' => 'route', + 'name' => '分析页', + 'local' => "menu.analysis", + 'key' => 'dashboard.analysis', + 'path' => '/dashboard/analysis', + ] + ] + ], + [ + 'type' => 'menu', + 'key' => 'procurement.product', + 'name' => '商品中心', + 'icon' => 'ShoppingOutlined', + 'children' => [ + [ + 'type' => 'route', + 'key' => 'product.category', + 'name' => '分类管理', + 'path' => '/product/category', + 'children' => [ + ['type' => 'rule', 'key' => 'product.category.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'product.category.create', 'name' => '新增'], + ['type' => 'rule', 'key' => 'product.category.update', 'name' => '编辑'], + ['type' => 'rule', 'key' => 'product.category.delete', 'name' => '删除'], + ], + ], + [ + 'type' => 'route', + 'key' => 'product.goods', + 'name' => '商品列表', + 'path' => '/product/goods', + 'children' => [ + ['type' => 'rule', 'key' => 'product.goods.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'product.goods.create', 'name' => '新增'], + ['type' => 'rule', 'key' => 'product.goods.update', 'name' => '编辑'], + ['type' => 'rule', 'key' => 'product.goods.delete', 'name' => '删除'], + ['type' => 'rule', 'key' => 'product.goods.batchPrice', 'name' => '批量调价'], + ], + ], + ], + ], + [ + 'type' => 'menu', + 'key' => 'procurement.customer', + 'name' => '客户管理', + 'icon' => 'ShopOutlined', + 'children' => [ + [ + 'type' => 'route', + 'key' => 'customer.store', + 'name' => '门店管理', + 'path' => '/customer/store', + 'children' => [ + ['type' => 'rule', 'key' => 'customer.store.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'customer.store.create', 'name' => '新增'], + ['type' => 'rule', 'key' => 'customer.store.update', 'name' => '编辑'], + ['type' => 'rule', 'key' => 'customer.store.delete', 'name' => '删除'], + ], + ], + [ + 'type' => 'route', + 'key' => 'customer.level', + 'name' => '客户等级', + 'path' => '/customer/level', + 'children' => [ + ['type' => 'rule', 'key' => 'customer.level.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'customer.level.create', 'name' => '新增'], + ['type' => 'rule', 'key' => 'customer.level.update', 'name' => '编辑'], + ['type' => 'rule', 'key' => 'customer.level.delete', 'name' => '删除'], + ], + ], + [ + 'type' => 'route', + 'key' => 'customer.supplier', + 'name' => '供应商', + 'path' => '/customer/supplier', + 'children' => [ + ['type' => 'rule', 'key' => 'customer.supplier.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'customer.supplier.create', 'name' => '新增'], + ['type' => 'rule', 'key' => 'customer.supplier.update', 'name' => '编辑'], + ['type' => 'rule', 'key' => 'customer.supplier.delete', 'name' => '删除'], + ], + ], + [ + 'type' => 'route', + 'key' => 'customer.miniUser', + 'name' => '小程序用户', + 'path' => '/customer/mini-user', + 'children' => [ + ['type' => 'rule', 'key' => 'customer.miniUser.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'customer.miniUser.update', 'name' => '启用停用'], + ['type' => 'rule', 'key' => 'customer.miniUser.bind', 'name' => '绑定主体'], + ], + ], + [ + 'type' => 'route', + 'key' => 'customer.notice', + 'name' => '通知管理', + 'path' => '/customer/notice', + 'children' => [ + ['type' => 'rule', 'key' => 'customer.notice.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'customer.notice.create', 'name' => '发布'], + ['type' => 'rule', 'key' => 'customer.notice.delete', 'name' => '删除'], + ], + ], + ], + ], + [ + 'type' => 'menu', + 'key' => 'procurement.order', + 'name' => '订货管理', + 'icon' => 'FileTextOutlined', + 'children' => [ + [ + 'type' => 'route', + 'key' => 'order.store', + 'name' => '门店订单', + 'path' => '/order/store', + 'children' => [ + ['type' => 'rule', 'key' => 'order.store.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'order.store.update', 'name' => '状态流转'], + ], + ], + ], + ], + [ + 'type' => 'menu', + 'key' => 'procurement.purchase', + 'name' => '采购管理', + 'icon' => 'ShoppingCartOutlined', + 'children' => [ + [ + 'type' => 'route', + 'key' => 'purchase.order', + 'name' => '采购单', + 'path' => '/purchase/order', + 'children' => [ + ['type' => 'rule', 'key' => 'purchase.order.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'purchase.order.update', 'name' => '修改'], + ['type' => 'rule', 'key' => 'purchase.order.generate', 'name' => '生成采购单'], + ['type' => 'rule', 'key' => 'purchase.order.export', 'name' => '导出'], + ['type' => 'rule', 'key' => 'purchase.order.send', 'name' => '发送供应商'], + ['type' => 'rule', 'key' => 'purchase.order.allocate', 'name' => '金额分摊'], + ], + ], + ], + ], + [ + 'type' => 'menu', + 'key' => 'procurement.recon', + 'name' => '对账管理', + 'icon' => 'AccountBookOutlined', + 'children' => [ + [ + 'type' => 'route', + 'key' => 'recon.list', + 'name' => '财务对账', + 'path' => '/recon/list', + 'children' => [ + ['type' => 'rule', 'key' => 'recon.list.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'recon.list.create', 'name' => '新增'], + ['type' => 'rule', 'key' => 'recon.list.update', 'name' => '编辑'], + ['type' => 'rule', 'key' => 'recon.list.delete', 'name' => '删除'], + ['type' => 'rule', 'key' => 'recon.list.build', 'name' => '生成明细'], + ['type' => 'rule', 'key' => 'recon.list.settle', 'name' => '生成结算表'], + // 对账明细操作权限点在独立控制器 recon.item 下(D4/D6/D8) + ['type' => 'rule', 'key' => 'recon.item.item.update', 'name' => '对账明细操作'], + ], + ], + [ + 'type' => 'route', + 'key' => 'recon.statement', + 'name' => '门店对账单', + 'path' => '/recon/statement', + 'children' => [ + ['type' => 'rule', 'key' => 'recon.statement.query', 'name' => '查询'], + ], + ], + [ + 'type' => 'route', + 'key' => 'recon.settlement', + 'name' => '结算表', + 'path' => '/recon/settlement', + 'children' => [ + ['type' => 'rule', 'key' => 'recon.settlement.query', 'name' => '查询'], + ['type' => 'rule', 'key' => 'recon.settlement.download', 'name' => '下载导出'], + ], + ], + ], + ], + [ + 'type' => 'menu', + 'name' => 'AI', + 'local' => "menu.ai", + 'icon' => "OpenAIOutlined", + 'key' => "ai", + 'children' => [ + [ + 'type' => "route", + 'key' => "ai.chat", + 'name' => "AI对话", + "path" => "/ai/chat", + 'local' => "menu.ai.chat", + 'children' => [ + ['type' => 'rule', 'name' => '发送消息', 'key' => 'ai.chat.send'], + ['type' => 'rule', 'name' => '会话列表', 'key' => 'ai.chat.conversations'], + ['type' => 'rule', 'name' => '消息列表', 'key' => 'ai.chat.messages'], + ['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.chat.delete'], + ] + ], + [ + 'type' => "route", + 'key' => "ai.conversation", + 'name' => "会话管理", + "path" => "/ai/conversation", + 'local' => "menu.ai.conversation", + 'children' => [ + ['type' => 'rule', 'name' => '查询会话列表', 'key' => 'ai.conversation.query'], + ['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.conversation.delete'], + ] + ], + [ + 'type' => "route", + 'key' => "ai.agent", + 'name' => "Agent 管理", + "path" => "/ai/agent", + 'local' => "menu.ai.agent", + 'children' => [ + ['type' => 'rule', 'name' => '查询列表', 'key' => 'ai.agent.query'], + ['type' => 'rule', 'name' => '更新 Agent', 'key' => 'ai.agent.update'], + ] + ], + ] + ], + [ + 'type' => "menu", + 'name' => "系统管理", + 'local' => "menu.system", + 'icon' => "SettingOutlined", + 'key' => "system", + 'children' => [ + [ + 'type' => "route", + 'key' => "system.user", + 'name' => "用户管理", + 'path' => "/system/user", + 'local' => "menu.system.user", + 'children' => [ + ['type' => 'rule', 'name' => '查询列表', 'key' => 'system.user.query'], + ['type' => 'rule', 'name' => '新增用户', 'key' => 'system.user.create'], + ['type' => 'rule', 'name' => '修改用户', 'key' => 'system.user.update'], + ['type' => 'rule', 'name' => '删除用户', 'key' => 'system.user.delete'], + ['type' => 'rule', 'name' => '重置用户密码', 'key' => 'system.user.resetPassword'], + ['type' => 'rule', 'name' => '获取角色选项', 'key' => 'system.user.role'], + ['type' => 'rule', 'name' => '获取部门选项', 'key' => 'system.user.dept'], + ] + ], + [ + 'type' => "route", + 'key' => "system.dept", + 'name' => "部门管理", + 'path' => "/system/dept", + 'local' => "menu.system.dept", + 'children' => [ + ['type' => 'rule', 'name' => '获取部门列表', 'key' => 'system.dept.query'], + ['type' => 'rule', 'name' => '新建部门', 'key' => 'system.dept.create'], + ['type' => 'rule', 'name' => '更新部门信息', 'key' => 'system.dept.update'], + ['type' => 'rule', 'name' => '删除部门', 'key' => 'system.dept.delete'], + ['type' => 'rule', 'name' => '获取部门用户', 'key' => 'system.dept.users'], + ] + ], + [ + 'type' => "route", + 'key' => "system.role", + 'name' => "角色管理", + 'path' => "/system/role", + 'local' => "menu.system.role", + 'children' => [ + ['type' => 'rule', 'name' => '新增角色', 'key' => 'system.role.create'], + ['type' => 'rule', 'name' => '查询角色列表', 'key' => 'system.role.query'], + ['type' => 'rule', 'name' => '更新角色信息', 'key' => 'system.role.update'], + ['type' => 'rule', 'name' => '删除角色', 'key' => 'system.role.delete'], + ['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.role.status'], + ['type' => 'rule', 'name' => '获取角色用户', 'key' => 'system.role.users'], + ['type' => 'rule', 'name' => '设置角色权限', 'key' => 'system.role.setRule'], + ['type' => 'rule', 'name' => '获取权限选项', 'key' => 'system.role.ruleList'], + ] + ], + [ + 'type' => "route", + 'key' => "system.rule", + 'name' => "菜单管理", + 'path' => "/system/rule", + 'local' => "menu.system.rule", + 'children' => [ + ['type' => 'rule', 'name' => '获取权限列表', 'key' => 'system.rule.query'], + ['type' => 'rule', 'name' => '创建权限规则', 'key' => 'system.rule.create'], + ['type' => 'rule', 'name' => '更新权限规则', 'key' => 'system.rule.update'], + ['type' => 'rule', 'name' => '删除权限规则', 'key' => 'system.rule.delete'], + ['type' => 'rule', 'name' => '获取父级权限', 'key' => 'system.rule.parentQuery'], + ['type' => 'rule', 'name' => '设置显示状态', 'key' => 'system.rule.show'], + ['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.rule.status'], + ] + ], + [ + 'type' => "route", + 'name' => "文件管理", + 'local' => "menu.system.file", + 'key' => "system.file", + 'path' => "/system/file", + 'children' => [ + ['type' => 'rule', 'name' => '获取文件夹', 'key' => 'system.file.group.query'], + ['type' => 'rule', 'name' => '新增文件夹', 'key' => 'system.file.group.create'], + ['type' => 'rule', 'name' => '编辑文件夹', 'key' => 'system.file.group.update'], + ['type' => 'rule', 'name' => '删除文件夹', 'key' => 'system.file.group.delete'], + ['type' => 'rule', 'name' => '查询文件列表', 'key' => 'system.file.list.query'], + ['type' => 'rule', 'name' => '上传文件', 'key' => 'system.file.list.upload'], + ['type' => 'rule', 'name' => '下载文件', 'key' => 'system.file.list.download'], + ['type' => 'rule', 'name' => '删除文件', 'key' => 'system.file.list.delete'], + ['type' => 'rule', 'name' => '永久删除文件', 'key' => 'system.file.list.force-delete'], + ['type' => 'rule', 'name' => '恢复文件', 'key' => 'system.file.list.restore'], + ['type' => 'rule', 'name' => '查看回收站', 'key' => 'system.file.list.trashed'], + ['type' => 'rule', 'name' => '清空回收站', 'key' => 'system.file.list.clean-trashed'], + ['type' => 'rule', 'name' => '复制文件', 'key' => 'system.file.list.copy'], + ['type' => 'rule', 'name' => '移动文件', 'key' => 'system.file.list.move'], + ['type' => 'rule', 'name' => '重命名文件', 'key' => 'system.file.list.rename'] + ], + ], + [ + 'type' => "route", + 'name' => "系统字典", + 'local' => "menu.system.dict", + 'key' => "system.dict", + 'path' => "/system/dict", + 'children' => [ + ['type' => 'rule', 'name' => '字典列表', 'key' => 'system.dict.list.query'], + ['type' => 'rule', 'name' => '新增字典', 'key' => 'system.dict.list.create'], + ['type' => 'rule', 'name' => '删除字典', 'key' => 'system.dict.list.delete'], + ['type' => 'rule', 'name' => '更新字典', 'key' => 'system.dict.list.update'], + ['type' => 'rule', 'name' => '字典项列表', 'key' => 'system.dict.item.query'], + ['type' => 'rule', 'name' => '字典项新增', 'key' => 'system.dict.item.create'], + ['type' => 'rule', 'name' => '字典项编辑', 'key' => 'system.dict.item.update'], + ['type' => 'rule', 'name' => '字典项删除', 'key' => 'system.dict.item.delete'], + ] + ], + [ + 'type' => "route", + 'name' => "系统配置", + 'local' => "menu.system.config", + 'key' => "system.config", + 'path' => "/system/config", + 'children' => [ + ['type' => 'rule', 'name' => '配置列表', 'key' => 'system.config.items.query'], + ['type' => 'rule', 'name' => '新增配置', 'key' => 'system.config.items.create'], + ['type' => 'rule', 'name' => '编辑配置', 'key' => 'system.config.items.update'], + ['type' => 'rule', 'name' => '删除配置', 'key' => 'system.config.items.delete'], + ['type' => 'rule', 'name' => '保存配置', 'key' => 'system.config.items.save'], + ['type' => 'rule', 'name' => '刷新配置', 'key' => 'system.config.items.refresh'], + ['type' => 'rule', 'name' => '配置组编辑', 'key' => 'system.config.group.update'], + ['type' => 'rule', 'name' => '配置组删除', 'key' => 'system.config.items.item.delete'], + ['type' => 'rule', 'name' => '配置组列表', 'key' => 'system.config.group.query'], + ['type' => 'rule', 'name' => '配置组新增', 'key' => 'system.config.group.create'], + ] + ], + [ + 'type' => 'route', + 'key' => 'system.mail', + 'name' => '邮件配置', + 'path' => '/system/mail', + 'local' => 'menu.system.mail', + 'children' => [ + ['type' => 'rule', 'name' => '获取配置', 'key' => 'system.mail.config'], + ['type' => 'rule', 'name' => '保存配置', 'key' => 'system.mail.save'], + ['type' => 'rule', 'name' => '发送测试', 'key' => 'system.mail.test'], + ] + ], + [ + 'type' => 'route', + 'key' => 'system.storage', + 'name' => '存储配置', + 'path' => '/system/storage', + 'local' => 'menu.system.storage', + 'children' => [ + ['type' => 'rule', 'name' => '获取配置', 'key' => 'system.storage.config'], + ['type' => 'rule', 'name' => '保存配置', 'key' => 'system.storage.save'], + ['type' => 'rule', 'name' => '测试连接', 'key' => 'system.storage.test'], + ] + ], + [ + 'type' => 'route', + 'key' => 'system.ai', + 'name' => 'AI 配置', + 'path' => '/system/ai', + 'local' => 'menu.system.ai', + 'children' => [ + ['type' => 'rule', 'name' => '获取可用AI列表', 'key' => 'system.ai.list'], + ['type' => 'rule', 'name' => '获取AI配置', 'key' => 'system.ai.config'], + ['type' => 'rule', 'name' => '保存AI配置', 'key' => 'system.ai.save'], + ['type' => 'rule', 'name' => '测试连接', 'key' => 'system.ai.test'], + ] + ], + [ + 'type' => "route", + 'name' => "系统信息", + 'local' => "menu.system.info", + 'key' => "system.info", + 'path' => "/system/info", + ] + ] + ] + ]; + } + + /** + * 递归写入菜单节点,收集全部节点 ID(menu/route/rule)用于授权 + * + * @param array> $nodes + * @param array $ruleIds + */ + private function insertNodes(array $nodes, int $parentId, array &$ruleIds): void + { + $now = now(); + $order = 0; + foreach ($nodes as $node) { + $id = DB::table('sys_rule')->insertGetId([ + 'parent_id' => $parentId, + 'type' => $node['type'], + 'key' => $node['key'], + 'name' => $node['name'], + 'path' => $node['path'] ?? '', + 'icon' => $node['icon'] ?? '', + 'order' => $order++, + 'local' => $node['local'] ?? '', + 'status' => 1, + 'hidden' => 1, + 'link' => $node['link'] ?? 0, + 'created_at' => $now, + 'updated_at' => $now, + ]); + $ruleIds[] = $id; + + if (!empty($node['children']) && is_array($node['children'])) { + $this->insertNodes($node['children'], $id, $ruleIds); + } + } + } +} diff --git a/database/seeders/ProcurementSeeder.php b/database/seeders/ProcurementSeeder.php deleted file mode 100644 index 61f5425..0000000 --- a/database/seeders/ProcurementSeeder.php +++ /dev/null @@ -1,276 +0,0 @@ - 'menu', - 'key' => 'procurement.product', - 'name' => '商品中心', - 'icon' => 'ShoppingOutlined', - 'children' => [ - [ - 'type' => 'route', - 'key' => 'product.category', - 'name' => '分类管理', - 'path' => '/product/category', - 'children' => [ - ['type' => 'rule', 'key' => 'product.category.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'product.category.create', 'name' => '新增'], - ['type' => 'rule', 'key' => 'product.category.update', 'name' => '编辑'], - ['type' => 'rule', 'key' => 'product.category.delete', 'name' => '删除'], - ], - ], - [ - 'type' => 'route', - 'key' => 'product.goods', - 'name' => '商品列表', - 'path' => '/product/goods', - 'children' => [ - ['type' => 'rule', 'key' => 'product.goods.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'product.goods.create', 'name' => '新增'], - ['type' => 'rule', 'key' => 'product.goods.update', 'name' => '编辑'], - ['type' => 'rule', 'key' => 'product.goods.delete', 'name' => '删除'], - ['type' => 'rule', 'key' => 'product.goods.batchPrice', 'name' => '批量调价'], - ], - ], - ], - ], - [ - 'type' => 'menu', - 'key' => 'procurement.customer', - 'name' => '客户管理', - 'icon' => 'ShopOutlined', - 'children' => [ - [ - 'type' => 'route', - 'key' => 'customer.store', - 'name' => '门店管理', - 'path' => '/customer/store', - 'children' => [ - ['type' => 'rule', 'key' => 'customer.store.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'customer.store.create', 'name' => '新增'], - ['type' => 'rule', 'key' => 'customer.store.update', 'name' => '编辑'], - ['type' => 'rule', 'key' => 'customer.store.delete', 'name' => '删除'], - ], - ], - [ - 'type' => 'route', - 'key' => 'customer.level', - 'name' => '客户等级', - 'path' => '/customer/level', - 'children' => [ - ['type' => 'rule', 'key' => 'customer.level.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'customer.level.create', 'name' => '新增'], - ['type' => 'rule', 'key' => 'customer.level.update', 'name' => '编辑'], - ['type' => 'rule', 'key' => 'customer.level.delete', 'name' => '删除'], - ], - ], - [ - 'type' => 'route', - 'key' => 'customer.supplier', - 'name' => '供应商', - 'path' => '/customer/supplier', - 'children' => [ - ['type' => 'rule', 'key' => 'customer.supplier.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'customer.supplier.create', 'name' => '新增'], - ['type' => 'rule', 'key' => 'customer.supplier.update', 'name' => '编辑'], - ['type' => 'rule', 'key' => 'customer.supplier.delete', 'name' => '删除'], - ], - ], - [ - 'type' => 'route', - 'key' => 'customer.miniUser', - 'name' => '小程序用户', - 'path' => '/customer/mini-user', - 'children' => [ - ['type' => 'rule', 'key' => 'customer.miniUser.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'customer.miniUser.update', 'name' => '启用停用'], - ['type' => 'rule', 'key' => 'customer.miniUser.bind', 'name' => '绑定主体'], - ], - ], - [ - 'type' => 'route', - 'key' => 'customer.notice', - 'name' => '通知管理', - 'path' => '/customer/notice', - 'children' => [ - ['type' => 'rule', 'key' => 'customer.notice.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'customer.notice.create', 'name' => '发布'], - ['type' => 'rule', 'key' => 'customer.notice.delete', 'name' => '删除'], - ], - ], - ], - ], - [ - 'type' => 'menu', - 'key' => 'procurement.order', - 'name' => '订货管理', - 'icon' => 'FileTextOutlined', - 'children' => [ - [ - 'type' => 'route', - 'key' => 'order.store', - 'name' => '门店订单', - 'path' => '/order/store', - 'children' => [ - ['type' => 'rule', 'key' => 'order.store.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'order.store.update', 'name' => '状态流转'], - ], - ], - ], - ], - [ - 'type' => 'menu', - 'key' => 'procurement.purchase', - 'name' => '采购管理', - 'icon' => 'ShoppingCartOutlined', - 'children' => [ - [ - 'type' => 'route', - 'key' => 'purchase.order', - 'name' => '采购单', - 'path' => '/purchase/order', - 'children' => [ - ['type' => 'rule', 'key' => 'purchase.order.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'purchase.order.update', 'name' => '修改'], - ['type' => 'rule', 'key' => 'purchase.order.generate', 'name' => '生成采购单'], - ['type' => 'rule', 'key' => 'purchase.order.export', 'name' => '导出'], - ['type' => 'rule', 'key' => 'purchase.order.send', 'name' => '发送供应商'], - ['type' => 'rule', 'key' => 'purchase.order.allocate', 'name' => '金额分摊'], - ], - ], - ], - ], - [ - 'type' => 'menu', - 'key' => 'procurement.recon', - 'name' => '对账管理', - 'icon' => 'AccountBookOutlined', - 'children' => [ - [ - 'type' => 'route', - 'key' => 'recon.list', - 'name' => '财务对账', - 'path' => '/recon/list', - 'children' => [ - ['type' => 'rule', 'key' => 'recon.list.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'recon.list.create', 'name' => '新增'], - ['type' => 'rule', 'key' => 'recon.list.update', 'name' => '编辑'], - ['type' => 'rule', 'key' => 'recon.list.delete', 'name' => '删除'], - ['type' => 'rule', 'key' => 'recon.list.build', 'name' => '生成明细'], - ['type' => 'rule', 'key' => 'recon.list.settle', 'name' => '生成结算表'], - // 对账明细操作权限点在独立控制器 recon.item 下(D4/D6/D8) - ['type' => 'rule', 'key' => 'recon.item.item.update', 'name' => '对账明细操作'], - ], - ], - [ - 'type' => 'route', - 'key' => 'recon.statement', - 'name' => '门店对账单', - 'path' => '/recon/statement', - 'children' => [ - ['type' => 'rule', 'key' => 'recon.statement.query', 'name' => '查询'], - ], - ], - [ - 'type' => 'route', - 'key' => 'recon.settlement', - 'name' => '结算表', - 'path' => '/recon/settlement', - 'children' => [ - ['type' => 'rule', 'key' => 'recon.settlement.query', 'name' => '查询'], - ['type' => 'rule', 'key' => 'recon.settlement.download', 'name' => '下载导出'], - ], - ], - ], - ], - ]; - } - - public function run(): void - { - $existing = DB::table('sys_rule') - ->whereIn('key', ['procurement.product', 'procurement.customer', 'procurement.order', 'procurement.purchase', 'procurement.recon']) - ->exists(); - if ($existing) { - $this->command?->warn('业务菜单已存在,跳过 ProcurementSeeder'); - - return; - } - - DB::transaction(function () { - $ruleIds = []; - foreach ($this->menus() as $menu) { - $this->insertNode($menu, 0, $ruleIds); - } - - // 授权给超级管理员角色(role_id=1),去重已存在的关联 - $existingPairs = DB::table('sys_role_rule') - ->where('role_id', 1) - ->whereIn('rule_id', $ruleIds) - ->pluck('rule_id') - ->all(); - $newPairs = array_map( - static fn (int $ruleId) => ['role_id' => 1, 'rule_id' => $ruleId], - array_values(array_diff($ruleIds, $existingPairs)) - ); - if ($newPairs !== []) { - DB::table('sys_role_rule')->insert($newPairs); - } - - $this->command?->info('业务菜单与权限点已写入,共 ' . count($ruleIds) . ' 个权限点已授权给超级管理员'); - }); - } - - /** - * 递归写入菜单节点,收集全部节点 ID(menu/route/rule)用于授权 - * - * @param array $node - * @param array $ruleIds - */ - private function insertNode(array $node, int $parentId, array &$ruleIds): void - { - $now = now(); - $id = DB::table('sys_rule')->insertGetId([ - 'parent_id' => $parentId, - 'type' => $node['type'], - 'key' => $node['key'], - 'name' => $node['name'], - 'path' => $node['path'] ?? '', - 'icon' => $node['icon'] ?? '', - 'order' => 0, - 'local' => '', - 'status' => 1, - 'hidden' => 1, - 'link' => 0, - 'created_at' => $now, - 'updated_at' => $now, - ]); - $ruleIds[] = $id; - - foreach ($node['children'] ?? [] as $child) { - $this->insertNode($child, $id, $ruleIds); - } - } -} diff --git a/database/seeders/SysUserSeeder.php b/database/seeders/SysUserSeeder.php index 315cfe7..bd06f10 100644 --- a/database/seeders/SysUserSeeder.php +++ b/database/seeders/SysUserSeeder.php @@ -11,6 +11,9 @@ class SysUserSeeder extends Seeder { /** * Run the database seeds. + * + * 仅负责用户、角色、部门基础数据; + * 菜单与权限点(sys_rule / sys_role_rule)统一由 PermissionSeeder 维护。 */ public function run(): void { @@ -116,483 +119,12 @@ class SysUserSeeder extends Seeder 'phone' => '19999999999', 'email' => Str::random(10).'@example.com', 'address' => '北京市海淀区人民路666号', - 'remark' => '我们坚信,卓越的投资在于发现价值,而卓越的投资管理在于创造价值。我们立志成为科技创业者身边最懂业务、最能赋能、最长情的资本伙伴,共同将创新的火种,转化为引领行业的参天大树。', + 'remark' => '我们坚信,卓越的投资在于发现价值,而卓越的投资管理在于创造价值。我们立志成为科技创业者身边最懂业务、最能赋能、最长情的资本伙伴。让我们将创新的火种,转化为引领行业的参天大树。', 'created_at' => $date, 'updated_at' => $date ], ]); - $rules = [ - [ - 'type' => 'menu', - 'name' => '仪表盘', - 'key' => 'dashboard', - 'icon' => 'PieChartOutlined', - 'local' => 'menu.dashboard', - 'children' => [ - [ - 'type' => 'route', - 'name' => '分析页', - 'local' => "menu.analysis", - 'key' => 'dashboard.analysis', - 'path' => '/dashboard/analysis', - ], - [ - 'type' => 'route', - 'name' => '监控页', - 'local' => "menu.monitor", - 'key' => 'dashboard.monitor', - 'path' => '/dashboard/monitor', - ], - [ - 'type' => 'route', - 'name' => '工作台', - 'local' => "menu.workplace", - 'key' => 'dashboard.workplace', - 'path' => '/dashboard/workplace', - ] - ] - ], - [ - 'type' => 'menu', - 'name' => '结果页面', - 'key' => 'result', - 'icon' => 'CheckCircleOutlined', - 'local' => 'menu.result', - 'children' => [ - [ - 'type' => 'route', - 'name' => '成功页', - 'local' => "menu.result.success", - 'key' => 'result.success', - 'path' => '/result/success', - ], - [ - 'type' => 'route', - 'name' => '失败页', - 'local' => "menu.result.fail", - 'key' => 'result.fail', - 'path' => '/result/fail', - ], - [ - 'type' => 'route', - 'name' => '警告页', - 'local' => "menu.result.warning", - 'key' => 'result.warning', - 'path' => '/result/warning', - ], - [ - 'type' => 'route', - 'name' => '信息页', - 'local' => "menu.result.info", - 'key' => 'result.info', - 'path' => '/result/info', - ] - ] - ], - [ - 'type' => 'menu', - 'name' => '异常页面', - 'key' => 'exception', - 'icon' => 'AlertOutlined', - 'local' => 'menu.exception', - 'children' => [ - [ - 'type' => 'route', - 'name' => '403', - 'local' => "menu.exception.403", - 'key' => 'exception.403', - 'path' => '/exception/403', - ], - [ - 'type' => 'route', - 'name' => '404', - 'local' => "menu.exception.404", - 'key' => 'exception.404', - 'path' => '/exception/404', - ], - [ - 'type' => 'route', - 'name' => '500', - 'local' => "menu.exception.500", - 'key' => 'exception.500', - 'path' => '/exception/500', - ] - ] - ], - [ - 'type' => 'menu', - 'name' => '多级菜单', - 'key' => 'multi-menu', - 'local' => "menu.multi-menu", - 'icon' => "MenuOutlined", - 'children' => [ - [ - 'type' => 'route', - 'name' => '二级页面', - 'local' => "menu.multi-menu.first", - 'key' => 'multi-menu.first', - 'path' => '/multi-menu/first', - ], - [ - 'type' => 'menu', - 'name' => '二级菜单', - 'local' => "menu.multi-menu.two", - 'key' => 'multi-menu.two', - 'children' => [ - [ - 'type' => 'route', - 'name' => '三级页面', - 'local' => "menu.multi-menu.two.second", - 'key' => 'multi-menu.two.second', - 'path' => '/multi-menu/second', - ], - [ - 'type' => 'menu', - 'name' => '三级菜单', - 'local' => "menu.multi-menu.two.three", - 'key' => 'multi-menu.two.three', - 'children' => [ - [ - 'type' => 'route', - 'name' => '四级页面', - 'local' => "menu.multi-menu.two.three.third", - 'key' => 'multi-menu.two.three.third', - 'path' => '/multi-menu/third', - ] - ] - ] - ] - ], - ] - ], - [ - 'type' => 'menu', - 'name' => '页面布局', - 'local' => "menu.page-layout", - 'icon' => "LayoutOutlined", - 'key' => 'page-layout', - 'children' => [ - [ - 'type' => 'route', - 'name' => '基础布局', - 'local' => "menu.page-layout.base-layout", - 'key' => 'page-layout.base-layout', - 'path' => '/page-layout/base-layout', - ], - [ - 'type' => 'route', - 'name' => '固定头部', - 'local' => "menu.page-layout.fix-header", - 'key' => 'page-layout.fix-header', - 'path' => '/page-layout/fix-header', - ], - [ - 'type' => 'route', - 'name' => '页面描述', - 'local' => "menu.page-layout.descriptions", - 'key' => 'page-layout.descriptions', - 'path' => '/page-layout/descriptions', - ] - ] - ], - [ - 'type' => 'menu', - 'key' => "example", - 'name' => "组件示例", - 'path' => "", - 'icon' => "AppstoreOutlined", - 'local' => "menu.example", - 'hidden' => 1, - 'link' => 0, - 'children' => [ - [ - 'type' => "route", - 'key' => "example.user-selector", - 'name' => "用户选择器", - 'path' => "/example/user-selector", - 'local' => "menu.example.user-selector", - 'hidden' => 1, - 'link' => 0 - ], - [ - 'type' => "route", - 'key' => "example.icon-selector", - 'name' => "图标", - 'path' => "/example/icon-selector", - 'local' => "menu.example.icon-selector", - 'hidden' => 1, - 'link' => 0 - ], - [ - 'type' => "route", - 'key' => "example.image-uploader", - 'name' => "图片上传器", - 'path' => "/example/image-uploader", - 'local' => "menu.example.image-uploader", - 'hidden' => 1, - 'link' => 0 - ], - [ - 'type' => "route", - 'key' => "example.xin-form", - 'name' => "XinForm 表单", - 'path' => "/example/xin-form", - 'local' => "menu.example.xin-form", - 'hidden' => 1, - 'link' => 0 - ], - [ - 'type' => "route", - 'key' => "example.xin-table", - 'name' => "XinTable 表格", - 'path' => "/example/xin-table", - 'local' => "menu.example.xin-table", - 'hidden' => 1, - 'link' => 0 - ] - ] - ], - [ - 'type' => 'menu', - 'name' => 'AI', - 'local' => "menu.ai", - 'icon' => "OpenAIOutlined", - 'key' => "ai", - 'children' => [ - [ - 'type' => "route", - 'key' => "ai.chat", - 'name' => "AI对话", - "path" => "/ai/chat", - 'local' => "menu.ai.chat", - 'children' => [ - ['type' => 'rule', 'name' => '发送消息', 'key' => 'ai.chat.send'], - ['type' => 'rule', 'name' => '会话列表', 'key' => 'ai.chat.conversations'], - ['type' => 'rule', 'name' => '消息列表', 'key' => 'ai.chat.messages'], - ['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.chat.delete'], - ] - ], - [ - 'type' => "route", - 'key' => "ai.conversation", - 'name' => "会话管理", - "path" => "/ai/conversation", - 'local' => "menu.ai.conversation", - 'children' => [ - ['type' => 'rule', 'name' => '查询会话列表', 'key' => 'ai.conversation.query'], - ['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.conversation.delete'], - ] - ], - [ - 'type' => "route", - 'key' => "ai.agent", - 'name' => "Agent 管理", - "path" => "/ai/agent", - 'local' => "menu.ai.agent", - 'children' => [ - ['type' => 'rule', 'name' => '查询列表', 'key' => 'ai.agent.query'], - ['type' => 'rule', 'name' => '更新 Agent', 'key' => 'ai.agent.update'], - ] - ], - ] - ], - [ - 'type' => "menu", - 'name' => "系统管理", - 'local' => "menu.system", - 'icon' => "SettingOutlined", - 'key' => "system", - 'children' => [ - [ - 'type' => "route", - 'key' => "system.user", - 'name' => "用户管理", - 'path' => "/system/user", - 'local' => "menu.system.user", - 'children' => [ - ['type' => 'rule', 'name' => '查询列表', 'key' => 'system.user.query'], - ['type' => 'rule', 'name' => '新增用户', 'key' => 'system.user.create'], - ['type' => 'rule', 'name' => '修改用户', 'key' => 'system.user.update'], - ['type' => 'rule', 'name' => '删除用户', 'key' => 'system.user.delete'], - ['type' => 'rule', 'name' => '重置用户密码', 'key' => 'system.user.resetPassword'], - ['type' => 'rule', 'name' => '获取角色选项', 'key' => 'system.user.role'], - ['type' => 'rule', 'name' => '获取部门选项', 'key' => 'system.user.dept'], - ] - ], - [ - 'type' => "route", - 'key' => "system.dept", - 'name' => "部门管理", - 'path' => "/system/dept", - 'local' => "menu.system.dept", - 'children' => [ - ['type' => 'rule', 'name' => '获取部门列表', 'key' => 'system.dept.query'], - ['type' => 'rule', 'name' => '新建部门', 'key' => 'system.dept.create'], - ['type' => 'rule', 'name' => '更新部门信息', 'key' => 'system.dept.update'], - ['type' => 'rule', 'name' => '删除部门', 'key' => 'system.dept.delete'], - ['type' => 'rule', 'name' => '获取部门用户', 'key' => 'system.dept.users'], - ] - ], - [ - 'type' => "route", - 'key' => "system.role", - 'name' => "角色管理", - 'path' => "/system/role", - 'local' => "menu.system.role", - 'children' => [ - ['type' => 'rule', 'name' => '新增角色', 'key' => 'system.role.create'], - ['type' => 'rule', 'name' => '查询角色列表', 'key' => 'system.role.query'], - ['type' => 'rule', 'name' => '更新角色信息', 'key' => 'system.role.update'], - ['type' => 'rule', 'name' => '删除角色', 'key' => 'system.role.delete'], - ['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.role.status'], - ['type' => 'rule', 'name' => '获取角色用户', 'key' => 'system.role.users'], - ['type' => 'rule', 'name' => '设置角色权限', 'key' => 'system.role.setRule'], - ['type' => 'rule', 'name' => '获取权限选项', 'key' => 'system.role.ruleList'], - ] - ], - [ - 'type' => "route", - 'key' => "system.rule", - 'name' => "菜单管理", - 'path' => "/system/rule", - 'local' => "menu.system.rule", - 'children' => [ - ['type' => 'rule', 'name' => '获取权限列表', 'key' => 'system.rule.query'], - ['type' => 'rule', 'name' => '创建权限规则', 'key' => 'system.rule.create'], - ['type' => 'rule', 'name' => '更新权限规则', 'key' => 'system.rule.update'], - ['type' => 'rule', 'name' => '删除权限规则', 'key' => 'system.rule.delete'], - ['type' => 'rule', 'name' => '获取父级权限', 'key' => 'system.rule.parentQuery'], - ['type' => 'rule', 'name' => '设置显示状态', 'key' => 'system.rule.show'], - ['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.rule.status'], - ] - ], - [ - 'type' => "route", - 'name' => "文件管理", - 'local' => "menu.system.file", - 'key' => "system.file", - 'path' => "/system/file", - 'children' => [ - ['type' => 'rule', 'name' => '获取文件夹', 'key' => 'system.file.group.query'], - ['type' => 'rule', 'name' => '新增文件夹', 'key' => 'system.file.group.create'], - ['type' => 'rule', 'name' => '编辑文件夹', 'key' => 'system.file.group.update'], - ['type' => 'rule', 'name' => '删除文件夹', 'key' => 'system.file.group.delete'], - ['type' => 'rule', 'name' => '查询文件列表', 'key' => 'system.file.list.query'], - ['type' => 'rule', 'name' => '上传文件', 'key' => 'system.file.list.upload'], - ['type' => 'rule', 'name' => '下载文件', 'key' => 'system.file.list.download'], - ['type' => 'rule', 'name' => '删除文件', 'key' => 'system.file.list.delete'], - ['type' => 'rule', 'name' => '永久删除文件', 'key' => 'system.file.list.force-delete'], - ['type' => 'rule', 'name' => '恢复文件', 'key' => 'system.file.list.restore'], - ['type' => 'rule', 'name' => '查看回收站', 'key' => 'system.file.list.trashed'], - ['type' => 'rule', 'name' => '清空回收站', 'key' => 'system.file.list.clean-trashed'], - ['type' => 'rule', 'name' => '复制文件', 'key' => 'system.file.list.copy'], - ['type' => 'rule', 'name' => '移动文件', 'key' => 'system.file.list.move'], - ['type' => 'rule', 'name' => '重命名文件', 'key' => 'system.file.list.rename'] - ], - ], - [ - 'type' => "route", - 'name' => "系统字典", - 'local' => "menu.system.dict", - 'key' => "system.dict", - 'path' => "/system/dict", - 'children' => [ - ['type' => 'rule', 'name' => '字典列表', 'key' => 'system.dict.list.query'], - ['type' => 'rule', 'name' => '新增字典', 'key' => 'system.dict.list.create'], - ['type' => 'rule', 'name' => '删除字典', 'key' => 'system.dict.list.delete'], - ['type' => 'rule', 'name' => '更新字典', 'key' => 'system.dict.list.update'], - ['type' => 'rule', 'name' => '字典项列表', 'key' => 'system.dict.item.query'], - ['type' => 'rule', 'name' => '字典项新增', 'key' => 'system.dict.item.create'], - ['type' => 'rule', 'name' => '字典项编辑', 'key' => 'system.dict.item.update'], - ['type' => 'rule', 'name' => '字典项删除', 'key' => 'system.dict.item.delete'], - ] - ], - [ - 'type' => "route", - 'name' => "系统配置", - 'local' => "menu.system.config", - 'key' => "system.config", - 'path' => "/system/config", - 'children' => [ - ['type' => 'rule', 'name' => '配置列表', 'key' => 'system.config.items.query'], - ['type' => 'rule', 'name' => '新增配置', 'key' => 'system.config.items.create'], - ['type' => 'rule', 'name' => '编辑配置', 'key' => 'system.config.items.update'], - ['type' => 'rule', 'name' => '删除配置', 'key' => 'system.config.items.delete'], - ['type' => 'rule', 'name' => '保存配置', 'key' => 'system.config.items.save'], - ['type' => 'rule', 'name' => '刷新配置', 'key' => 'system.config.items.refresh'], - ['type' => 'rule', 'name' => '配置组编辑', 'key' => 'system.config.group.update'], - ['type' => 'rule', 'name' => '配置组删除', 'key' => 'system.config.items.item.delete'], - ['type' => 'rule', 'name' => '配置组列表', 'key' => 'system.config.group.query'], - ['type' => 'rule', 'name' => '配置组新增', 'key' => 'system.config.group.create'], - ] - ], - [ - 'type' => 'route', - 'key' => 'system.mail', - 'name' => '邮件配置', - 'path' => '/system/mail', - 'local' => 'menu.system.mail', - 'children' => [ - ['type' => 'rule', 'name' => '获取配置', 'key' => 'system.mail.config'], - ['type' => 'rule', 'name' => '保存配置', 'key' => 'system.mail.save'], - ['type' => 'rule', 'name' => '发送测试', 'key' => 'system.mail.test'], - ] - ], - [ - 'type' => 'route', - 'key' => 'system.storage', - 'name' => '存储配置', - 'path' => '/system/storage', - 'local' => 'menu.system.storage', - 'children' => [ - ['type' => 'rule', 'name' => '获取配置', 'key' => 'system.storage.config'], - ['type' => 'rule', 'name' => '保存配置', 'key' => 'system.storage.save'], - ['type' => 'rule', 'name' => '测试连接', 'key' => 'system.storage.test'], - ] - ], - [ - 'type' => 'route', - 'key' => 'system.ai', - 'name' => 'AI 配置', - 'path' => '/system/ai', - 'local' => 'menu.system.ai', - 'children' => [ - ['type' => 'rule', 'name' => '获取可用AI列表', 'key' => 'system.ai.list'], - ['type' => 'rule', 'name' => '获取AI配置', 'key' => 'system.ai.config'], - ['type' => 'rule', 'name' => '保存AI配置', 'key' => 'system.ai.save'], - ['type' => 'rule', 'name' => '测试连接', 'key' => 'system.ai.test'], - ] - ], - [ - 'type' => "route", - 'name' => "系统信息", - 'local' => "menu.system.info", - 'key' => "system.info", - 'path' => "/system/info", - ] - ] - ], - [ - 'type' => 'route', - 'name' => 'XinAdmin', - 'local' => "menu.xin-admin", - 'key' => "xin-admin", - 'icon' => "LinkOutlined", - 'link' => 1, - 'path' => 'https://xinadmin.cn', - ] - ]; - - $this->insertRules($rules); - - DB::table('sys_role_rule')->insertUsing( - ['role_id', 'rule_id'], - DB::table('sys_rule') - ->where('status', 1) - ->select(DB::raw('1 as role_id'), 'id') - ); - DB::table('sys_user_role')->insert([ [ 'user_id' => 1, @@ -604,43 +136,4 @@ class SysUserSeeder extends Seeder ] ]); } - - - /** - * 递归插入权限规则数据 - * - * @param array $rules 规则数据 - * @param int $pid 父级ID,默认为0(顶级) - * @return void - */ - function insertRules(array $rules, int $pid = 0): void - { - $order = 0; - foreach ($rules as $rule) { - // 准备插入数据 - $insertData = [ - 'parent_id' => $pid, - 'type' => $rule['type'], - 'key' => $rule['key'], - 'name' => $rule['name'], - 'path' => $rule['path'] ?? '', - 'icon' => $rule['icon'] ?? '', - 'order' => $order++, - 'local' => $rule['local'] ?? '', - 'status' => 1, - 'hidden' => 1, - 'link' => $rule['link'] ?? 0, - 'created_at' => now(), - 'updated_at' => now(), - ]; - - // 插入数据并获取插入的ID - $currentId = DB::table('sys_rule')->insertGetId($insertData); - - // 如果有子菜单,递归插入 - if (!empty($rule['children']) && is_array($rule['children'])) { - $this->insertRules($rule['children'], $currentId); - } - } - } }