load(); \support\App::loadAllConfig(['route']); use plugin\saiadmin\app\model\water\WaterPackage; use plugin\saiadmin\app\model\system\SystemMenu; if (!in_array('--apply', $argv, true)) { echo "Plan: add package metadata, finance approval records and shared road quota table; register separate delete/finance permissions. No balance changes or role grants.\n"; exit; } $db = (new WaterPackage())->getConnection(); $schema = $db->getSchemaBuilder(); foreach (['category' => 'VARCHAR(30) NULL', 'includes_device' => 'TINYINT NULL', 'description' => 'TEXT NULL'] as $column => $type) { if (!$schema->hasColumn('sa_water_package', $column)) $db->statement("ALTER TABLE sa_water_package ADD COLUMN `$column` $type"); } $db->statement("CREATE TABLE IF NOT EXISTS sa_water_finance_request ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, enterprise_id BIGINT UNSIGNED NOT NULL, kind VARCHAR(30) NOT NULL, checkout_id BIGINT UNSIGNED NULL, amount_cents BIGINT UNSIGNED NOT NULL, reference VARCHAR(100) NOT NULL, note VARCHAR(255) NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'pending', request_key VARCHAR(80) NOT NULL, payload_hash CHAR(64) NOT NULL, created_by BIGINT UNSIGNED NOT NULL, reviewed_by BIGINT UNSIGNED NULL, review_note VARCHAR(255) NULL, reviewed_at DATETIME NULL, result LONGTEXT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, UNIQUE KEY request_key(created_by,request_key), UNIQUE KEY evidence(kind,reference), UNIQUE KEY checkout_refund(checkout_id), KEY enterprise_requests(enterprise_id,id), KEY pending_requests(status,id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); $db->statement("CREATE TABLE IF NOT EXISTS sa_water_road_quota ( name VARCHAR(64) PRIMARY KEY, next_at BIGINT UNSIGNED NOT NULL DEFAULT 0, lease_hash CHAR(64) NULL, lease_until BIGINT UNSIGNED NOT NULL DEFAULT 0, actor_id BIGINT UNSIGNED NULL, quota_day CHAR(10) NOT NULL DEFAULT '', day_count INT UNSIGNED NOT NULL DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); $permissions = [ 'packages' => ['delete' => '删除套餐'], 'finance' => ['balance_read' => '查询企业余额', 'balance_credit' => '申请企业余额充值', 'balance_refund' => '申请企业退款', 'balance_review' => '审核企业资金申请'], ]; $db->transaction(function () use ($permissions) { foreach ($permissions as $module => $actions) { $parent = SystemMenu::query()->where('code', 'Water' . ucfirst($module))->whereNull('delete_time')->first(); if (!$parent) throw new RuntimeException('Missing water menu: ' . $module); foreach ($actions as $action => $name) { $slug = 'water:' . $module . ':' . $action; if (SystemMenu::query()->where('slug', $slug)->whereNull('delete_time')->exists()) continue; SystemMenu::query()->create([ 'parent_id' => $parent->id, 'name' => $name, 'code' => 'Water' . ucfirst($module) . str_replace('_', '', ucwords($action, '_')), 'slug' => $slug, 'type' => 3, 'method' => $action === 'balance_read' ? 'GET' : 'POST', 'sort' => 0, 'is_iframe' => 2, 'is_keep_alive' => 2, 'is_hidden' => 2, 'is_fixed_tab' => 2, 'is_full_page' => 2, 'generate_id' => 0, 'status' => 1, 'remark' => '独立供水业务权限;需显式授予角色', 'created_by' => 1, 'updated_by' => 1, 'create_time' => date('Y-m-d H:i:s'), 'update_time' => date('Y-m-d H:i:s'), ]); } } }); \plugin\saiadmin\app\cache\UserAuthCache::clear(); \plugin\saiadmin\app\cache\UserMenuCache::clearMenuCache(); echo "Applied additive engineering tables, package metadata and unassigned independent permissions.\n";