model = plugin()->webman->config('database.app_version_model'); } /** * 版本 * @auth true * @return Card */ public function index(): Card { return Card::create(Tabs::create() ->pane(admin_trans('app_version.system_key.' . AppVersion::SYSTEM_KEY_ANDROID), $this->androidList()) ->pane(admin_trans('app_version.system_key.' . AppVersion::SYSTEM_KEY_IOS), $this->iosList()) ->type('card') ->destroyInactiveTabPane() ); } /** * 安装版本 * @return Grid */ public function androidList(): Grid { return Grid::create(new $this->model(), function (Grid $grid) { $grid->model()->where('system_key', AppVersion::SYSTEM_KEY_ANDROID)->orderBy('id', 'desc'); $this->getList($grid, AppVersion::SYSTEM_KEY_ANDROID); }); } /** * 苹果版本 * @return Grid */ public function iosList(): Grid { return Grid::create(new $this->model(), function (Grid $grid) { $grid->model()->where('system_key', AppVersion::SYSTEM_KEY_IOS)->orderBy('id', 'desc'); $this->getList($grid, AppVersion::SYSTEM_KEY_IOS); }); } /** * 版本列表 * @param $grid * @param $systemKey */ public function getList($grid, $systemKey) { $grid->title(admin_trans('app_version.title')); $exAdminFilter = Request::input('ex_admin_filter', []); if (isset($exAdminFilter['created_at_start']) && !empty($exAdminFilter['created_at_start'])) { $grid->model()->whereDate('created_at', '>=', $exAdminFilter['created_at_start']); } if (isset($exAdminFilter['created_at_end']) && !empty($exAdminFilter['created_at_end'])) { $grid->model()->whereDate('created_at', '<=', $exAdminFilter['created_at_end']); } $grid->autoHeight(); $grid->bordered(true); $grid->column('channel.name', admin_trans('channel.fields.name'))->align('center'); $grid->column('system_key', admin_trans('app_version.fields.system_key'))->align('center'); $grid->column('app_version', admin_trans('app_version.fields.app_version')); $grid->column('app_version_key', admin_trans('app_version.fields.app_version_key'))->align('center'); $grid->column('apk_url', admin_trans('app_version.fields.apk_url'))->align('center'); $grid->column('force_update', admin_trans('app_version.fields.force_update'))->switch([[1 => ''], [0 => '']])->align('center'); $grid->column('hot_update', admin_trans('app_version.fields.hot_update'))->switch([[1 => ''], [0 => '']])->align('center'); $grid->column('regular_update', admin_trans('app_version.fields.regular_update'))->align('center'); $grid->column('notes', admin_trans('app_version.fields.notes'))->align('center'); $grid->column('status', admin_trans('app_version.fields.status'))->switch([[1 => ''], [0 => '']])->align('center'); $grid->column('created_at', admin_trans('app_version.fields.created_at'))->align('center'); $grid->hideDelete(); $grid->hideSelection(); $grid->filter(function (Filter $filter) { $filter->eq()->select('department_id') ->showSearch() ->style(['width' => '200px']) ->dropdownMatchSelectWidth() ->placeholder(admin_trans('channel.fields.name')) ->remoteOptions(admin_url(['addons-webman-controller-ChannelController', 'getDepartmentOptions'])); $filter->eq()->select('status') ->placeholder(admin_trans('app_version.fields.status')) ->options([ 1 => admin_trans('post.normal'), 0 => admin_trans('post.disable') ]); $filter->form()->hidden('created_at_start'); $filter->form()->hidden('created_at_end'); $filter->form()->dateRange('created_at_start', 'created_at_end', '')->placeholder([admin_trans('public_msg.created_at_start'), admin_trans('public_msg.created_at_end')]); }); $grid->setForm()->drawer($this->form($systemKey)); $grid->quickSearch(); } /** * 添加修改版本 * @auth true */ public function form($systemKey): Form { ini_set('memory_limit', '512M'); Form::extend('myEditor', MyEditor::class); return Form::create(new $this->model, function (Form $form) use ($systemKey) { $form->title(admin_trans('app_version.title')); $form->radio('system_key', admin_trans('app_version.fields.system_key')) ->button() ->default($systemKey) ->options([ AppVersion::SYSTEM_KEY_ANDROID => admin_trans('app_version.system_key.' . AppVersion::SYSTEM_KEY_ANDROID), AppVersion::SYSTEM_KEY_IOS => admin_trans('app_version.system_key.' . AppVersion::SYSTEM_KEY_IOS), ])->required(); $form->dateTime('regular_update', admin_trans('app_version.fields.regular_update'))->required(); $form->select('department_id', admin_trans('slider.fields.department_id')) ->options($this->getChannelOptions())->required(); $form->text('app_version', admin_trans('app_version.fields.app_version'))->rule([ 'regex:/^\d+\.\d+\.\d+$/' => admin_trans('app_version.app_version_regex') ])->maxlength(50)->required(); $form->text('app_version_key', admin_trans('app_version.fields.app_version_key'))->disabled(true)->maxlength(50)->required(); $form->watch([ 'app_version' => function ($value, Watch $watch) { $versionNumbers = explode('.', $value); $newVersion = implode('', $versionNumbers); $watch['app_version_key'] = $newVersion; }, ]); $form->row(function (Form $form) { $form->switch('status', admin_trans('app_version.fields.status'))->span(8)->required(); $form->switch('force_update', admin_trans('app_version.fields.force_update'))->span(8)->required(); $form->switch('hot_update', admin_trans('app_version.fields.hot_update')) ->default(0) ->when('==', 1, function (Form $form) { $form->file('apk_url', admin_trans('app_version.hot_apk_url')) ->directory('app_version') ->type('file') ->ext(['zip']) ->chunkSize(1) ->chunk() ->limit(1) ->fileSize('200MB')->hideFinder()->required(); })->when('==', 0, function (Form $form) { $form->text('apk_url', admin_trans('app_version.fields.apk_url'))->ruleUrl()->maxlength(200)->required(); }) ->span(8) ->required(); }, null); $form->textarea('notes', admin_trans('app_version.fields.notes'))->maxlength(125)->bindAttr('rows', 3); $form->myEditor('update_content', admin_trans('app_version.fields.update_content')); $form->hidden('user_id')->value(!empty(Admin::user()) ? Admin::user()->id : 0); $form->hidden('user_name')->value(!empty(Admin::user()) ? Admin::user()->username : ''); $form->hidden('hot_update_url'); $form->layout('vertical'); $form->saving(function (Form $form) { $apkUrl = $form->input('apk_url'); $hotUpdate = $form->input('hot_update'); $hotUpdateUrl = $form->input('hot_update_url'); $appVersionKey = $form->input('app_version_key'); if (!$apkUrl) { return message_error(admin_trans('app_version.missing_package_address')); } if (!$appVersionKey) { return message_error(admin_trans('app_version.app_version_key_not_found')); } if (AppVersion::query()->where('department_id', $form->input('department_id'))->where('app_version_key', $appVersionKey)->exists()) { return message_error(admin_trans('app_version.app_version_key_exists')); } if ($hotUpdate == 1) { $apkUrl = str_replace(env('APP_DOMAIN'), '', $apkUrl); if (!file_exists(public_path() . $apkUrl)) { return message_error(admin_trans('app_version.upload_update_package')); } if (empty($hotUpdateUrl)) { $extension = pathinfo($apkUrl, PATHINFO_EXTENSION); $fileName = pathinfo($apkUrl, PATHINFO_FILENAME); if (!$extension || !$fileName) { return message_error(admin_trans('app_version.hot_apk_url_error')); } // 解压压缩包 $hotUrl = $this->decompression($appVersionKey, $extension, $apkUrl); $form->input('hot_update_url', $hotUrl); } } }); }); } /** * 筛选部门/渠道 * @return array */ public function getChannelOptions(): array { $channelList = Channel::query()->orderBy('created_at', 'desc')->get(); $data = []; /** @var Channel $channel */ foreach ($channelList as $channel) { $data[$channel->department_id] = $channel->name; } return $data; } /** * @param $appVersionKey * @param string $type * @param string $file * @return string|void * @throws \Exception */ public function decompression($appVersionKey, string $type = '', string $file = '') { try { $file = public_path() . $file; $savePath = '/storage/app_version/' . $appVersionKey; $newPath = public_path() . $savePath; if (!file_exists($newPath)) { //检查是否有该文件夹,如果没有就创建,并给予最高权限 mkdir($newPath, 0755, true); } switch ($type) { case 'zip': $zip = new ZipArchive; if ($zip->open($file) === TRUE) { $zip->extractTo($newPath); $zip->close(); return env('APP_DOMAIN') . $savePath; } else { throw new \Exception(admin_trans('app_version.decompression_failed')); } case 'rar': $file = RarArchive::open($file); if ($file !== FALSE) { $entries = $file->getEntries(); foreach ($entries as $entry) { $entry->extract($newPath); } $file->close(); return env('APP_DOMAIN') . $savePath; } else { throw new \Exception(admin_trans('app_version.decompression_failed')); } } } catch (Exception $e) { throw new \Exception($e->getMessage()); } } }