os) { case AppOs::Android: $instance->setAttribute('android', [ 'apk_url' => $instance->apk_url, 'wgt_url' => $instance->wgt_url, ]); break; case AppOs::Ios: $instance->setAttribute('ios', [ 'apk_url' => $instance->apk_url, 'wgt_url' => $instance->wgt_url, ]); break; } }); } public function store($data): bool { Validator::validate( data: $data, rules: [ 'name' => ['bail', 'required', 'max:255'], 'version' => ['bail', 'required', 'int'], 'title' => ['bail', 'required', 'max:255'], 'description' => ['bail', 'required'], 'update_strategy' => ['bail', 'required', Rule::enum(AppUpdateStrategy::class)], 'is_force' => ['bail', 'required', 'bool'], 'os' => ['bail', 'required', Rule::enum(AppOs::class)], 'release_at' => ['bail', 'nullable', 'date_format:Y-m-d H:i:s'], ], attributes: [ 'name' => __('app_version.name'), 'version' => __('app_version.version'), 'title' => __('app_version.title'), 'description' => __('app_version.description'), 'update_strategy' => __('app_version.update_strategy'), 'is_force' => __('app_version.is_force'), 'os' => __('app_version.os'), 'release_at' => __('app_version.release_at'), ], ); // 全量包 $apkUrl = ''; // 增量包 $wgtUrl = ''; // 更新策略 $aus = AppUpdateStrategy::from($data['update_strategy']); switch (AppOs::from($data['os'])) { case AppOs::Android: $apkUrl = (string) Arr::get($data, 'android.apk_url'); $wgtUrl = (string) Arr::get($data, 'android.wgt_url'); if ($aus === AppUpdateStrategy::Apk) { admin_abort_if($apkUrl === '', '请上传全量包'); } else { admin_abort_if($wgtUrl === '', '请上传增量包'); } break; case AppOs::Ios: $apkUrl = (string) Arr::get($data, 'ios.apk_url'); $wgtUrl = (string) Arr::get($data, 'ios.wgt_url'); if ($aus === AppUpdateStrategy::Apk) { admin_abort_if($apkUrl === '', '苹果应用地址 不能为空。'); } else { admin_abort_if($wgtUrl === '', '请上传增量包'); } break; default: admin_abort('未知操作系统'); break; } $model = $this->getModel(); $instance = new $model($data); try { $filename = $data['name'].'_'.time(); if ($extension = pathinfo($apkUrl, PATHINFO_EXTENSION)) { $filename .= '.'.$extension; } $instance->apk_url = $this->saveUploadedFile($apkUrl, "app-versions/{$filename}"); } catch (FileNotFoundException $e) { admin_abort('全量包未找到,请重新上传'); } try { $filename = $data['name'].'_'.time(); if ($extension = pathinfo($wgtUrl, PATHINFO_EXTENSION)) { $filename .= '.'.$extension; } $instance->wgt_url = $this->saveUploadedFile($wgtUrl, "app-versions/{$filename}"); } catch (FileNotFoundException $e) { admin_abort('增量包未找到,请重新上传'); } return $instance->save(); } public function update($primaryKey, $data): bool { Validator::validate( data: $data, rules: [ 'name' => ['bail', 'required', 'max:255'], 'version' => ['bail', 'required', 'int'], 'title' => ['bail', 'required', 'max:255'], 'description' => ['bail', 'required'], 'update_strategy' => ['bail', 'required', Rule::enum(AppUpdateStrategy::class)], 'is_force' => ['bail', 'required', 'bool'], 'os' => ['bail', 'required', Rule::enum(AppOs::class)], 'release_at' => ['bail', 'nullable', 'date_format:Y-m-d H:i:s'], ], attributes: [ 'name' => __('app_version.name'), 'version' => __('app_version.version'), 'title' => __('app_version.title'), 'description' => __('app_version.description'), 'update_strategy' => __('app_version.update_strategy'), 'is_force' => __('app_version.is_force'), 'os' => __('app_version.os'), 'release_at' => __('app_version.release_at'), ], ); // 全量包 $apkUrl = ''; // 增量包 $wgtUrl = ''; // 更新策略 $aus = AppUpdateStrategy::from($data['update_strategy']); switch (AppOs::from($data['os'])) { case AppOs::Android: $apkUrl = (string) Arr::get($data, 'android.apk_url'); $wgtUrl = (string) Arr::get($data, 'android.wgt_url'); if ($aus === AppUpdateStrategy::Apk) { admin_abort_if($apkUrl === '', '请上传全量包'); } else { admin_abort_if($wgtUrl === '', '请上传增量包'); } break; case AppOs::Ios: $apkUrl = (string) Arr::get($data, 'ios.apk_url'); $wgtUrl = (string) Arr::get($data, 'ios.wgt_url'); if ($aus === AppUpdateStrategy::Apk) { admin_abort_if($apkUrl === '', '苹果应用地址 不能为空。'); } else { admin_abort_if($wgtUrl === '', '请上传增量包'); } break; default: admin_abort('未知操作系统'); break; } $instance = $this->query()->whereKey($primaryKey)->firstOrFail(); $instance->fill($data); try { $filename = $data['name'].'_'.time(); if ($extension = pathinfo($apkUrl, PATHINFO_EXTENSION)) { $filename .= '.'.$extension; } $instance->apk_url = $this->saveUploadedFile($apkUrl, "app-versions/{$filename}"); } catch (FileNotFoundException $e) { admin_abort('全量包未找到,请重新上传'); } try { $filename = $data['name'].'_'.time(); if ($extension = pathinfo($wgtUrl, PATHINFO_EXTENSION)) { $filename .= '.'.$extension; } $instance->wgt_url = $this->saveUploadedFile($wgtUrl, "app-versions/{$filename}"); } catch (FileNotFoundException $e) { admin_abort('增量包未找到,请重新上传'); } return $instance->save(); } protected function saveUploadedFile(string $from, string $to): string { if ($from === '' || preg_match('/^https?:\/\//', $from)) { return $from; } $disk = Storage::disk(Admin::config('admin.upload.disk')); if (! $disk->exists($from)) { throw new FileNotFoundException(); } $disk->move($from, $to); return $disk->url($to); } }