275 lines
12 KiB
PHP
275 lines
12 KiB
PHP
<?php
|
|
|
|
namespace addons\webman\controller;
|
|
|
|
use addons\webman\Admin;
|
|
use addons\webman\form\MyEditor;
|
|
use addons\webman\model\AppVersion;
|
|
use addons\webman\model\Channel;
|
|
use ExAdmin\ui\component\form\Form;
|
|
use ExAdmin\ui\component\form\Watch;
|
|
use ExAdmin\ui\component\grid\card\Card;
|
|
use ExAdmin\ui\component\grid\grid\Filter;
|
|
use ExAdmin\ui\component\grid\grid\Grid;
|
|
use ExAdmin\ui\component\grid\tabs\Tabs;
|
|
use ExAdmin\ui\support\Request;
|
|
use RarArchive;
|
|
use Respect\Validation\Exceptions\Exception;
|
|
use ZipArchive;
|
|
|
|
|
|
/**
|
|
* 版本管理
|
|
*/
|
|
class AppVersionController
|
|
{
|
|
protected $model;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->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());
|
|
}
|
|
}
|
|
}
|