master
lion 1 month ago
parent 960529413e
commit 3ce7844a2a

@ -40,6 +40,9 @@ SMS_MOCK=false
# 同一手机号再次发送验证码最短间隔(秒)
SMS_RESEND_INTERVAL_SECONDS=60
# 报名表未在 JSON 中写 company_name.required_when 时:企业名称在何「参赛组别」取值下必填(须与下拉 value 一致,自定义 value 如 entry_group2 时填 entry_group2
# ENTRY_GROUP_COMPANY_REQUIRED_VALUE=entry_group2
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025

@ -84,6 +84,102 @@ class ApplicationController extends Controller
return array_values(array_filter(array_map('strval', $raw), fn (string $v) => $v !== ''));
}
/**
* 报名表 schema 中 entry_group 下拉允许的「值」(与选项 `value` 一致,如 entry_group1
*
* @return list<string>
*/
private function entryGroupSelectValuesFromSignupSchema(Competition $competition): array
{
$competition->loadMissing('formSchema');
$rows = $competition->formSchema?->schema_json;
if (! is_array($rows)) {
return [];
}
foreach ($rows as $row) {
if (! is_array($row) || ($row['key'] ?? '') !== 'entry_group') {
continue;
}
$opts = $row['options'] ?? [];
if (! is_array($opts)) {
return [];
}
$out = [];
foreach ($opts as $opt) {
if (is_array($opt) && array_key_exists('value', $opt)) {
$s = trim((string) $opt['value']);
if ($s !== '') {
$out[] = $s;
}
} elseif (is_string($opt)) {
$s = trim($opt);
if ($s !== '') {
$out[] = $s;
}
}
}
return array_values(array_unique($out));
}
return [];
}
/**
* 参赛组别取何值时企业名称必填:优先读 company_name 的 required_when否则读 config。
*
* @return list<string>
*/
private function companyNameRequiredWhenEntryGroupValues(Competition $competition): array
{
$competition->loadMissing('formSchema');
$rows = $competition->formSchema?->schema_json;
if (! is_array($rows)) {
$rows = [];
}
foreach ($rows as $row) {
if (! is_array($row) || ($row['key'] ?? '') !== 'company_name') {
continue;
}
$rw = $row['required_when'] ?? null;
if (! is_array($rw) || ($rw['field'] ?? '') !== 'entry_group') {
break;
}
$vals = $rw['values'] ?? [];
if (! is_array($vals)) {
break;
}
$out = [];
foreach ($vals as $v) {
$s = trim((string) $v);
if ($s !== '') {
$out[] = $s;
}
}
if (count($out) > 0) {
return array_values(array_unique($out));
}
break;
}
$cv = trim((string) config('contest.entry_group_company_required_value', '创业组'));
return $cv !== '' ? [$cv] : [];
}
/**
* @return list<string>
*/
private function allowedEntryGroupValues(Competition $competition): array
{
$fromSchema = $this->entryGroupSelectValuesFromSignupSchema($competition);
if (count($fromSchema) > 0) {
return $fromSchema;
}
return $this->entryGroupOptionValues();
}
public function show(Request $request): JsonResponse
{
$app = $this->currentApplication($request);
@ -102,18 +198,23 @@ class ApplicationController extends Controller
$trackCodes = $this->enabledTrackCodes($competition);
$degrees = config('contest.degrees', []);
$countries = config('contest.location_countries', []);
$entryGroupValues = $this->entryGroupOptionValues();
$trackRules = count($trackCodes)
? ['nullable', 'string', Rule::in($trackCodes)]
: ['nullable', 'string', 'max:100'];
$companyRules = ['nullable', 'string', 'max:255'];
if ($this->signupSchemaHasKey($competition, 'entry_group')) {
$cv = (string) config('contest.entry_group_company_required_value', '创业组');
$companyRules[] = 'required_if:entry_group,'.$cv;
$reqVals = $this->companyNameRequiredWhenEntryGroupValues($competition);
if (count($reqVals) > 0) {
$companyRules[] = Rule::requiredIf(function () use ($request, $reqVals): bool {
$eg = (string) $request->input('entry_group', '');
return in_array($eg, $reqVals, true);
});
}
}
$trackRules = count($trackCodes)
? ['nullable', 'string', Rule::in($trackCodes)]
: ['nullable', 'string', 'max:100'];
$rules = [
'player_name' => ['nullable', 'string', 'max:120'],
'school' => ['nullable', 'string', 'max:200'],
@ -130,7 +231,7 @@ class ApplicationController extends Controller
'intro' => ['nullable', 'string', 'max:5000'],
];
if ($this->signupSchemaHasKey($competition, 'entry_group')) {
$rules['entry_group'] = ['required', 'string', Rule::in($entryGroupValues)];
$rules['entry_group'] = ['required', 'string', Rule::in($this->allowedEntryGroupValues($competition))];
}
if ($this->signupSchemaRequiresCommitment($competition)) {
$rules['commitment_accepted'] = ['sometimes', 'boolean'];
@ -191,12 +292,17 @@ class ApplicationController extends Controller
$degrees = config('contest.degrees', []);
$countries = config('contest.location_countries', []);
$entryGroupValues = $this->entryGroupOptionValues();
$companyRules = ['nullable', 'string', 'max:255'];
if ($this->signupSchemaHasKey($competition, 'entry_group')) {
$cv = (string) config('contest.entry_group_company_required_value', '创业组');
$companyRules[] = 'required_if:entry_group,'.$cv;
$reqVals = $this->companyNameRequiredWhenEntryGroupValues($competition);
if (count($reqVals) > 0) {
$companyRules[] = Rule::requiredIf(function () use ($request, $reqVals): bool {
$eg = (string) $request->input('entry_group', '');
return in_array($eg, $reqVals, true);
});
}
}
$rules = [
@ -215,7 +321,7 @@ class ApplicationController extends Controller
'intro' => ['nullable', 'string', 'max:5000'],
];
if ($this->signupSchemaHasKey($competition, 'entry_group')) {
$rules['entry_group'] = ['required', 'string', Rule::in($entryGroupValues)];
$rules['entry_group'] = ['required', 'string', Rule::in($this->allowedEntryGroupValues($competition))];
}
if ($this->signupSchemaRequiresCommitment($competition)) {
$rules['commitment_accepted'] = ['required', 'accepted'];

@ -6,8 +6,11 @@ return [
'location_countries' => ['中国', '海外'],
/** 参赛组别(报名表 entry_group 可选值,与选手端 schema 一致) */
'entry_groups' => ['创新组', '创业组'],
/** 选择该组别时企业名称必填(须为 entry_groups 中一项) */
'entry_group_company_required_value' => '创业组',
/**
* 选择该组别时企业名称必填:存储的是下拉 option 的 **value**(与展示 label 可不同)。
* 若报名表 JSON 里 company_name.required_when 已配置,则以 schema 为准;否则用此配置(无 schema 兜底时常见)。
*/
'entry_group_company_required_value' => env('ENTRY_GROUP_COMPANY_REQUIRED_VALUE', '创业组'),
/** 单文件上限KB须保证 PHP upload_max_filesize、post_max_size 均大于此值(见 public/.user.ini 与 composer serve-dev */
'file_max_kb' => 20480,
'file_mimes' => ['pdf', 'ppt', 'pptx', 'doc', 'docx', 'wps', 'rar', 'zip'],

Loading…
Cancel
Save