Files
yuezi-saas/backend/database/seeders/InitSeeder.php
T
li 11c177a432 feat: 第一阶段基础框架搭建
后端 (Laravel 10 + Sanctum):
- RBAC 四层权限系统 (users→roles→permissions→menus)
- 门店隔离中间件 (BelongsToStore Trait + StoreIsolation Middleware)
- 操作日志中间件 (自动记录写操作)
- 权限检查中间件 (CheckPermission)
- 16张数据库表迁移 (系统基础+RBAC+字典+配置)
- 11个 Eloquent Model
- Auth API (登录/登出/用户信息)
- 系统设置模块 CRUD (门店/部门/职务/用户/角色/菜单/权限/字典/日志)
- 45条 RESTful API 路由
- InitSeeder 初始数据 (超管/角色/76权限/31菜单)

前端 (Vue 3 + Element Plus + Vite):
- Axios 请求封装 + Token 注入
- Pinia 状态管理 (user + permission store)
- 动态路由 (服务端菜单→前端路由自动生成)
- 后台布局 (侧边栏+顶栏+主内容区)
- 登录页 + 仪表盘首页
- 系统设置 7 个 CRUD 页面

技术方案文档 (7卷):
- 技术总览/数据库设计/API规范/RBAC设计/模块详设/小程序设计/部署方案
2026-03-13 19:52:09 +08:00

267 lines
14 KiB
PHP

