first version

This commit is contained in:
liu
2026-07-23 20:41:25 +08:00
parent 00a0938a1b
commit 10cff754a4
211 changed files with 11577 additions and 842 deletions
+276
View File
@@ -0,0 +1,276 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
/**
* 订货采购系统业务菜单与权限点种子
*
* 约定(V2.0 计划):
* - local 一律留空,name 直接写中文(layout 在 local 为空时回退显示 name,无需 i18n)
* - 幂等:顶级菜单 key 已存在时跳过,可重复执行
* - 执行后自动将全部新增权限点授予超级管理员角色(role_id=1)
*
* 执行:php artisan db:seed --class=ProcurementSeeder
*/
class ProcurementSeeder extends Seeder
{
/**
* 菜单结构:menu 目录 → route 页面 → rule 权限点
*/
private function menus(): array
{
return [
[
'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' => '下载导出'],
],
],
],
],
];
}
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<string, mixed> $node
* @param array<int> $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);
}
}
}