You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
13 KiB

<?php
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Models\User;
use App\Models\Venue;
use App\Models\AdminMenu;
use App\Models\Activity;
use App\Models\Blacklist;
use App\Models\RolePermission;
use App\Models\RoleMenuPermission;
use App\Models\DictItem;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
$superAdmin = User::firstOrCreate(
['username' => 'admin'],
[
'name' => '超级管理员',
'email' => 'admin@szkp.local',
'password' => 'admin123456',
'role' => 'super_admin',
'is_active' => true,
]
);
$venue = Venue::firstOrCreate(
['name' => '苏州青少年科技馆'],
[
'district' => '工业园区',
'open_time' => '09:00-17:00',
'address' => '苏州工业园区示例地址',
'sort' => 10,
'is_active' => true,
]
);
$districts = ['姑苏区', '吴中区', '相城区', '虎丘区', '吴江区', '工业园区', '常熟市', '张家港市', '昆山市', '太仓市'];
foreach ($districts as $index => $name) {
DictItem::updateOrCreate(
['dict_type' => 'district', 'item_value' => $name],
['item_label' => $name, 'sort' => ($index + 1) * 10, 'is_active' => true]
);
}
$venueTypes = [
['item_label' => '科技场馆类', 'item_value' => 'science_venue', 'item_remark' => '#165DFF'],
['item_label' => '教育科研类', 'item_value' => 'education_research', 'item_remark' => '#00B42A'],
['item_label' => '“三农”类', 'item_value' => 'agriculture', 'item_remark' => '#86909C'],
['item_label' => '企业类', 'item_value' => 'enterprise', 'item_remark' => '#722ED1'],
['item_label' => '自然资源类', 'item_value' => 'nature_resource', 'item_remark' => '#FF7D00'],
['item_label' => '其他类', 'item_value' => 'other', 'item_remark' => '#F53F3F'],
];
foreach ($venueTypes as $index => $row) {
DictItem::updateOrCreate(
['dict_type' => 'venue_type', 'item_value' => $row['item_value']],
[
'dict_name' => '场馆类型',
'item_label' => $row['item_label'],
'item_remark' => $row['item_remark'],
'sort' => ($index + 1) * 10,
'is_active' => true,
]
);
}
$ticketTypes = [
['item_label' => '免费', 'item_value' => 'free', 'item_remark' => '#00B42A'],
['item_label' => '收费', 'item_value' => 'paid', 'item_remark' => '#F53F3F'],
];
foreach ($ticketTypes as $index => $row) {
DictItem::updateOrCreate(
['dict_type' => 'ticket_type', 'item_value' => $row['item_value']],
[
'dict_name' => '门票类型',
'item_label' => $row['item_label'],
'item_remark' => $row['item_remark'],
'sort' => ($index + 1) * 10,
'is_active' => true,
]
);
}
$venueAdmin = User::firstOrCreate(
['username' => 'venue_admin_01'],
[
'name' => '场馆管理员01',
'email' => 'venue_admin_01@szkp.local',
'password' => 'admin123456',
'role' => 'venue_admin',
'is_active' => true,
]
);
$venueAdmin->venues()->syncWithoutDetaching([$venue->id]);
$activity = Activity::firstOrCreate(
['venue_id' => $venue->id, 'title' => '周末科普实验课'],
[
'category' => '实验课',
'quota' => 40,
'registered_count' => 1,
'start_at' => now()->addDay(),
'end_at' => now()->addDays(2),
'is_active' => true,
]
);
// 给核销接口一条可测试预约数据
$venue->reservations()->updateOrCreate(
['visitor_name' => '测试用户', 'venue_id' => $venue->id],
[
'activity_id' => $activity->id,
'visitor_phone' => '13800000000',
'qr_token' => (string) Str::uuid(),
'status' => 'pending',
]
);
Blacklist::firstOrCreate(
['venue_id' => $venue->id, 'visitor_phone' => '13900000000'],
['visitor_name' => '黑名单测试', 'reason' => '多次爽约']
);
$menuRows = [
['name' => '工作台', 'path' => '/dashboard', 'icon' => 'IconDashboard', 'parent_id' => 0, 'sort' => 10],
['name' => '场馆管理', 'path' => null, 'icon' => 'IconApps', 'parent_id' => 0, 'sort' => 20],
['name' => '活动管理', 'path' => null, 'icon' => 'IconCalendar', 'parent_id' => 0, 'sort' => 30],
['name' => '研学线路管理', 'path' => null, 'icon' => 'IconBook', 'parent_id' => 0, 'sort' => 40],
['name' => '客流监控', 'path' => null, 'icon' => 'IconBarChart', 'parent_id' => 0, 'sort' => 50],
['name' => '数据统计', 'path' => null, 'icon' => 'IconFile', 'parent_id' => 0, 'sort' => 60],
['name' => '用户与权限', 'path' => null, 'icon' => 'IconUserGroup', 'parent_id' => 0, 'sort' => 70],
['name' => '系统设置', 'path' => null, 'icon' => 'IconSettings', 'parent_id' => 0, 'sort' => 80],
];
foreach ($menuRows as $row) {
AdminMenu::updateOrCreate(['name' => $row['name'], 'parent_id' => $row['parent_id']], $row + ['is_visible' => true]);
}
$parentId = AdminMenu::query()->pluck('id', 'name');
$children = [
['name' => '场馆列表', 'path' => '/venues', 'icon' => 'IconList', 'parent' => '场馆管理', 'sort' => 1],
['name' => '活动列表', 'path' => '/activities', 'icon' => 'IconCalendarClock', 'parent' => '活动管理', 'sort' => 1],
['name' => '报名管理', 'path' => '/activities/registrations', 'icon' => 'IconUser', 'parent' => '活动管理', 'sort' => 2],
['name' => '现场核销', 'path' => '/activities/verify', 'icon' => 'IconScan', 'parent' => '活动管理', 'sort' => 3],
['name' => '用户管理', 'path' => '/activities/blacklist', 'icon' => 'IconLock', 'parent' => '活动管理', 'sort' => 4],
['name' => '线路列表', 'path' => '/study-tours', 'icon' => 'IconBook', 'parent' => '研学线路管理', 'sort' => 1],
['name' => '实时客流监控', 'path' => '/traffic', 'icon' => 'IconEye', 'parent' => '客流监控', 'sort' => 1],
['name' => '活跃指数排行榜', 'path' => '/traffic/leaderboard', 'icon' => 'IconTrophy', 'parent' => '客流监控', 'sort' => 2],
['name' => '异常告警', 'path' => '/traffic/alerts', 'icon' => 'IconNotification', 'parent' => '客流监控', 'sort' => 3],
['name' => '综合统计', 'path' => '/stats', 'icon' => 'IconPieChart', 'parent' => '数据统计', 'sort' => 1],
['name' => '区域分析', 'path' => '/stats/regions', 'icon' => 'IconLocation', 'parent' => '数据统计', 'sort' => 2],
['name' => '类别分析', 'path' => '/stats/categories', 'icon' => 'IconFilter', 'parent' => '数据统计', 'sort' => 3],
['name' => '报表导出', 'path' => '/stats/exports', 'icon' => 'IconExport', 'parent' => '数据统计', 'sort' => 4],
['name' => '管理员账号', 'path' => '/system/admins', 'icon' => 'IconUserGroup', 'parent' => '用户与权限', 'sort' => 1],
['name' => '角色权限', 'path' => '/system/roles', 'icon' => 'IconSafe', 'parent' => '用户与权限', 'sort' => 2],
['name' => '操作日志', 'path' => '/system/audit-logs', 'icon' => 'IconHistory', 'parent' => '用户与权限', 'sort' => 3],
['name' => '权限菜单', 'path' => '/system/menus', 'icon' => 'IconMenu', 'parent' => '用户与权限', 'sort' => 4],
['name' => '微信配置', 'path' => '/settings/wechat', 'icon' => 'IconMessage', 'parent' => '系统设置', 'sort' => 1],
['name' => '地图与第三方配置', 'path' => '/settings/map', 'icon' => 'IconMap', 'parent' => '系统设置', 'sort' => 2],
['name' => '消息通知', 'path' => '/settings/notifications', 'icon' => 'IconBell', 'parent' => '系统设置', 'sort' => 3],
['name' => '系统日志', 'path' => '/settings/system-logs', 'icon' => 'IconFile', 'parent' => '系统设置', 'sort' => 4],
['name' => '数据字典', 'path' => '/settings/dictionaries', 'icon' => 'IconStorage', 'parent' => '系统设置', 'sort' => 5],
];
foreach ($children as $child) {
AdminMenu::updateOrCreate(
['name' => $child['name'], 'parent_id' => $parentId[$child['parent']] ?? 0],
[
'path' => $child['path'],
'icon' => $child['icon'],
'parent_id' => $parentId[$child['parent']] ?? 0,
'sort' => $child['sort'],
'is_visible' => true,
]
);
}
$allMenuIds = AdminMenu::query()->pluck('id')->map(fn ($id) => (int) $id)->values();
foreach (['super_admin', 'venue_admin'] as $role) {
foreach ($allMenuIds as $menuId) {
RoleMenuPermission::firstOrCreate([
'role' => $role,
'menu_id' => $menuId,
]);
}
}
$permissionRows = [
['module' => '管理员账号', 'permission' => '查看管理员列表', 'super_admin_allowed' => true, 'venue_admin_allowed' => false, 'scope' => '超级管理员可查看全部管理员信息', 'sort' => 10],
['module' => '管理员账号', 'permission' => '新增/编辑管理员', 'super_admin_allowed' => true, 'venue_admin_allowed' => false, 'scope' => '仅超级管理员可创建账号并绑定场馆', 'sort' => 20],
['module' => '场馆管理', 'permission' => '查看场馆', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可查看绑定场馆', 'sort' => 30],
['module' => '场馆管理', 'permission' => '编辑场馆', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可编辑绑定场馆', 'sort' => 40],
['module' => '活动管理', 'permission' => '新增活动', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员新增活动默认关联绑定场馆', 'sort' => 50],
['module' => '活动管理', 'permission' => '编辑/启停活动', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可操作绑定场馆活动', 'sort' => 60],
['module' => '活动管理', 'permission' => '删除/恢复活动', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '删除受报名记录保护;恢复后可自动置为停用', 'sort' => 70],
['module' => '报名管理', 'permission' => '查看报名记录', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可查看绑定场馆记录', 'sort' => 80],
['module' => '报名管理', 'permission' => '现场核销', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可核销绑定场馆二维码', 'sort' => 90],
['module' => '报名管理', 'permission' => '一键拉黑', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可拉黑绑定场馆报名用户', 'sort' => 100],
['module' => '用户管理', 'permission' => '查看用户与预约场馆', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可查看预约过本场馆的用户', 'sort' => 110],
['module' => '用户管理', 'permission' => '批量拉黑/解除黑名单', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅可操作本场馆;超级管理员可按一个或多个场馆批量操作', 'sort' => 120],
['module' => '数据统计', 'permission' => '查看统计看板', 'super_admin_allowed' => true, 'venue_admin_allowed' => true, 'scope' => '场馆管理员仅看绑定场馆统计口径', 'sort' => 130],
];
foreach ($permissionRows as $row) {
RolePermission::updateOrCreate(
['module' => $row['module'], 'permission' => $row['permission']],
$row
);
}
}
}