header(admin_trans( 'admin.album')) ->body($this->indexForm()); $html = $html->render(); //删除第一个formID对应的JS代码 preg_match('/]*id="([^"]*)"[^>]*>/', $html, $matches); if (isset($matches[1])) { $formId = $matches[1]; // 获取 id 的值 // echo "找到的 form id: " . $formId . "\n"; // 2. 根据 id 值,删除对应的 JavaScript 代码 $pattern = '/\$\(\'#' . preg_quote($formId, '/') . '\'\)\.form\(\{.*?\}\);/s'; $html = preg_replace($pattern, '', $html); } //把第一个form标签替换成div标签 $html = preg_replace('/]*)>(.*?)<\/form>/s', '$2', $html, 1); return $html; } protected function indexForm() { return Form::make(new NullRepository(), function (Form $form) { $form->action('/site-album'); $folderModel = new SiteAlbumFolderModel(); $folderTree = $folderModel->allNodes(); $form->block(2, function (Form\BlockForm $form) use ($folderTree) { $type = [ 'default' => [ 'icon' => true, ], ]; $plugins = ['types']; $form->tree() ->setTitleColumn('title') ->nodes($folderTree) ->type($type) ->plugins($plugins) ->width(12,0); }); $form->block(10, function (Form\BlockForm $form) { $form->html($this->grid())->width(12); }); //以下JS代码用于点击文件夹时,自动跳转到相应页面 Admin::script( << { const containerUl = document.getElementsByClassName('jstree-node'); if (containerUl.length > 0) { clearInterval(interval); // 找到容器后停止检测 // 以下是原有逻辑(已优化) const folderId = $('select[name="folder_id"]').data('value'); // 提取 folderId 到外层,避免重复查询[1](@ref) const anchors = document.querySelectorAll('a.jstree-anchor'); anchors.forEach(anchor => { const id = anchor.id.split('_')[0]; const href = `/prime-control/site-album?folder_id=`+id; // 绑定点击事件(阻止默认行为) anchor.addEventListener('click', event => { event.preventDefault(); window.location.href = href; }); // 高亮当前节点 if (folderId == id) { anchor.classList.add('jstree-clicked'); } }); } }, 100); // 每100ms检测一次 const firstCheckbox = document.querySelector('.vs-checkbox-primary'); // 如果找到元素,则隐藏它 if (firstCheckbox) { firstCheckbox.style.display = 'none'; } //清空_previous_ const input = document.querySelector('input[name="_previous_"]'); if (input) { // 清空其值 input.value = ''; } JS ); }); } protected function grid() { return Grid::make(new SiteAlbum(), function (Grid $grid) { //默认分页条数 $grid->paginate(config('admin.per_page')); $grid->column('id')->sortable(); $grid->column('cover')->display(function ($images) { $images = json_decode($images); // 限制最多显示2个缩略图 $dataImages = array_slice($images, 0, 1); return CommonHelper::displayImage($dataImages,80); }); $grid->column('title',admin_trans_label('product_name')); //$grid->column('title_en'); $grid->column('model'); $grid->column('folder_id',admin_trans_label('folder')) ->display(function ($folder_id) { $folderModel = new SiteAlbumFolderModel(); $folderName = $folderModel->find($folder_id)->title; return $folderName; }); $grid->column('order'); $grid->column('enabled')->using(admin_trans_array(config('dictionary.enabled'))) ->label([ 0 => 'danger', 1 => 'success', ]); $grid->column('status')->display(function ($status) { $updated_at = $this->updated_at->format('Y-m-d H:i:s'); //三个月前显示待更新 if (time() - strtotime($updated_at) > 90 * 24 * 3600) { return '待更新'; } else { return '正常'; } }); $grid->column('missing_content')->display(function ($missing_content) { $missing_content = []; if ($this->cover == '[]') {$missing_content[] = '主图';} if ($this->text_detail == '') {$missing_content[] = '文字介绍';} if ($this->en_detail == '[]') {$missing_content[] = '英文详情页';} if ($this->cn_detail == '[]') {$missing_content[] = '中文详情页';} if ($this->video == '[]') {$missing_content[] = '视频';} if ($this->poster == '[]') {$missing_content[] = '海报';} if ($this->cert == '[]') {$missing_content[] = '证书';} if ($this->pdf == '[]') {$missing_content[] = 'PDF';} return implode(' / ', $missing_content); }); // 筛选 $grid->filter(function (Grid\Filter $filter) { $selectOptions = SiteAlbumFolderModel::selectOptions(); unset($selectOptions[0]); $filter->panel(); $filter->expand(); $filter->like('model')->width(2); $filter->equal('folder_id',admin_trans_label('folder'))->select($selectOptions)->width(3); $filter->where('status', function ($query) { $status = $this->input; // 自定义查询逻辑 if ($status == 1) { // 三个月内的 $query->where('updated_at', '>=', date('Y-m-d H:i:s', strtotime('-3 month'))); } else { // 三个月前的 $query->where('updated_at', '<', date('Y-m-d H:i:s', strtotime('-3 month'))); } })->select(admin_trans_array(config('dictionary.album_status')))->width(3); }); $grid->disableViewButton(); $grid->disablePerPages(); $grid->disableRefreshButton(); $grid->model()->orderBy('order', 'desc')->orderBy('id', 'desc'); //弹窗大小 $grid->setDialogFormDimensions('830px','670px'); }); } protected function form() { $thisObj = $this; return Form::make(new SiteAlbum(), function (Form $form) use ($thisObj) { if ($form->isEditing()) { $form->title("编辑 | " . $form->model()->title); } $form->width(9, 1); $form->disableViewButton(); $form->disableViewCheck(); $form->saving(function (Form $form) use ($thisObj) { //处理video $videos = $form->input('video'); if ($videos) { foreach ($videos as $key => $value) { if (empty($value['cover']) && $value['_remove_'] != 1) { //自动生成封面 $result = $thisObj->autoGenerateCover($value['video_src']); if ($result['status']) { $videos[$key]['cover'] = $result['path']; } else { return $form->response()->error($result['msg']); } } } } else { $videos = []; } $form->input('video', $videos); //处理pdf $pdfs = $form->input('pdf'); $pdfs = empty($pdfs) ? [] : $pdfs; $form->input('pdf', $pdfs); //记录日志 if (!$form->isCreating()) { $id = $form->getKey(); $cacheKey = 'album_log_'.$id; Cache::add($cacheKey, json_encode($form->model()->toArray()), 3600); } }); $form->saved(function (Form $form) { $id = $form->getKey(); if (empty($form->input('model')) == false) { $action = $form->isCreating() ? 'add' : 'edit'; if ($action == 'add') { $oldData = "[]"; } else { $oldData = Cache::get('album_log_'. $id); Cache::forget('album_log_'. $id); } SiteAlbumLog::log($action, $id,$form->input('model'),$oldData); } //更新site_preview_video表 $video = $form->input('video'); $data = []; foreach ($video as $value) { if ($value['_remove_'] != 1){ $data[] = ['cover'=>$value['cover'],'video_title'=>$value['video_title'],'video_en_title' => $value['video_en_title'],'video_src'=>$value['video_src']]; } } SitePreviewVideo::updatePreviewVideo($id,$data); }); $form->tab(admin_trans_label('basic_info'), function (Form $form) { $selectOptions = SiteAlbumFolder::selectOptions(); unset($selectOptions[0]); $folderId = getTempValue('folderId'); if ($folderId == 0) { $folderId = array_key_first($selectOptions); } $form->select('folder_id')->options($selectOptions)->default($folderId)->required(); $form->text('title',admin_trans_label('product_name'))->required(); $form->text('title_en',admin_trans_label('product_name_en'))->required(); $form->text('model')->required(); $form->table('parameters',admin_trans_label('attribute_name'), function (Form\NestedForm $table) { $table->text('key')->required(); $table->text('value')->required(); })->setView('admin.form_custom.hasmanytable') ->saving(function ($input) { return json_encode($input); }); $form->number('order') ->default(0) ->rules('numeric'); $form->switch('enabled')->default(1); })->tab(admin_trans_label('cover'), function (Form $form) { $form->multipleImage('cover') ->retainable()//禁止删OSS图 ->sortable() // 可拖动排序 ->removable() // 可移除图片 ->autoUpload() // 自动上传 ->uniqueName() ->limit(config('admin.upload.oss_image.limit')) ->accept(config('admin.upload.oss_image.accept')) ->maxSize(config('admin.upload.oss_image.max_size')) ->dir(config("admin.upload.directory.image").'/uploads/'.date("Ym")) ->saving(function ($images) use ($form) { return json_encode($images); }); })->tab(admin_trans_label('text_detail'), function (Form $form) { $form->editor('text_detail',admin_trans_label('text_detail')); })->tab(admin_trans_label('en_detail'), function (Form $form) { $form->multipleImage('en_detail') ->retainable()//禁止删OSS图 ->sortable() // 可拖动排序 ->removable() // 可移除图片 ->autoUpload() // 自动上传 ->uniqueName() ->limit(config('admin.upload.oss_image.limit')) ->accept(config('admin.upload.oss_image.accept')) ->maxSize(config('admin.upload.oss_image.max_size')) ->dir(config("admin.upload.directory.image").'/uploads/'.date("Ym")) ->saving(function ($images) use ($form) { return json_encode($images); }); })->tab(admin_trans_label('cn_detail'), function (Form $form) { $form->multipleImage('cn_detail') ->retainable()//禁止删OSS图 ->sortable() // 可拖动排序 ->removable() // 可移除图片 ->autoUpload() // 自动上传 ->uniqueName() ->limit(config('admin.upload.oss_image.limit')) ->accept(config('admin.upload.oss_image.accept')) ->maxSize(config('admin.upload.oss_image.max_size')) ->dir(config("admin.upload.directory.image").'/uploads/'.date("Ym")) ->saving(function ($images) use ($form) { return json_encode($images); }); })->tab(admin_trans_label('video'), function (Form $form) { $count = 0; $form->hasMany('video', function (Form\NestedForm $form) use (&$count) { $videos = $form->model()->video; $imgArray = ""; if ($videos) { $videos = json_decode($videos,true); foreach ($videos as $key => $value) { if ($value['cover'] && $key == $count-1) { $imgArray = [$value['cover']]; } } } $imgHtml = CommonHelper::displayImage($imgArray); $form->html($imgHtml,admin_trans_label('image_preview')); $count++; $form->text('video_title',admin_trans_label('video_title'))->required(); $form->text('video_en_title',admin_trans_label('video_en_title'))->required(); $form->hidden('cover',admin_trans_label('video_cover'))->placeholder('自动生成')->readOnly(); $form->tradFile('video_src') ->retainable()//禁止删OSS图 ->removable() // 可移除图片 ->autoUpload() // 自动上传 ->uniqueName()// ->downloadable() ->accept(config('admin.upload.oss_video.accept')) ->maxSize(config('admin.upload.oss_video.max_size')) ->dir(config("admin.upload.directory.video").'/uploads/'.date("Ym")) ->chunkSize(1024) ->required(); })->useTable() ->customFormat(function ($data) {return json_decode($data,true);}) ->setView('admin.form_custom.hasmanytable') ->saving(function ($input) { $data = []; foreach ($input as $value) { if ($value['_remove_'] != 1){ $data[] = ['cover'=>$value['cover'],'video_title'=>$value['video_title'],'video_en_title' => $value['video_en_title'],'video_src'=>$value['video_src']]; } } return json_encode($data); }); })->tab(admin_trans_label('poster'), function (Form $form) { $form->multipleImage('poster') ->retainable()//禁止删OSS图 ->sortable() // 可拖动排序 ->removable() // 可移除图片 ->autoUpload() // 自动上传 ->uniqueName() ->limit(config('admin.upload.oss_image.limit')) ->accept(config('admin.upload.oss_image.accept')) ->maxSize(config('admin.upload.oss_image.max_size')) ->dir(config("admin.upload.directory.image").'/uploads/'.date("Ym")) ->saving(function ($images) use ($form) { return json_encode($images); }); })->tab(admin_trans_label('cert'), function (Form $form) { $form->multipleImage('cert') ->retainable()//禁止删OSS图 ->sortable() // 可拖动排序 ->removable() // 可移除图片 ->autoUpload() // 自动上传 ->uniqueName() ->limit(config('admin.upload.oss_image.limit')) ->accept(config('admin.upload.oss_image.accept')) ->maxSize(config('admin.upload.oss_image.max_size')) ->dir(config("admin.upload.directory.image").'/uploads/'.date("Ym")) ->saving(function ($images) use ($form) { return json_encode($images); }); })->tab(admin_trans_label('pdf'), function (Form $form) { $form->hasMany('pdf', function ($form) { $form->text('pdf_title')->required(); $form->text('pdf_title_en')->required(); $form->tradFile('pdf_src') ->retainable()//禁止删OSS图 ->removable() // 可移除图片 ->autoUpload() // 自动上传 ->uniqueName() ->downloadable() ->accept(config('admin.upload.oss_pdf.accept')) ->maxSize(config('admin.upload.oss_pdf.max_size')) ->dir(config("admin.upload.directory.pdf").'/uploads/'.date("Ym")) ->chunkSize(1024) ->required(); })->useTable() ->customFormat(function ($data) { return json_decode($data,true); }) ->setView('admin.form_custom.hasmanytable') ->saving(function ($input) { $data = []; foreach ($input as $value) { if ($value['_remove_'] != 1){ $data[] = ['pdf_title'=>$value['pdf_title'],'pdf_title_en' => $value['pdf_title_en'],'pdf_src'=>$value['pdf_src']]; } } return json_encode($data); }); }); //以下JS代码用于点击列表时,带上folder_id参数,还有隐藏的tab切换功能 $thisObj->formAddJS(); }); } /* * 自动生成视频封面,并上传到OSS */ private function autoGenerateCover($videoSrc) { try { $cover = $videoSrc.'?x-oss-process=video/snapshot,t_2000,f_jpg,h_500,m_fast'; $cover = CommonHelper::ossUrl($cover); $path = $this->upload($cover,'.jpg'); } catch (\Exception $e) { $path = ['status'=>true,'path'=>'/static/common/images/no-image.jpg']; } return $path; } private function upload($file,$imgType='.jpg') { $disk = $this->disk('oss'); $newName = uniqueCode("video_cover_").$imgType; $dir = config("admin.upload.directory.image").'/uploads/'.date("Ym").'/'.$newName; $contents = file_get_contents($file); if (!$contents) { return ['status'=>false,'msg'=>'图片上传失败,请检查PHP配置']; } $disk->put($dir, $contents); return ['status'=>true,'path'=>$dir]; } private function formAddJS() { $folderTabs = SiteAlbumFolder::getAllFolderTabs(); $album_tabs = config('dictionary.album_tabs'); foreach ($folderTabs as $key => $value) { foreach ($value as $k => $v) { $folderTabs[$key][$k] = admin_trans_label($album_tabs[$v]); } } $folderTabs = json_encode($folderTabs); //以下JS作用:1.点击列表时,把folder_id参数传递给表单 2.切换文件夹时,显示隐藏相应的tab Admin::script( << 的上级 元素 const parentLink = featherIcon.closest('a'); if (parentLink) { // 绑定 onclick 事件 parentLink.onclick = function(event) { // 阻止默认行为(如跳转) event.preventDefault(); // 获取 folder_id 的值 let folderIdValue = $('select[name="folder_id"]').val(); // 在 href 后追加 ?folder_id=xxx if (parentLink.href) { const newHref = parentLink.href + '?folder_id=' + folderIdValue; window.location.href = newHref; // 跳转到新的 URL } }; } } // 监听