|
|
<?php
|
|
|
|
|
|
namespace Database\Seeders;
|
|
|
|
|
|
use App\Models\Competition;
|
|
|
use App\Models\FormSchemaDefinition;
|
|
|
use App\Support\SignupFieldI18n;
|
|
|
use App\Support\SignupOptionCatalog;
|
|
|
use Illuminate\Database\Seeder;
|
|
|
|
|
|
/**
|
|
|
* 与选手端 ApplyFormView 字段 key / 校验口径对齐的报名表 schema(purpose=signup)。
|
|
|
*
|
|
|
* 运行:php artisan db:seed --class=CompetitionSignupFormSchemaSeeder
|
|
|
* 可选:SIGNUP_SCHEMA_COMPETITION_ID=1(默认 1)
|
|
|
*/
|
|
|
class CompetitionSignupFormSchemaSeeder extends Seeder
|
|
|
{
|
|
|
public function run(): void
|
|
|
{
|
|
|
$competitionId = (int) env('SIGNUP_SCHEMA_COMPETITION_ID', 1);
|
|
|
$competition = Competition::query()->find($competitionId);
|
|
|
if (! $competition) {
|
|
|
$this->command?->warn("Competition {$competitionId} not found, skip.");
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
$purpose = FormSchemaDefinition::PURPOSE_SIGNUP;
|
|
|
$nextVersion = (int) FormSchemaDefinition::query()
|
|
|
->where('competition_id', $competition->id)
|
|
|
->where('purpose', $purpose)
|
|
|
->max('version') + 1;
|
|
|
|
|
|
$schema = FormSchemaDefinition::query()->create([
|
|
|
'competition_id' => $competition->id,
|
|
|
'purpose' => $purpose,
|
|
|
'name' => '选手端报名表(与 /c/{slug}/apply 一致)',
|
|
|
'version' => $nextVersion,
|
|
|
'schema_json' => $this->schemaJson(),
|
|
|
'is_published' => true,
|
|
|
]);
|
|
|
|
|
|
$competition->update(['form_schema_id' => $schema->id]);
|
|
|
|
|
|
$this->command?->info("Form schema #{$schema->id} (v{$nextVersion}) created and bound to competition #{$competitionId}.");
|
|
|
|
|
|
$audiencePurpose = FormSchemaDefinition::PURPOSE_AUDIENCE;
|
|
|
$audienceVersion = (int) FormSchemaDefinition::query()
|
|
|
->where('competition_id', $competition->id)
|
|
|
->where('purpose', $audiencePurpose)
|
|
|
->max('version') + 1;
|
|
|
$audienceSchema = FormSchemaDefinition::query()->create([
|
|
|
'competition_id' => $competition->id,
|
|
|
'purpose' => $audiencePurpose,
|
|
|
'name' => '观众报名表(默认五项)',
|
|
|
'version' => $audienceVersion,
|
|
|
'schema_json' => $this->audienceSchemaJson(),
|
|
|
'is_published' => true,
|
|
|
]);
|
|
|
$competition->update(['audience_form_schema_id' => $audienceSchema->id]);
|
|
|
$this->command?->info("Audience form schema #{$audienceSchema->id} (v{$audienceVersion}) bound to competition #{$competitionId}.");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @return list<array<string, mixed>>
|
|
|
*/
|
|
|
private function schemaJson(): array
|
|
|
{
|
|
|
$degreeOptions = SignupOptionCatalog::schemaOptions(SignupOptionCatalog::degrees());
|
|
|
$countryOptions = SignupOptionCatalog::schemaOptions(SignupOptionCatalog::locationCountries());
|
|
|
$eventLocationOptions = SignupOptionCatalog::schemaOptions(SignupOptionCatalog::eventLocations());
|
|
|
|
|
|
$provinceOptions = array_map(
|
|
|
fn (string $p) => ['label' => $p, 'value' => $p],
|
|
|
$this->provinceOrder(),
|
|
|
);
|
|
|
|
|
|
return $this->withFieldI18n([
|
|
|
[
|
|
|
'key' => 'project_name',
|
|
|
'type' => 'text',
|
|
|
'label' => '项目名称',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'player_name',
|
|
|
'type' => 'text',
|
|
|
'label' => '申请人姓名',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'contact_email',
|
|
|
'type' => 'email',
|
|
|
'label' => '注册邮箱',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'contact_mobile',
|
|
|
'type' => 'tel',
|
|
|
'label' => '申请人电话',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'school',
|
|
|
'type' => 'text',
|
|
|
'label' => '毕业院校',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'degree',
|
|
|
'type' => 'select',
|
|
|
'label' => '最高学历',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'filter' => true,
|
|
|
'options' => $degreeOptions,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'track',
|
|
|
'type' => 'select',
|
|
|
'label' => '细分赛道',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'filter' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'company_name',
|
|
|
'type' => 'text',
|
|
|
'label' => '企业名称',
|
|
|
'required' => true,
|
|
|
'prefill_from' => 'user.company',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'location_country',
|
|
|
'type' => 'select',
|
|
|
'label' => '项目所在地',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'filter' => true,
|
|
|
'options' => $countryOptions,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'location_province',
|
|
|
'type' => 'select',
|
|
|
'label' => '省份',
|
|
|
'required' => false,
|
|
|
'options' => $provinceOptions,
|
|
|
'help' => '选择「中国」时必填',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'location_city',
|
|
|
'type' => 'text',
|
|
|
'label' => '城市',
|
|
|
'required' => false,
|
|
|
'help' => '选择「中国」时填写所在城市',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'oversea_country',
|
|
|
'type' => 'text',
|
|
|
'label' => '所在国',
|
|
|
'required' => false,
|
|
|
'placeholder' => '如:新加坡、日本、美国',
|
|
|
'help' => '选择「海外」时必填',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'event_location',
|
|
|
'type' => 'select',
|
|
|
'label' => '意向参赛地点',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'filter' => true,
|
|
|
'options' => $eventLocationOptions,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'team_members',
|
|
|
'type' => 'text',
|
|
|
'label' => '团队成员',
|
|
|
'required' => true,
|
|
|
'placeholder' => '多人请用顿号分隔',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'recommend',
|
|
|
'type' => 'text',
|
|
|
'label' => '推荐方',
|
|
|
'required' => false,
|
|
|
'placeholder' => '单位或推荐人名称',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'intro',
|
|
|
'type' => 'textarea',
|
|
|
'label' => '项目简介',
|
|
|
'required' => true,
|
|
|
'placeholder' => '约200字左右',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'commitment_accepted',
|
|
|
'type' => 'checkbox',
|
|
|
'label' => '参赛承诺书',
|
|
|
'required' => true,
|
|
|
'help' => '请点击按钮打开承诺书全文,阅读后在文末手写签名并点击「确认签署」。',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'plan',
|
|
|
'type' => 'file',
|
|
|
'label' => '上传商业计划书',
|
|
|
'required' => true,
|
|
|
'help' => '包括企业概况与定位、核心产品/服务、市场规模和竞争情况、创新壁垒与差异化优势、核心团队介绍与优势、未来发展战略规划等,PDF格式,建议不超过20页。',
|
|
|
'file_extensions' => ['pdf'],
|
|
|
'file_max_count' => 1,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'supporting',
|
|
|
'type' => 'file',
|
|
|
'label' => '其他佐证材料',
|
|
|
'required' => false,
|
|
|
'help' => '可上传多个文件:企业营业执照扫描件;知识产权相关证明材料(专利证书、商标注册证、软件著作权等),其他佐证材料(产品或服务介绍、获奖证书、投融资证明等)、创始人或主要负责人学历学位等资质证明。单文件 20M 以内,支持:PDF、PPT、PPTX、DOC、DOCX、WPS、RAR、ZIP',
|
|
|
],
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @return list<array<string, mixed>>
|
|
|
*/
|
|
|
private function audienceSchemaJson(): array
|
|
|
{
|
|
|
$purposeOptions = SignupOptionCatalog::schemaOptions(SignupOptionCatalog::audiencePurposes());
|
|
|
|
|
|
return $this->withFieldI18n([
|
|
|
[
|
|
|
'key' => 'name',
|
|
|
'type' => 'text',
|
|
|
'label' => '个人姓名',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'placeholder' => '请输入姓名',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'phone',
|
|
|
'type' => 'tel',
|
|
|
'label' => '联系电话',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'placeholder' => '请输入11位手机号',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'company',
|
|
|
'type' => 'text',
|
|
|
'label' => '所属单位',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'placeholder' => '请输入单位名称',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'job',
|
|
|
'type' => 'text',
|
|
|
'label' => '个人职务',
|
|
|
'required' => false,
|
|
|
'list' => true,
|
|
|
'placeholder' => '请输入职务',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'purpose',
|
|
|
'type' => 'select',
|
|
|
'label' => '观赛目的',
|
|
|
'required' => true,
|
|
|
'list' => true,
|
|
|
'filter' => true,
|
|
|
'placeholder' => '请选择观赛目的',
|
|
|
'options' => $purposeOptions,
|
|
|
],
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 与前端 src/data/chinaRegion.ts provinceOrder 一致。
|
|
|
*
|
|
|
* @return list<string>
|
|
|
*/
|
|
|
private function provinceOrder(): array
|
|
|
{
|
|
|
return [
|
|
|
'北京市', '天津市', '上海市', '重庆市',
|
|
|
'河北省', '山西省', '内蒙古自治区',
|
|
|
'辽宁省', '吉林省', '黑龙江省',
|
|
|
'江苏省', '浙江省', '安徽省', '福建省', '江西省', '山东省',
|
|
|
'河南省', '湖北省', '湖南省', '广东省', '广西壮族自治区', '海南省',
|
|
|
'四川省', '贵州省', '云南省', '西藏自治区',
|
|
|
'陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区',
|
|
|
'香港特别行政区', '澳门特别行政区', '台湾省',
|
|
|
];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @param list<array<string, mixed>> $rows
|
|
|
* @return list<array<string, mixed>>
|
|
|
*/
|
|
|
private function withFieldI18n(array $rows): array
|
|
|
{
|
|
|
return SignupFieldI18n::enrichSchemaRows($rows);
|
|
|
}
|
|
|
}
|