<?php
namespace Database\Seeders;
use App\Models\Department;
use App\Models\Menu;
use App\Models\Permission;
use App\Models\Region;
use App\Models\Role;
use App\Models\Store;
use App\Models\User;
use Illuminate\Database\Seeder;
class InitSeeder extends Seeder
{
public function run(): void
{
// 1. 创建默认区域
$region = Region::create(['name' => '默认区域', 'sort' => 0, 'status' => 1]);
// 2. 创建默认门店
$store = Store::create([
'region_id' => $region->id,
'name' => '宫中有喜总店',
'code' => 'HQ001',
'status' => 1,
]);
// 3. 创建默认部门
Department::create(['store_id' => $store->id, 'name' => '管理层', 'sort' => 0]);
// 4. 创建超级管理员
$admin = User::create([
'store_id' => $store->id,
'username' => 'admin',
'password' => 'admin123',
'name' => '超级管理员',
'status' => 1,
'is_super' => 1,
]);
// 5. 创建默认角色
$superRole = Role::create([
'name' => '超级管理员',
'code' => 'super_admin',
'description' => '系统最高权限',
'is_system' => 1,
]);
$storeAdmin = Role::create([
'store_id' => $store->id,
'name' => '门店管理员',
'code' => 'store_admin',
'description' => '门店最高权限',
'is_system' => 1,
]);
$admin->roles()->attach($superRole->id);
// 6. 创建权限
$this->createPermissions();
// 7. 创建菜单
$this->createMenus();
// 8. 门店管理员分配所有权限
$allPermissions = Permission::pluck('id')->toArray();
$storeAdmin->permissions()->sync($allPermissions);
}
private function createPermissions(): void
{
$modules = [
['name' => 'CRM管理', 'code' => 'crm', 'children' => [
['name' => '线索管理', 'code' => 'crm.lead', 'children' => [
['name' => '查看', 'code' => 'crm.lead.view', 'type' => 2],
['name' => '新建', 'code' => 'crm.lead.create', 'type' => 2],
['name' => '编辑', 'code' => 'crm.lead.update', 'type' => 2],
['name' => '删除', 'code' => 'crm.lead.delete', 'type' => 2],
]],
['name' => '客户管理', 'code' => 'crm.customer', 'children' => [
['name' => '查看', 'code' => 'crm.customer.view', 'type' => 2],
['name' => '新建', 'code' => 'crm.customer.create', 'type' => 2],
['name' => '编辑', 'code' => 'crm.customer.update', 'type' => 2],
['name' => '删除', 'code' => 'crm.customer.delete', 'type' => 2],
]],
['name' => '合同管理', 'code' => 'crm.contract', 'children' => [
['name' => '查看', 'code' => 'crm.contract.view', 'type' => 2],
['name' => '新建', 'code' => 'crm.contract.create', 'type' => 2],
['name' => '审批', 'code' => 'crm.contract.approve', 'type' => 2],
]],
]],
['name' => '房务管理', 'code' => 'room', 'children' => [
['name' => '房间管理', 'code' => 'room.room', 'children' => [
['name' => '查看', 'code' => 'room.room.view', 'type' => 2],
['name' => '编辑', 'code' => 'room.room.update', 'type' => 2],
]],
['name' => '预定管理', 'code' => 'room.reservation', 'children' => [
['name' => '查看', 'code' => 'room.reservation.view', 'type' => 2],
['name' => '新建', 'code' => 'room.reservation.create', 'type' => 2],
['name' => '操作', 'code' => 'room.reservation.operate', 'type' => 2],
]],
]],
['name' => '护理管理', 'code' => 'care', 'children' => [
['name' => '护理档案', 'code' => 'care.profile', 'children' => [
['name' => '查看', 'code' => 'care.profile.view', 'type' => 2],
['name' => '编辑', 'code' => 'care.profile.update', 'type' => 2],
]],
['name' => '护理记录', 'code' => 'care.record', 'children' => [
['name' => '查看', 'code' => 'care.record.view', 'type' => 2],
['name' => '新建', 'code' => 'care.record.create', 'type' => 2],
]],
]],
['name' => '月子餐管理', 'code' => 'meal', 'children' => [
['name' => '菜品管理', 'code' => 'meal.dish', 'children' => [
['name' => '查看', 'code' => 'meal.dish.view', 'type' => 2],
['name' => '编辑', 'code' => 'meal.dish.update', 'type' => 2],
]],
['name' => '排餐管理', 'code' => 'meal.plan', 'children' => [
['name' => '查看', 'code' => 'meal.plan.view', 'type' => 2],
['name' => '编辑', 'code' => 'meal.plan.update', 'type' => 2],
]],
]],
['name' => '服务产康', 'code' => 'service', 'children' => [
['name' => '服务项目', 'code' => 'service.item', 'children' => [
['name' => '查看', 'code' => 'service.item.view', 'type' => 2],
['name' => '编辑', 'code' => 'service.item.update', 'type' => 2],
]],
]],
['name' => '月嫂管理', 'code' => 'nanny', 'children' => [
['name' => '月嫂档案', 'code' => 'nanny.profile', 'children' => [
['name' => '查看', 'code' => 'nanny.profile.view', 'type' => 2],
['name' => '编辑', 'code' => 'nanny.profile.update', 'type' => 2],
]],
]],
['name' => '进销存', 'code' => 'stock', 'children' => [
['name' => '库存管理', 'code' => 'stock.inventory', 'children' => [
['name' => '查看', 'code' => 'stock.inventory.view', 'type' => 2],
['name' => '操作', 'code' => 'stock.inventory.operate', 'type' => 2],
]],
]],
['name' => '财务管理', 'code' => 'finance', 'children' => [
['name' => '收支管理', 'code' => 'finance.record', 'children' => [
['name' => '查看', 'code' => 'finance.record.view', 'type' => 2],
['name' => '新建', 'code' => 'finance.record.create', 'type' => 2],
['name' => '审核', 'code' => 'finance.record.approve', 'type' => 2],
]],
]],
['name' => '人事薪资', 'code' => 'hr', 'children' => [
['name' => '员工管理', 'code' => 'hr.employee', 'children' => [
['name' => '查看', 'code' => 'hr.employee.view', 'type' => 2],
['name' => '编辑', 'code' => 'hr.employee.update', 'type' => 2],
]],
]],
['name' => '办公协同', 'code' => 'office', 'children' => [
['name' => '审批管理', 'code' => 'office.approval', 'children' => [
['name' => '查看', 'code' => 'office.approval.view', 'type' => 2],
['name' => '审批', 'code' => 'office.approval.operate', 'type' => 2],
]],
]],
['name' => '统计报表', 'code' => 'report', 'children' => [
['name' => '查看报表', 'code' => 'report.view', 'type' => 2],
['name' => '导出报表', 'code' => 'report.export', 'type' => 2],
]],
['name' => '知识库', 'code' => 'kb', 'children' => [
['name' => '文章管理', 'code' => 'kb.article', 'children' => [
['name' => '查看', 'code' => 'kb.article.view', 'type' => 2],
['name' => '编辑', 'code' => 'kb.article.update', 'type' => 2],
]],
]],
['name' => '系统设置', 'code' => 'system', 'children' => [
['name' => '门店管理', 'code' => 'system.store', 'type' => 2],
['name' => '用户管理', 'code' => 'system.user', 'type' => 2],
['name' => '角色管理', 'code' => 'system.role', 'type' => 2],
['name' => '菜单管理', 'code' => 'system.menu', 'type' => 2],
['name' => '字典管理', 'code' => 'system.dict', 'type' => 2],
['name' => '操作日志', 'code' => 'system.log', 'type' => 2],
]],
];
$this->insertPermissions($modules);
}
private function insertPermissions(array $items, int $parentId = 0, int &$sort = 0): void
{
foreach ($items as $item) {
$children = $item['children'] ?? [];
unset($item['children']);
$item['parent_id'] = $parentId;
$item['type'] = $item['type'] ?? 1;
$item['module'] = explode('.', $item['code'])[0];
$item['sort'] = $sort++;
$permission = Permission::create($item);
if ($children) {
$this->insertPermissions($children, $permission->id, $sort);
}
}
}
private function createMenus(): void
{
$menus = [
['name' => '首页', 'path' => '/dashboard', 'component' => 'dashboard/index', 'icon' => 'HomeFilled', 'sort' => 0],
['name' => 'CRM管理', 'icon' => 'User', 'sort' => 1, 'permission_code' => 'crm', 'children' => [
['name' => '线索管理', 'path' => '/crm/leads', 'component' => 'crm/leads/index', 'permission_code' => 'crm.lead'],
['name' => '客户管理', 'path' => '/crm/customers', 'component' => 'crm/customers/index', 'permission_code' => 'crm.customer'],
['name' => '合同管理', 'path' => '/crm/contracts', 'component' => 'crm/contracts/index', 'permission_code' => 'crm.contract'],
]],
['name' => '房务管理', 'icon' => 'House', 'sort' => 2, 'permission_code' => 'room', 'children' => [
['name' => '房态看板', 'path' => '/room/board', 'component' => 'room/board/index', 'permission_code' => 'room.room'],
['name' => '预定管理', 'path' => '/room/reservations', 'component' => 'room/reservations/index', 'permission_code' => 'room.reservation'],
]],
['name' => '护理管理', 'icon' => 'FirstAidKit', 'sort' => 3, 'permission_code' => 'care', 'children' => [
['name' => '护理档案', 'path' => '/care/profiles', 'component' => 'care/profiles/index', 'permission_code' => 'care.profile'],
['name' => '护理记录', 'path' => '/care/records', 'component' => 'care/records/index', 'permission_code' => 'care.record'],
]],
['name' => '月子餐', 'icon' => 'Bowl', 'sort' => 4, 'permission_code' => 'meal', 'children' => [
['name' => '菜品管理', 'path' => '/meal/dishes', 'component' => 'meal/dishes/index', 'permission_code' => 'meal.dish'],
['name' => '排餐管理', 'path' => '/meal/plans', 'component' => 'meal/plans/index', 'permission_code' => 'meal.plan'],
]],
['name' => '服务产康', 'icon' => 'Promotion', 'sort' => 5, 'permission_code' => 'service'],
['name' => '月嫂管理', 'icon' => 'Avatar', 'sort' => 6, 'permission_code' => 'nanny'],
['name' => '进销存', 'icon' => 'Box', 'sort' => 7, 'permission_code' => 'stock'],
['name' => '财务管理', 'icon' => 'Money', 'sort' => 8, 'permission_code' => 'finance'],
['name' => '人事薪资', 'icon' => 'Stamp', 'sort' => 9, 'permission_code' => 'hr'],
['name' => '办公协同', 'icon' => 'ChatDotRound', 'sort' => 10, 'permission_code' => 'office'],
['name' => '统计报表', 'icon' => 'DataAnalysis', 'sort' => 11, 'permission_code' => 'report'],
['name' => '知识库', 'icon' => 'Reading', 'sort' => 12, 'permission_code' => 'kb'],
['name' => '系统设置', 'icon' => 'Setting', 'sort' => 99, 'permission_code' => 'system', 'children' => [
['name' => '门店管理', 'path' => '/system/stores', 'component' => 'system/stores/index', 'permission_code' => 'system.store'],
['name' => '部门管理', 'path' => '/system/departments', 'component' => 'system/departments/index', 'permission_code' => 'system.store'],
['name' => '职务管理', 'path' => '/system/positions', 'component' => 'system/positions/index', 'permission_code' => 'system.store'],
['name' => '用户管理', 'path' => '/system/users', 'component' => 'system/users/index', 'permission_code' => 'system.user'],
['name' => '角色管理', 'path' => '/system/roles', 'component' => 'system/roles/index', 'permission_code' => 'system.role'],
['name' => '菜单管理', 'path' => '/system/menus', 'component' => 'system/menus/index', 'permission_code' => 'system.menu'],
['name' => '字典管理', 'path' => '/system/dictionaries', 'component' => 'system/dictionaries/index', 'permission_code' => 'system.dict'],
['name' => '操作日志', 'path' => '/system/logs', 'component' => 'system/logs/index', 'permission_code' => 'system.log'],
]],
];
$this->insertMenus($menus);
}
private function insertMenus(array $items, int $parentId = 0): void
{
foreach ($items as $index => $item) {
$children = $item['children'] ?? [];
unset($item['children']);
$item['parent_id'] = $parentId;
$item['type'] = isset($item['component']) ? 2 : 1; // 有 component = 菜单,否则目录
$item['sort'] = $item['sort'] ?? $index;
$item['visible'] = 1;
$item['status'] = 1;
$menu = Menu::create($item);
if ($children) {
$this->insertMenus($children, $menu->id);
}
}
}
}