refactor: 修复知识库和操作指引
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\SopTemplate;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\SopTemplate>
|
||||
*/
|
||||
class SopTemplateFactory extends Factory
|
||||
{
|
||||
protected $model = SopTemplate::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->randomElement([
|
||||
'设备启动操作规程',
|
||||
'产品质检标准流程',
|
||||
'安全生产检查清单',
|
||||
'设备维护保养流程',
|
||||
'应急处理操作指南',
|
||||
]) . '-' . fake()->numberBetween(1, 100),
|
||||
'description' => fake()->sentence(20),
|
||||
'category' => fake()->randomElement(['生产操作', '质量管理', '安全管理', '设备维护', '应急处理']),
|
||||
'tags' => fake()->randomElements(['标准作业', '安全', '质量', '效率', '培训'], fake()->numberBetween(1, 3)),
|
||||
'version' => '1.0.0',
|
||||
'status' => fake()->randomElement(['draft', 'published', 'archived']),
|
||||
'applicable_departments' => fake()->randomElements(['生产部', '质检部', '设备部', '安全部'], fake()->numberBetween(1, 2)),
|
||||
'applicable_positions' => fake()->randomElements(['操作员', '质检员', '班组长', '技术员'], fake()->numberBetween(1, 2)),
|
||||
'published_at' => fake()->optional(0.6)->dateTimeBetween('-6 months', 'now'),
|
||||
'created_by' => User::factory(),
|
||||
];
|
||||
}
|
||||
|
||||
public function draft(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'status' => 'draft',
|
||||
'published_at' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function published(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'status' => 'published',
|
||||
'published_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function archived(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'status' => 'archived',
|
||||
'published_at' => fake()->dateTimeBetween('-1 year', '-1 month'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ return new class extends Migration
|
||||
$table->string('name')->comment('终端名称');
|
||||
$table->string('code', 100)->unique()->comment('终端编码');
|
||||
$table->string('ip_address', 45)->nullable()->comment('IP地址');
|
||||
$table->unsignedBigInteger('station_id')->nullable()->comment('线站ID');
|
||||
$table->string('station_id', 50)->nullable()->comment('线站ID');
|
||||
$table->string('diagram_url', 500)->nullable()->comment('组态图URL');
|
||||
$table->json('display_config')->nullable()->comment('显示配置');
|
||||
$table->boolean('is_online')->default(false)->comment('在线状态');
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('sop_templates', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->comment('模板名称');
|
||||
$table->text('description')->nullable()->comment('模板描述');
|
||||
$table->string('category', 100)->nullable()->comment('分类');
|
||||
$table->json('tags')->nullable()->comment('标签');
|
||||
$table->string('version', 50)->default('1.0.0')->comment('版本号');
|
||||
$table->enum('status', ['draft', 'published', 'archived'])->default('draft')->comment('状态');
|
||||
$table->json('applicable_departments')->nullable()->comment('适用部门');
|
||||
$table->json('applicable_positions')->nullable()->comment('适用岗位');
|
||||
$table->timestamp('published_at')->nullable()->comment('发布时间');
|
||||
$table->unsignedBigInteger('created_by')->nullable()->comment('创建人');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
// 添加索引
|
||||
$table->index('status', 'idx_sop_templates_status');
|
||||
$table->index('category', 'idx_sop_templates_category');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sop_templates');
|
||||
}
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('sop_steps', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('sop_template_id')->comment('模板ID');
|
||||
$table->integer('step_number')->comment('步骤序号');
|
||||
$table->string('title')->comment('步骤标题');
|
||||
$table->text('content')->nullable()->comment('步骤内容');
|
||||
$table->integer('sort_order')->default(0)->comment('排序');
|
||||
$table->boolean('is_required')->default(true)->comment('是否必需');
|
||||
$table->timestamps();
|
||||
|
||||
// 添加外键约束
|
||||
$table->foreign('sop_template_id')
|
||||
->references('id')
|
||||
->on('sop_templates')
|
||||
->onDelete('cascade');
|
||||
|
||||
// 添加索引
|
||||
$table->index(['sop_template_id', 'sort_order'], 'idx_template_sort');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sop_steps');
|
||||
}
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('sop_interactive_tasks', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('sop_step_id')->comment('步骤ID');
|
||||
$table->enum('task_type', ['confirm', 'input', 'select', 'photo', 'scan'])->comment('任务类型');
|
||||
$table->json('task_config')->nullable()->comment('任务配置');
|
||||
$table->json('validation_rules')->nullable()->comment('验证规则');
|
||||
$table->integer('timeout_seconds')->nullable()->comment('超时时间');
|
||||
$table->boolean('is_required')->default(true)->comment('是否必需');
|
||||
$table->timestamps();
|
||||
|
||||
// 添加外键约束
|
||||
$table->foreign('sop_step_id')
|
||||
->references('id')
|
||||
->on('sop_steps')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sop_interactive_tasks');
|
||||
}
|
||||
};
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('sop_template_versions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('sop_template_id')->comment('模板ID');
|
||||
$table->string('version', 50)->comment('版本号');
|
||||
$table->text('change_log')->nullable()->comment('变更说明');
|
||||
$table->json('content_snapshot')->nullable()->comment('内容快照');
|
||||
$table->unsignedBigInteger('created_by')->nullable()->comment('创建人');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
|
||||
// 添加外键约束
|
||||
$table->foreign('sop_template_id')
|
||||
->references('id')
|
||||
->on('sop_templates')
|
||||
->onDelete('cascade');
|
||||
|
||||
// 添加索引
|
||||
$table->index(['sop_template_id', 'version'], 'idx_template_version');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sop_template_versions');
|
||||
}
|
||||
};
|
||||
@@ -24,8 +24,8 @@ return new class extends Migration
|
||||
// 终端管理
|
||||
'terminal.viewAny' => 'terminal.view',
|
||||
|
||||
// SOP模板
|
||||
'sop-template.viewAny' => 'sop-template.view',
|
||||
// 操作指引
|
||||
'guide.viewAny' => 'guide.view',
|
||||
|
||||
// 分组管理
|
||||
'group.viewAny' => 'group.view',
|
||||
@@ -78,7 +78,7 @@ return new class extends Migration
|
||||
'system-setting.view',
|
||||
'activity-log.view',
|
||||
'terminal.view',
|
||||
'sop-template.view',
|
||||
'guide.view',
|
||||
'group.view',
|
||||
'user.view',
|
||||
'role.view',
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('guides', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->comment('指引名称');
|
||||
$table->text('description')->nullable()->comment('指引描述');
|
||||
$table->string('category', 50)->default('operation')->comment('分类: operation/fault_handling/training');
|
||||
$table->json('tags')->nullable()->comment('标签');
|
||||
$table->string('status', 20)->default('draft')->comment('状态: draft/published/archived');
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('published_at')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index('category');
|
||||
$table->index('status');
|
||||
});
|
||||
|
||||
Schema::create('guide_pages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('guide_id')->constrained()->cascadeOnDelete();
|
||||
$table->unsignedInteger('page_number')->comment('页码');
|
||||
$table->string('title')->comment('页面标题');
|
||||
$table->string('html_url', 500)->comment('HTML页面链接');
|
||||
$table->integer('parent_id')->default(-1);
|
||||
$table->unsignedInteger('sort_order')->default(0)->comment('排序');
|
||||
$table->json('options')->nullable();
|
||||
$table->string('branch_option', 100)->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('parent_id');
|
||||
$table->index(['guide_id', 'sort_order']);
|
||||
});
|
||||
|
||||
Schema::create('terminal_guides', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('terminal_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('guide_id')->constrained()->cascadeOnDelete();
|
||||
$table->integer('priority')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['terminal_id', 'guide_id'], 'uk_terminal_guide');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('terminal_guides');
|
||||
Schema::dropIfExists('guide_pages');
|
||||
Schema::dropIfExists('guides');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('terminals', function (Blueprint $table) {
|
||||
$table->string('mac_address', 17)->nullable()->unique()->after('ip_address')
|
||||
->comment('MAC地址 (AA:BB:CC:DD:EE:FF)');
|
||||
$table->string('scada_data_url', 500)->nullable()->after('diagram_url')
|
||||
->comment('OPC UA网关数据查询地址');
|
||||
$table->string('scada_tags_url', 500)->nullable()->after('scada_data_url')
|
||||
->comment('OPC UA网关点位定义查询地址');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('terminals', function (Blueprint $table) {
|
||||
$table->dropColumn(['mac_address', 'scada_data_url', 'scada_tags_url']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('documents', function (Blueprint $table) {
|
||||
$table->foreignId('knowledge_base_id')
|
||||
->nullable()
|
||||
->after('group_id')
|
||||
->constrained('knowledge_bases')
|
||||
->nullOnDelete();
|
||||
|
||||
$table->index('knowledge_base_id');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('documents', function (Blueprint $table) {
|
||||
$table->dropForeign(['knowledge_base_id']);
|
||||
$table->dropColumn('knowledge_base_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -33,7 +33,7 @@ class DatabaseSeeder extends Seeder
|
||||
'email' => 'admin@example.com',
|
||||
'password' => Hash::make('TRG}E^5BvPcbyErc'),
|
||||
]);
|
||||
|
||||
|
||||
// 为管理员分配 super-admin 角色
|
||||
$admin->assignRole('super-admin');
|
||||
|
||||
@@ -218,13 +218,13 @@ class DatabaseSeeder extends Seeder
|
||||
]);
|
||||
|
||||
$this->command->info('演示数据生成完成!');
|
||||
|
||||
|
||||
// 9. 创建终端数据
|
||||
$this->call(TerminalSeeder::class);
|
||||
|
||||
// 10. 创建SOP模板数据
|
||||
$this->call(SopTemplateSeeder::class);
|
||||
|
||||
|
||||
// 10. 创建操作指引数据
|
||||
$this->call(GuideSeeder::class);
|
||||
|
||||
$this->command->newLine();
|
||||
$this->command->info('=== 生成的数据摘要 ===');
|
||||
$this->command->info('用户数量: ' . User::count());
|
||||
|
||||
219
database/seeders/GuideSeeder.php
Normal file
219
database/seeders/GuideSeeder.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Guide;
|
||||
use App\Models\GuidePage;
|
||||
use App\Models\Terminal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class GuideSeeder extends Seeder
|
||||
{
|
||||
private const BASE_URL = 'https://ssrf.9z.work/guides';
|
||||
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->command->info('开始创建操作指引数据...');
|
||||
|
||||
$admin = User::where('email', 'admin@example.com')->first();
|
||||
$terminals = Terminal::all();
|
||||
|
||||
// 1. 如何用光(带分支)
|
||||
$guide1 = $this->createHowToUseBeamGuide($admin);
|
||||
|
||||
// 2. 真空阀门故障处理
|
||||
$guide2 = $this->createVacuumValveIssueGuide($admin);
|
||||
|
||||
// 3. 漏水报警处理
|
||||
$guide3 = $this->createWaterLeakAlarmGuide($admin);
|
||||
|
||||
// 将所有指引关联到所有终端
|
||||
$this->command->info('关联指引到所有终端...');
|
||||
foreach ($terminals as $terminal) {
|
||||
$terminal->guides()->attach([
|
||||
$guide1->id => ['priority' => 1],
|
||||
$guide2->id => ['priority' => 2],
|
||||
$guide3->id => ['priority' => 3],
|
||||
]);
|
||||
}
|
||||
|
||||
$this->command->info('操作指引数据创建完成!');
|
||||
$this->command->info(' - 指引数量: ' . Guide::count());
|
||||
$this->command->info(' - 指引页面数量: ' . GuidePage::count());
|
||||
$this->command->info(' - 关联终端数量: ' . $terminals->count());
|
||||
}
|
||||
|
||||
private function createHowToUseBeamGuide(User $admin): Guide
|
||||
{
|
||||
$this->command->info('创建指引: 如何用光...');
|
||||
|
||||
$guide = Guide::create([
|
||||
'name' => '如何用光',
|
||||
'description' => '光束线用光操作完整流程指引,包含前门12和后门两条路径',
|
||||
'category' => 'operation',
|
||||
'tags' => ['用光', '光闸', 'PS1', '光学棚屋'],
|
||||
'status' => 'published',
|
||||
'created_by' => $admin->id,
|
||||
'published_at' => now(),
|
||||
]);
|
||||
|
||||
$baseUrl = self::BASE_URL . '/how-to-use-beam';
|
||||
|
||||
// 步骤1: 打开光子光闸 PS1(根节点)
|
||||
$step1 = GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => 1,
|
||||
'title' => '打开光子光闸 PS1',
|
||||
'html_url' => "{$baseUrl}/step-1.html",
|
||||
'parent_id' => -1,
|
||||
'sort_order' => 0,
|
||||
]);
|
||||
|
||||
// 步骤2: 搜索光学棚屋(带选项:前门12 / 后门)
|
||||
$step2 = GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => 2,
|
||||
'title' => '搜索光学棚屋',
|
||||
'html_url' => "{$baseUrl}/step-2.html",
|
||||
'parent_id' => $step1->id,
|
||||
'sort_order' => 1,
|
||||
'options' => ['前门12', '后门'],
|
||||
]);
|
||||
|
||||
// 步骤3a: 前门12路径 - 检查设备状态
|
||||
$step3a = GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => 3,
|
||||
'title' => '前门12路径 - 检查设备状态',
|
||||
'html_url' => "{$baseUrl}/step-3a.html",
|
||||
'parent_id' => $step2->id,
|
||||
'sort_order' => 0,
|
||||
'branch_option' => '前门12',
|
||||
]);
|
||||
|
||||
// 步骤3b: 后门路径 - 安全确认
|
||||
$step3b = GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => 3,
|
||||
'title' => '后门路径 - 安全确认',
|
||||
'html_url' => "{$baseUrl}/step-3b.html",
|
||||
'parent_id' => $step2->id,
|
||||
'sort_order' => 1,
|
||||
'branch_option' => '后门',
|
||||
]);
|
||||
|
||||
// 步骤4a: 前门12路径 - 打开实验站光闸
|
||||
GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => 4,
|
||||
'title' => '前门12路径 - 打开实验站光闸',
|
||||
'html_url' => "{$baseUrl}/step-4a.html",
|
||||
'parent_id' => $step3a->id,
|
||||
'sort_order' => 0,
|
||||
]);
|
||||
|
||||
// 步骤4b: 后门路径 - 设备检查
|
||||
GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => 4,
|
||||
'title' => '后门路径 - 设备检查',
|
||||
'html_url' => "{$baseUrl}/step-4b.html",
|
||||
'parent_id' => $step3b->id,
|
||||
'sort_order' => 0,
|
||||
]);
|
||||
|
||||
// 步骤5: 完成(根节点,最终汇合)
|
||||
GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => 5,
|
||||
'title' => '完成',
|
||||
'html_url' => "{$baseUrl}/step-5.html",
|
||||
'parent_id' => -1,
|
||||
'sort_order' => 1,
|
||||
]);
|
||||
|
||||
return $guide;
|
||||
}
|
||||
|
||||
private function createVacuumValveIssueGuide(User $admin): Guide
|
||||
{
|
||||
$this->command->info('创建指引: 真空阀门故障处理...');
|
||||
|
||||
$guide = Guide::create([
|
||||
'name' => '真空阀门故障处理',
|
||||
'description' => '真空阀门异常时的排查和处理流程',
|
||||
'category' => 'fault_handling',
|
||||
'tags' => ['真空', '阀门', '故障', '联锁', '气动'],
|
||||
'status' => 'published',
|
||||
'created_by' => $admin->id,
|
||||
'published_at' => now(),
|
||||
]);
|
||||
|
||||
$baseUrl = self::BASE_URL . '/vacuum-valve-issue';
|
||||
$steps = [
|
||||
['title' => '检查真空度', 'file' => 'step-1.html'],
|
||||
['title' => '检查联锁状态', 'file' => 'step-2.html'],
|
||||
['title' => '尝试手动复位', 'file' => 'step-3.html'],
|
||||
['title' => '检查气动系统', 'file' => 'step-4.html'],
|
||||
['title' => '联系维护人员', 'file' => 'step-5.html'],
|
||||
];
|
||||
|
||||
$parentId = -1;
|
||||
foreach ($steps as $i => $step) {
|
||||
$page = GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => $i + 1,
|
||||
'title' => $step['title'],
|
||||
'html_url' => "{$baseUrl}/{$step['file']}",
|
||||
'parent_id' => $parentId,
|
||||
'sort_order' => $parentId === -1 ? $i : 0,
|
||||
]);
|
||||
$parentId = $page->id;
|
||||
}
|
||||
|
||||
return $guide;
|
||||
}
|
||||
|
||||
private function createWaterLeakAlarmGuide(User $admin): Guide
|
||||
{
|
||||
$this->command->info('创建指引: 漏水报警处理...');
|
||||
|
||||
$guide = Guide::create([
|
||||
'name' => '漏水报警处理',
|
||||
'description' => '漏水报警时的应急处理和复位流程',
|
||||
'category' => 'fault_handling',
|
||||
'tags' => ['漏水', '报警', '应急', '复位'],
|
||||
'status' => 'published',
|
||||
'created_by' => $admin->id,
|
||||
'published_at' => now(),
|
||||
]);
|
||||
|
||||
$baseUrl = self::BASE_URL . '/water-leak-alarm';
|
||||
$steps = [
|
||||
['title' => '确认报警位置', 'file' => 'step-1.html'],
|
||||
['title' => '搜索光学棚屋', 'file' => 'step-2.html'],
|
||||
['title' => '定位并处理漏水点', 'file' => 'step-3.html'],
|
||||
['title' => '复位报警', 'file' => 'step-4.html'],
|
||||
['title' => '完成', 'file' => 'step-5.html'],
|
||||
];
|
||||
|
||||
$parentId = -1;
|
||||
foreach ($steps as $i => $step) {
|
||||
$page = GuidePage::create([
|
||||
'guide_id' => $guide->id,
|
||||
'page_number' => $i + 1,
|
||||
'title' => $step['title'],
|
||||
'html_url' => "{$baseUrl}/{$step['file']}",
|
||||
'parent_id' => $parentId,
|
||||
'sort_order' => $parentId === -1 ? $i : 0,
|
||||
]);
|
||||
$parentId = $page->id;
|
||||
}
|
||||
|
||||
return $guide;
|
||||
}
|
||||
}
|
||||
@@ -40,13 +40,13 @@ class PermissionSeeder extends Seeder
|
||||
'terminal.delete' => '删除终端',
|
||||
'terminal.sync' => '同步终端配置',
|
||||
|
||||
// SOP模板权限
|
||||
'sop-template.view' => '查看SOP模板',
|
||||
'sop-template.create' => '创建SOP',
|
||||
'sop-template.update' => '编辑SOP',
|
||||
'sop-template.delete' => '删除SOP',
|
||||
'sop-template.publish' => '发布SOP',
|
||||
'sop-template.archive' => '归档SOP',
|
||||
// 操作指引权限
|
||||
'guide.view' => '查看指引',
|
||||
'guide.create' => '创建指引',
|
||||
'guide.update' => '编辑指引',
|
||||
'guide.delete' => '删除指引',
|
||||
'guide.publish' => '发布指引',
|
||||
'guide.archive' => '归档指引',
|
||||
|
||||
// 分组管理权限
|
||||
'group.view' => '查看分组',
|
||||
@@ -129,13 +129,13 @@ class PermissionSeeder extends Seeder
|
||||
'terminal.delete',
|
||||
'terminal.sync',
|
||||
|
||||
// SOP模板
|
||||
'sop-template.view',
|
||||
'sop-template.create',
|
||||
'sop-template.update',
|
||||
'sop-template.delete',
|
||||
'sop-template.publish',
|
||||
'sop-template.archive',
|
||||
// 操作指引
|
||||
'guide.view',
|
||||
'guide.create',
|
||||
'guide.update',
|
||||
'guide.delete',
|
||||
'guide.publish',
|
||||
'guide.archive',
|
||||
|
||||
// 分组管理
|
||||
'group.view',
|
||||
@@ -173,8 +173,8 @@ class PermissionSeeder extends Seeder
|
||||
// 终端管理(仅查看)
|
||||
'terminal.view',
|
||||
|
||||
// SOP模板(仅查看)
|
||||
'sop-template.view',
|
||||
// 操作指引(仅查看)
|
||||
'guide.view',
|
||||
|
||||
// 分组管理(仅查看)
|
||||
'group.view',
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\SopTemplate;
|
||||
use App\Models\SopStep;
|
||||
use App\Models\SopInteractiveTask;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SopTemplateSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$this->command->info('开始创建SOP模板数据...');
|
||||
|
||||
// 获取或创建一个用户作为创建者
|
||||
$user = User::first();
|
||||
if (!$user) {
|
||||
$this->command->warn('未找到用户,跳过SOP模板创建');
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 光束线开机流程
|
||||
$this->command->info('创建光束线开机流程...');
|
||||
$template1 = SopTemplate::create([
|
||||
'name' => '光束线标准开机流程',
|
||||
'description' => '本流程规定了光束线开机前的检查项目、开机步骤和注意事项,确保光束线安全、正常启动。',
|
||||
'category' => '光束线操作',
|
||||
'tags' => ['标准作业', '开机流程', '安全'],
|
||||
'version' => '1.0.0',
|
||||
'status' => 'published',
|
||||
'applicable_departments' => ['BL02U1', 'BL07U', 'BL08U', 'BL13HB', 'BL13U', 'BL14B', 'BL14W', 'BL15U', 'BL16B', 'BL16U1'],
|
||||
'applicable_positions' => ['操作员', '值班员'],
|
||||
'published_at' => now()->subMonths(2),
|
||||
'created_by' => $user->id,
|
||||
]);
|
||||
|
||||
$steps1 = [
|
||||
[
|
||||
'step_number' => 1,
|
||||
'title' => '开机前安全检查',
|
||||
'content' => '<p>检查光束线周围环境,确保无障碍物和安全隐患。</p><ul><li>检查光束线外观是否完好</li><li>检查安全联锁装置是否正常</li><li>检查急停按钮是否正常</li><li>确认辐射防护门关闭</li></ul>',
|
||||
'sort_order' => 1,
|
||||
'is_required' => true,
|
||||
],
|
||||
[
|
||||
'step_number' => 2,
|
||||
'title' => '真空系统检查',
|
||||
'content' => '<p>检查真空系统状态。</p><ul><li>确认真空泵运行正常</li><li>检查真空度读数</li><li>检查真空阀门状态</li></ul>',
|
||||
'sort_order' => 2,
|
||||
'is_required' => true,
|
||||
],
|
||||
[
|
||||
'step_number' => 3,
|
||||
'title' => '冷却水系统检查',
|
||||
'content' => '<p>检查冷却水系统。</p><ul><li>确认冷却水流量正常</li><li>检查水温是否在正常范围</li><li>检查冷却水压力</li></ul>',
|
||||
'sort_order' => 3,
|
||||
'is_required' => true,
|
||||
],
|
||||
[
|
||||
'step_number' => 4,
|
||||
'title' => '启动光束线',
|
||||
'content' => '<p>按照正确顺序启动光束线。</p><ol><li>打开控制系统</li><li>等待系统自检完成</li><li>启动束流</li><li>观察束流参数</li></ol>',
|
||||
'sort_order' => 4,
|
||||
'is_required' => true,
|
||||
],
|
||||
[
|
||||
'step_number' => 5,
|
||||
'title' => '运行状态确认',
|
||||
'content' => '<p>确认光束线正常运行。</p><ul><li>检查束流强度</li><li>检查束流位置</li><li>检查各项参数是否在正常范围</li></ul>',
|
||||
'sort_order' => 5,
|
||||
'is_required' => true,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($steps1 as $stepData) {
|
||||
$step = SopStep::create(array_merge($stepData, ['sop_template_id' => $template1->id]));
|
||||
|
||||
// 为第1步添加确认任务
|
||||
if ($stepData['step_number'] == 1) {
|
||||
SopInteractiveTask::create([
|
||||
'sop_step_id' => $step->id,
|
||||
'task_type' => 'confirm',
|
||||
'task_config' => [
|
||||
'title' => '安全检查确认',
|
||||
'message' => '我已完成所有安全检查项目,确认无安全隐患',
|
||||
],
|
||||
'validation_rules' => [],
|
||||
'timeout_seconds' => 300,
|
||||
'is_required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
// 为第4步添加拍照任务
|
||||
if ($stepData['step_number'] == 4) {
|
||||
SopInteractiveTask::create([
|
||||
'sop_step_id' => $step->id,
|
||||
'task_type' => 'photo',
|
||||
'task_config' => [
|
||||
'title' => '拍摄控制系统状态',
|
||||
'message' => '请拍摄控制系统界面照片',
|
||||
'min_photos' => 1,
|
||||
'max_photos' => 3,
|
||||
],
|
||||
'validation_rules' => [],
|
||||
'timeout_seconds' => 180,
|
||||
'is_required' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 用户实验准备流程
|
||||
$this->command->info('创建用户实验准备流程...');
|
||||
$template2 = SopTemplate::create([
|
||||
'name' => '用户实验准备标准流程',
|
||||
'description' => '本流程规定了用户实验前的准备工作、样品安装和参数设置步骤。',
|
||||
'category' => '实验操作',
|
||||
'tags' => ['用户实验', '标准作业', '样品准备'],
|
||||
'version' => '1.0.0',
|
||||
'status' => 'published',
|
||||
'applicable_departments' => ['BL02U1', 'BL07U', 'BL08U', 'BL13HB', 'BL13U', 'BL14B', 'BL14W', 'BL15U', 'BL16B', 'BL16U1'],
|
||||
'applicable_positions' => ['操作员', '实验员'],
|
||||
'published_at' => now()->subMonth(),
|
||||
'created_by' => $user->id,
|
||||
]);
|
||||
|
||||
$steps2 = [
|
||||
[
|
||||
'step_number' => 1,
|
||||
'title' => '扫描用户机时单',
|
||||
'content' => '<p>使用扫码枪扫描用户机时单二维码,获取实验信息。</p>',
|
||||
'sort_order' => 1,
|
||||
'is_required' => true,
|
||||
],
|
||||
[
|
||||
'step_number' => 2,
|
||||
'title' => '样品安全检查',
|
||||
'content' => '<p>检查样品安全性。</p><ul><li>确认样品无放射性</li><li>确认样品无毒性</li><li>确认样品符合实验要求</li></ul>',
|
||||
'sort_order' => 2,
|
||||
'is_required' => true,
|
||||
],
|
||||
[
|
||||
'step_number' => 3,
|
||||
'title' => '样品安装',
|
||||
'content' => '<p>将样品安装到样品台。</p><ul><li>调整样品位置</li><li>固定样品</li><li>对准光束中心</li></ul>',
|
||||
'sort_order' => 3,
|
||||
'is_required' => true,
|
||||
],
|
||||
[
|
||||
'step_number' => 4,
|
||||
'title' => '实验参数设置',
|
||||
'content' => '<p>在控制系统中设置实验参数。</p>',
|
||||
'sort_order' => 4,
|
||||
'is_required' => true,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($steps2 as $stepData) {
|
||||
$step = SopStep::create(array_merge($stepData, ['sop_template_id' => $template2->id]));
|
||||
|
||||
// 为第1步添加扫码任务
|
||||
if ($stepData['step_number'] == 1) {
|
||||
SopInteractiveTask::create([
|
||||
'sop_step_id' => $step->id,
|
||||
'task_type' => 'scan',
|
||||
'task_config' => [
|
||||
'title' => '扫描机时单二维码',
|
||||
'scan_type' => 'qrcode',
|
||||
],
|
||||
'validation_rules' => [
|
||||
'pattern' => '^[A-Z0-9]{10,20}$',
|
||||
],
|
||||
'timeout_seconds' => 60,
|
||||
'is_required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
// 为第2步添加选择任务
|
||||
if ($stepData['step_number'] == 2) {
|
||||
SopInteractiveTask::create([
|
||||
'sop_step_id' => $step->id,
|
||||
'task_type' => 'select',
|
||||
'task_config' => [
|
||||
'title' => '样品安全检查结果',
|
||||
'options' => ['通过', '不通过'],
|
||||
],
|
||||
'validation_rules' => [],
|
||||
'timeout_seconds' => 120,
|
||||
'is_required' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
// 为第3步添加拍照任务
|
||||
if ($stepData['step_number'] == 3) {
|
||||
SopInteractiveTask::create([
|
||||
'sop_step_id' => $step->id,
|
||||
'task_type' => 'photo',
|
||||
'task_config' => [
|
||||
'title' => '拍摄样品安装照片',
|
||||
'message' => '请拍摄样品安装完成后的照片',
|
||||
'min_photos' => 1,
|
||||
'max_photos' => 2,
|
||||
],
|
||||
'validation_rules' => [],
|
||||
'timeout_seconds' => 180,
|
||||
'is_required' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 创建一个草稿模板
|
||||
$this->command->info('创建草稿模板...');
|
||||
SopTemplate::create([
|
||||
'name' => '光束线日常维护流程(草稿)',
|
||||
'description' => '光束线日常维护保养操作流程,包括清洁、检查、记录等内容。',
|
||||
'category' => '设备维护',
|
||||
'tags' => ['维护', '保养'],
|
||||
'version' => '0.1.0',
|
||||
'status' => 'draft',
|
||||
'applicable_departments' => ['BL02U1', 'BL07U', 'BL08U'],
|
||||
'applicable_positions' => ['维修工', '技术员'],
|
||||
'published_at' => null,
|
||||
'created_by' => $user->id,
|
||||
]);
|
||||
|
||||
$this->command->info('SOP模板数据创建完成!');
|
||||
$this->command->newLine();
|
||||
$this->command->info('=== 生成的SOP模板摘要 ===');
|
||||
$this->command->info('总模板数量: ' . SopTemplate::count());
|
||||
$this->command->info(' - 已发布: ' . SopTemplate::where('status', 'published')->count());
|
||||
$this->command->info(' - 草稿: ' . SopTemplate::where('status', 'draft')->count());
|
||||
$this->command->info(' - 已归档: ' . SopTemplate::where('status', 'archived')->count());
|
||||
$this->command->info('总步骤数量: ' . SopStep::count());
|
||||
$this->command->info('总交互任务数量: ' . SopInteractiveTask::count());
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ class TerminalSeeder extends Seeder
|
||||
'code' => "SCREEN-{$beamline}",
|
||||
'ip_address' => $ipAddress,
|
||||
'station_id' => $beamline,
|
||||
'diagram_url' => "https://example.com/diagrams/{$beamline}.png",
|
||||
'diagram_url' => 'https://ssrf.9z.work/scada/demo.html',
|
||||
'display_config' => [
|
||||
'resolution' => '3840x2160',
|
||||
'refresh_rate' => 60,
|
||||
@@ -46,11 +46,11 @@ class TerminalSeeder extends Seeder
|
||||
'touch_enabled' => true,
|
||||
],
|
||||
'is_online' => in_array($beamline, ['BL02U1', 'BL07U', 'BL08U', 'BL13U', 'BL15U']),
|
||||
'last_online_at' => in_array($beamline, ['BL02U1', 'BL07U', 'BL08U', 'BL13U', 'BL15U'])
|
||||
? now()
|
||||
'last_online_at' => in_array($beamline, ['BL02U1', 'BL07U', 'BL08U', 'BL13U', 'BL15U'])
|
||||
? now()
|
||||
: now()->subHours(rand(1, 24)),
|
||||
]);
|
||||
|
||||
|
||||
// 为每个终端创建提示词
|
||||
TerminalPrompt::create([
|
||||
'terminal_id' => $terminal->id,
|
||||
|
||||
Reference in New Issue
Block a user