|
|
<?php
|
|
|
|
|
|
namespace Database\Seeders;
|
|
|
|
|
|
use App\Models\Competition;
|
|
|
use App\Models\FormSchemaDefinition;
|
|
|
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}.");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @return list<array<string, mixed>>
|
|
|
*/
|
|
|
private function schemaJson(): array
|
|
|
{
|
|
|
$tracks = config('contest.tracks', []);
|
|
|
$degrees = config('contest.degrees', []);
|
|
|
$countries = config('contest.location_countries', ['中国', '海外']);
|
|
|
|
|
|
$trackOptions = array_map(fn (string $t) => ['label' => $t, 'value' => $t], $tracks);
|
|
|
$degreeOptions = array_map(fn (string $d) => ['label' => $d, 'value' => $d], $degrees);
|
|
|
$countryOptions = array_map(fn (string $c) => ['label' => $c, 'value' => $c], $countries);
|
|
|
|
|
|
$provinceOptions = array_map(
|
|
|
fn (string $p) => ['label' => $p, 'value' => $p],
|
|
|
$this->provinceOrder(),
|
|
|
);
|
|
|
|
|
|
return [
|
|
|
[
|
|
|
'key' => 'player_name',
|
|
|
'type' => 'text',
|
|
|
'label' => '参赛人姓名',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'school',
|
|
|
'type' => 'text',
|
|
|
'label' => '毕业院校',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'degree',
|
|
|
'type' => 'select',
|
|
|
'label' => '最高学历',
|
|
|
'required' => true,
|
|
|
'options' => $degreeOptions,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'contact_email',
|
|
|
'type' => 'email',
|
|
|
'label' => '注册邮箱',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'contact_mobile',
|
|
|
'type' => 'tel',
|
|
|
'label' => '联系电话',
|
|
|
'required' => true,
|
|
|
'placeholder' => '11 位中国大陆手机号',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'entry_group',
|
|
|
'type' => 'select',
|
|
|
'label' => '参赛组别',
|
|
|
'required' => true,
|
|
|
'options' => [
|
|
|
['label' => '创新组', 'value' => '创新组'],
|
|
|
['label' => '创业组', 'value' => '创业组'],
|
|
|
],
|
|
|
'help' => '仅限创业组填报企业名称(创新组不展示该字段)',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'company_name',
|
|
|
'type' => 'text',
|
|
|
'label' => '企业名称',
|
|
|
'required' => false,
|
|
|
'placeholder' => '请填写工商注册全称',
|
|
|
'required_when' => [
|
|
|
'field' => 'entry_group',
|
|
|
'values' => [(string) config('contest.entry_group_company_required_value', '创业组')],
|
|
|
],
|
|
|
],
|
|
|
[
|
|
|
'key' => 'project_name',
|
|
|
'type' => 'text',
|
|
|
'label' => '项目名称',
|
|
|
'required' => true,
|
|
|
],
|
|
|
[
|
|
|
'key' => 'track',
|
|
|
'type' => 'select',
|
|
|
'label' => '主题赛道',
|
|
|
'required' => true,
|
|
|
'options' => $trackOptions,
|
|
|
'help' => '请从本场赛事公布的赛道中选择',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'location_country',
|
|
|
'type' => 'select',
|
|
|
'label' => '项目所在地(国家或地区)',
|
|
|
'required' => 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' => 'intro',
|
|
|
'type' => 'textarea',
|
|
|
'label' => '项目简介',
|
|
|
'required' => false,
|
|
|
'placeholder' => '约200字左右',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'commitment_accepted',
|
|
|
'type' => 'checkbox',
|
|
|
'label' => '本人已阅读并同意《参赛承诺书》的全部内容',
|
|
|
'required' => true,
|
|
|
'help' => '提交报名即表示承诺所填信息真实有效,并遵守赛事规则。',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'plan',
|
|
|
'type' => 'file',
|
|
|
'label' => '上传商业计划书',
|
|
|
'required' => true,
|
|
|
'help' => '可传多份,单文件 20M 内;支持 PDF、PPT、Office 文档及压缩包',
|
|
|
],
|
|
|
[
|
|
|
'key' => 'supporting',
|
|
|
'type' => 'file',
|
|
|
'label' => '其他佐证材料',
|
|
|
'required' => false,
|
|
|
'help' => '可选;格式要求同上',
|
|
|
],
|
|
|
];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 与前端 src/data/chinaRegion.ts provinceOrder 一致。
|
|
|
*
|
|
|
* @return list<string>
|
|
|
*/
|
|
|
private function provinceOrder(): array
|
|
|
{
|
|
|
return [
|
|
|
'北京市', '天津市', '上海市', '重庆市',
|
|
|
'河北省', '山西省', '内蒙古自治区',
|
|
|
'辽宁省', '吉林省', '黑龙江省',
|
|
|
'江苏省', '浙江省', '安徽省', '福建省', '江西省', '山东省',
|
|
|
'河南省', '湖北省', '湖南省', '广东省', '广西壮族自治区', '海南省',
|
|
|
'四川省', '贵州省', '云南省', '西藏自治区',
|
|
|
'陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区',
|
|
|
'香港特别行政区', '澳门特别行政区', '台湾省',
|
|
|
];
|
|
|
}
|
|
|
}
|