// +---------------------------------------------------------------------- // +---------------------------------------------------------------------- // | 栏目管理 // +---------------------------------------------------------------------- namespace app\admin\controller\cms; use app\admin\model\cms\Category as CategoryModel; use app\admin\model\cms\CategoryPriv as CategoryPrivModel; use app\common\controller\Adminbase; use think\Db; class Category extends Adminbase { private $categoryTemplate; private $listTemplate; private $showTemplate; private $pageTemplate; protected $noNeedRight = ['count_items', 'public_cache', 'public_tpl_file_list']; protected function initialize() { parent::initialize(); $this->modelClass = new CategoryModel; //取得当前内容模型模板存放目录 $themePath = TEMPLATE_PATH . (config('site.theme') ?: "default") . DS . "cms" . DS; //取得栏目频道模板列表 $this->categoryTemplate = str_replace($themePath . DS, '', glob($themePath . DS . 'category*')); //取得栏目列表模板列表 $this->listTemplate = str_replace($themePath . DS, '', glob($themePath . DS . 'list*')); //取得内容页模板列表 $this->showTemplate = str_replace($themePath . DS, '', glob($themePath . DS . 'show*')); //取得单页模板 $this->pageTemplate = str_replace($themePath . DS, '', glob($themePath . DS . 'page*')); } //栏目列表 public function index() { if ($this->request->isAjax()) { $models = cache('Model'); $tree = new \util\Tree(); $tree->icon = ['   │ ', '   ├─ ', '   └─ ']; $tree->nbsp = '   '; $categorys = []; $result = Db::name('category')->order('listorder DESC, id DESC')->select(); foreach ($result as $k => $v) { if (isset($models[$v['modelid']]['name'])) { $v['modelname'] = $models[$v['modelid']]['name']; } else { $v['modelname'] = '/'; } $v['catname'] = '' . $v['catname'] . ''; $v['add_url'] = url("add", ["parentid" => $v['id']]); $v['url'] = buildCatUrl($v['id'], $v['url']); $categorys[$v['id']] = $v; } $tree->init($categorys); $_list = $tree->getTreeList($tree->getTreeArray(0), 'catname'); $total = count($_list); $result = ["code" => 0, "count" => $total, "data" => $_list]; return json($result); } return $this->fetch(); } //新增栏目 public function add() { if ($this->request->isPost()) { $data = $this->request->post(); if (empty($data)) { $this->error('添加栏目数据不能为空!'); } switch ($data['type']) { //单页 case 1: $scene = 'page'; break; //列表 case 2: $scene = 'list'; break; //外链 case 3: $scene = 'link'; break; default: $this->error('栏目类型错误~'); } if ($data['isbatch']) { unset($data['isbatch'], $data['info']['catname'], $data['info']['catdir']); //需要批量添加的栏目 $batch_add = explode(PHP_EOL, $data['batch_add']); if (empty($batch_add) || empty($data['batch_add'])) { $this->error('请填写需要添加的栏目!'); } foreach ($batch_add as $rs) { if (trim($rs) == '') { continue; } $cat = explode('|', $rs, 2); $data['catname'] = $cat[0]; $data['catdir'] = $cat[1] ?? ''; $data['catdir'] = $this->get_dirpinyin($data['catname'], $data['catdir']); $result = $this->validate($data, 'app\admin\validate\cms\Category.' . $scene); if (true !== $result) { $this->error($result); } try { $this->modelClass->allowField(true)->isUpdate(false)->data($data)->save(); } catch (\Exception $e) { $this->error($e->getMessage()); } } $this->success("添加成功!"); } else { $data['catdir'] = $this->get_dirpinyin($data['catname'], $data['catdir']); $result = $this->validate($data, 'app\admin\validate\cms\Category.' . $scene); if (true !== $result) { $this->error($result); } try { $this->modelClass->allowField(true)->save($data); } catch (\Exception $e) { $this->error($e->getMessage()); } $this->success("添加成功!"); } } else { $parentid = $this->request->param('parentid/d', 0); if (!empty($parentid)) { $Ca = getCategory($parentid); if (empty($Ca)) { $this->error("父栏目不存在!"); } } //输出可用模型 $modelsdata = cache("Model"); $models = []; foreach ($modelsdata as $v) { if ($v['status'] == 1 && $v['module'] == 'cms') { $models[] = $v; } } //栏目列表 可以用缓存的方式 $array = Db::name('Category')->order('listorder DESC, id DESC')->column('*', 'id'); if (!empty($array) && is_array($array)) { $tree = new \util\Tree(); $tree->icon = ['  │ ', '  ├─ ', '  └─ ']; $tree->nbsp = '  '; $str = ""; $tree->init($array); $categorydata = $tree->getTree(0, $str, $parentid); } else { $categorydata = ''; } $this->assign([ 'category' => $categorydata, 'models' => $models, 'tp_category' => $this->categoryTemplate, 'tp_list' => $this->listTemplate, 'tp_show' => $this->showTemplate, 'tp_page' => $this->pageTemplate, 'parentid_modelid' => $Ca['modelid'] ?? 0, "Member_Group" => cache("Member_Group"), "cmsConfig" => get_addon_config("cms"), ]); return $this->fetch(); } } //编辑栏目 public function edit() { if ($this->request->isPost()) { $catid = $this->request->param('id/d', 0); $row = $this->modelClass->get($catid); if (!$row) { $this->error('记录未找到'); } $data = $this->request->post(); //上级栏目不能是自身 if ($data['parentid'] == $catid) { $this->error('上级栏目不能是自身!'); } switch ($data['type']) { //单页 case 1: $data['modelid'] = 0; $scene = 'page'; break; //列表 case 2: $scene = 'list'; break; //列表 case 3: $data['modelid'] = 0; $scene = 'link'; break; default: $this->error('栏目类型错误~'); } $data['catdir'] = $this->get_dirpinyin($data['catname'], $data['catdir'], $catid); $result = $this->validate($data, 'app\admin\validate\cms\Category.' . $scene); if (true !== $result) { $this->error($result); } try { $row->allowField(true)->save($data); } catch (\Exception $e) { $this->error($e->getMessage()); } $this->success("修改成功!"); } else { $catid = $this->request->param('id/d', 0); if (empty($catid)) { $this->error('请选择需要修改的栏目!'); } $data = Db::name('category')->where(['id' => $catid])->find(); $setting = unserialize($data['setting']); //输出可用模型 $modelsdata = cache("Model"); $models = []; foreach ($modelsdata as $v) { if ($v['status'] == 1 && $v['module'] == 'cms') { $models[] = $v; } } //栏目列表 可以用缓存的方式 $array = Db::name('Category')->order('listorder DESC, id DESC')->column('*', 'id'); if (!empty($array) && is_array($array)) { $tree = new \util\Tree(); $tree->icon = ['  │ ', '  ├─ ', '  └─ ']; $tree->nbsp = '  '; $str = ""; $tree->init($array); $categorydata = $tree->getTree(0, $str, $data['parentid']); } else { $categorydata = ''; } $this->assign([ 'data' => $data, 'setting' => $setting, 'category' => $categorydata, 'models' => $models, 'tp_category' => $this->categoryTemplate, 'tp_list' => $this->listTemplate, 'tp_show' => $this->showTemplate, 'tp_page' => $this->pageTemplate, 'privs' => CategoryPrivModel::where('catid', $catid)->select(), "cmsConfig" => get_addon_config("cms"), "Member_Group" => cache("Member_Group"), ]); return $this->fetch(); } } //栏目授权 public function cat_priv() { $act = $this->request->param('act'); $id = $this->request->param('id'); if ($act == 'authorization') { if (empty($id)) { $this->error('请指定需要授权的角色!'); } if ($this->request->isAjax()) { $data = $this->request->post(); $priv = []; if (isset($data['priv'])) { foreach ($data['priv'] as $k => $v) { foreach ($v as $e => $q) { $priv[] = ["roleid" => $id, "catid" => $k, "action" => $q, "is_admin" => 1]; } } Db::name("CategoryPriv")->where("roleid", $id)->delete(); Db::name("CategoryPriv")->insertAll($priv); $this->success("栏目授权成功!"); } else { $this->error('请指定需要授权的栏目!'); } } else { $tree = new \util\Tree(); $tree->icon = ['   │ ', '   ├─ ', '   └─ ']; $tree->nbsp = '   '; $category_priv = Db::name('CategoryPriv')->where("roleid", $id)->select(); $priv = []; foreach ($category_priv as $k => $v) { $priv[$v['catid']][$v['action']] = true; } $categorys = Db::name('category')->order('listorder DESC, id DESC')->select(); foreach ($categorys as $k => $v) { if ($v['type'] == 1 || $v['child']) { $v['disabled'] = 'disabled'; $v['init_check'] = ''; $v['add_check'] = ''; $v['delete_check'] = ''; $v['listorder_check'] = ''; $v['move_check'] = ''; $v['edit_check'] = ''; $v['status_check'] = ''; } else { $v['disabled'] = ''; $v['add_check'] = isset($priv[$v['id']]['add']) ? 'checked' : ''; $v['delete_check'] = isset($priv[$v['id']]['delete']) ? 'checked' : ''; $v['listorder_check'] = isset($priv[$v['id']]['listorder']) ? 'checked' : ''; $v['move_check'] = isset($priv[$v['id']]['remove']) ? 'checked' : ''; $v['edit_check'] = isset($priv[$v['id']]['edit']) ? 'checked' : ''; $v['status_check'] = isset($priv[$v['id']]['status']) ? 'checked' : ''; } $v['init_check'] = isset($priv[$v['id']]['init']) ? 'checked' : ''; $categorys[$k] = $v; } $str = " @spacer@catname "; $tree->init($categorys); $categorydata = $tree->getTree(0, $str); $this->assign("categorys", $categorydata); return $this->fetch('authorization'); } } elseif ($act == 'remove') { Db::name('CategoryPriv')->where('roleid', $id)->delete(); $this->success('删除成功!'); } if ($this->request->isAjax()) { $priv_num = []; $category_priv = Db::name('CategoryPriv')->field("count(*) as num,roleid")->group("roleid")->select(); foreach ($category_priv as $k => $v) { $priv_num[$v['roleid']] = $v['num']; } $_list = Db::name('AuthGroup')->where('status', 1)->order('id', 'desc')->field('id,title')->select(); foreach ($_list as $k => $v) { $_list[$k]['admin'] = $v['id'] == 1; $_list[$k]['num'] = $priv_num[$v['id']] ?? 0; } $result = ["code" => 0, "data" => $_list]; return json($result); } else { $cmsConfig = get_addon_config("cms"); $this->assign("cmsConfig", $cmsConfig); return $this->fetch(); } } //更新栏目缓存并修复 public function public_cache() { $this->repair(); $this->cache(); $this->success("更新缓存成功!", Url("cms/category/index")); } //清除栏目缓存 protected function cache() { cache('Category', null); } //修复栏目数据 private function repair() { //取出需要处理的栏目数据 $categorys = Db::name('Category')->order('listorder DESC, id DESC')->column('*', 'id'); if (empty($categorys)) { return true; } try { if (is_array($categorys)) { foreach ($categorys as $catid => $cat) { //获取父栏目ID列表 $arrparentid = CategoryModel::get_arrparentid($catid); //获取子栏目ID列表 $arrchildid = CategoryModel::get_arrchildid($catid); $child = is_numeric($arrchildid) ? 0 : 1; //是否有子栏目 //检查所有父id 子栏目id 等相关数据是否正确,不正确更新 if ($cat['arrparentid'] != $arrparentid || $cat['arrchildid'] != $arrchildid || $cat['child'] != $child) { Db::name('Category')->where('id', $catid)->update(['arrparentid' => $arrparentid, 'arrchildid' => $arrchildid, 'child' => $child]); } \think\facade\Cache::rm('getCategory_' . $catid, null); //删除在非正常显示的不含信息或子栏目的栏目 if ($cat['parentid'] != 0 && !isset($categorys[$cat['parentid']])) { CategoryModel::destroy($catid); } } } } catch (\Exception $e) { //$this->error($e->getMessage()); } return true; } //重新统计栏目信息数量 public function count_items() { $result = Db::name('Category')->order('listorder DESC, id DESC')->select(); $model_cache = cache("Model"); foreach ($result as $r) { if ($r['type'] == 2) { $modelid = $r['modelid']; if (isset($model_cache[$modelid])) { $number = Db::name(ucwords($model_cache[$modelid]['tablename']))->where('catid', $r['id'])->count(); Db::name('Category')->where('id', $r['id'])->update(['items' => $number]); } else { Db::name('Category')->where('id', $r['id'])->update(['items' => 0]); } } else { Db::name('Category')->where('id', $r['id'])->update(['items' => 0]); } } $this->success("栏目数量校正成功!"); } public function multi() { $id = $this->request->param('id/d'); cache('Category', null); getCategory($id, '', true); return parent::multi(); } //获取栏目的拼音 private function get_dirpinyin($catname = '', $catdir = '', $id = 0) { $pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader'); if (empty($catdir)) { $catdir = $pinyin->permalink($catname, ''); } if (strval(intval($catdir)) == strval($catdir)) { $catdir .= genRandomString(3); } $map = [ ['catdir', '=', $catdir], ]; if (intval($id) > 0) { $map[] = ['id', '<>', $id]; } $result = Db::name('Category')->field('id')->where($map)->find(); if (!empty($result)) { $nowDirname = $catdir . genRandomString(3); return $this->get_dirpinyin($catname, $nowDirname, $id); } return $catdir; } //动态根据模型ID加载栏目模板 public function public_tpl_file_list() { $id = $this->request->param('id/d'); $data = Db::name('Model')->where('id', $id)->find(); if ($data) { $json = ['code' => 0, 'data' => unserialize($data['setting'])]; return json($json); } } }