request->get('cid'); $parameter->catId = $catId; $parameter->headline = '根分类'; $parameter->logoUrl = ''; if ($cat = DeviceCatRepository::selectOne($catId)) { if ($cat->img_path) { $parameter->logoUrl = ImageManager::getUrl($cat->img_path); } } // 获取所有 < DeviceCatModel::CAT_TREE_MAX_LEVEL 的树 $nodes = DeviceCatRepository::getCatsByWhere(['<', 'level', DeviceCatModel::CAT_TREE_MAX_LEVEL], false); /** * 树处理 */ //父ID $parentId = 0; //点击节点 $selectedId = $catId; $treeArr = $this->buildTree($nodes, $parentId, $selectedId); $treeArr = [ 'id' => "0", 'text' => '设备分类', 'children' => $treeArr, 'state' => [ 'opened' => true ] ]; $catTree = json_encode($treeArr); $deviceList = array(); $pages = null; if (!empty($cat['parent_id'])) { $map = array(); if (!empty($cat['id'])) { $map[] = array("=","d.device_cat_id",$cat['id'],"I"); } /** * 分页处理 */ $deviceModel = new DeviceModel(); $pageSize = $this->request->get("pageSize") ? (int) $this->request->get("pageSize") : 20; $pages = new Pagination(['totalCount' => $deviceModel->getDeviceListCount($map), 'pageSize' => $pageSize]); $deviceList = $deviceModel->getDeviceList($pages->offset,$pages->limit,$map); } return $this->render("index",[ 'catTree' => $catTree, 'parameter' => $parameter, 'treeOptions' => json_encode((array)$this->buildTreeOptions($nodes, 0)), 'deviceList' => $deviceList, 'pages' => $pages ]); } /** * 获取所有设备分类节点 * 获取路径长度不能超过 CAT_TREE_MAX_LEVEL * @return array|\yii\db\ActiveRecord[] */ private function getAllNode() { // 获取所有类目 $nodes = DeviceCatRepository::getCatsByWhere(['<', 'level', DeviceCatModel::CAT_TREE_MAX_LEVEL], false); return $nodes; } /** * 返回指定ID的[子类目ID及本身ID] * @param $id * @return array * 由ID 组成的数组 */ private function getChildrenIds($treeDatas, $id) { $result = []; // 处理获取的数据 $id = (int)$id; $treeDatas = (array)$treeDatas; // ID处理 if (!$id) { return $result; } $result[] = $id; foreach ($treeDatas AS $i => $treeData) { if ($id == $treeData['id']) { // 删除已读取的数据 unset($treeDatas[$i]); $result = array_merge($result, $this->getChildrenIds($treeDatas, $treeData['id'])); } } return $result; } /** * 构造树数据 * @param $catDatas 一维数组 * @param int $parentId 父ID * @param int $checkboxId 默认选中 * @return array 返回树状的数组 */ private function buildTree($catDatas, $parentId = 0, $selectedId = 0) { // 处理送过来的数据 $catDatas = (array)$catDatas; $parentId = (int)$parentId; /** * 处理数据 */ $treeChilds = []; foreach ($catDatas AS $i => $catData) { if ($catData['parent_id'] == $parentId) { $child = []; $child['id'] = $catData['id']; $child['text'] = $catData['name']; $child['sort_order'] = $catData['sort_order']; // 默认打开 if (self::CAT_TREE_DEFAULT_OPEN >= $catData['level']) { // 默认选中 if ($catData['id'] == $selectedId) { $child['state'] = ["opened" => true, "selected" => true]; } else { $child['state'] = ["opened" => true ]; } } else { // 默认选中 if ($catData['id'] == $selectedId) { $child['state'] = ["selected" => true, "opened" => true]; } } // 删除已调用的数组 unset($catDatas[$i]); // 回调数据 $buildTree = $this->buildTree($catDatas, $catData['id'], $selectedId); $child['children'] = !empty($buildTree) ? $buildTree : false; $treeChilds[] = $child; } } // 排序 $sortOrders = []; foreach ($treeChilds as $child) { $sortOrders[] = $child['sort_order']; } array_multisort($sortOrders, SORT_ASC, $treeChilds); return $treeChilds; } /** * 构造从类目 $deviceCatId 到一级类目的中文路径 * @param $treeDates * @param $deviceCatId * @return string */ private function buildPath($treeDates, $deviceCatId) { $returnPath = ''; $treeDates = (array)$treeDates; $deviceCatId = (int)$deviceCatId; foreach ($treeDates as $treedate) { if ($deviceCatId == $treedate['id']) { if (0 != $treedate['parent_id']) { $returnPath = $returnPath ? $returnPath . '/' . $treedate['name'] : $treedate['name']; $returnCallback = $this->buildPath($treeDates, $treedate['parent_id']); $returnPath = $returnCallback ? $returnCallback . '/' . $returnPath : $returnPath; } break; } } return $returnPath; } /** * 构造类目select显示数组 * @param $treeDates * @param $parentId * @param array $returnOptions * @return array */ private function buildTreeOptions($treeDates, $parentId, $returnOptions = []) { $treeDates = (array)$treeDates; $parentId = (int)$parentId; foreach ($treeDates as $treeDate) { if ($parentId == $treeDate['parent_id']) { if (0 != $treeDate['parent_id']) { $returnOptions[] = [ 'id' => $treeDate['id'], 'catName' => $this->buildPath($treeDates, $treeDate['id']) ]; } $returnOptions = $this->buildTreeOptions($treeDates, $treeDate['id'], $returnOptions); } } return $returnOptions; } /** * ajax * 新增加类目 */ public function actionAjaxCreateNode() { // 初始化 $result = new stdClass(); $result->code = null; $result->success = false; $result->datas = []; // 父类ID $parentId = (int)$this->request->post('id'); // 新建类名称 $newName = (string)$this->request->post('text'); // 父类下的原有所有子类目IDS,如为空 即新建类目sort_order = 1; $nodeSort = 1; $lastChildCat = DeviceCatModel::find() ->where(['parent_id' => $parentId]) ->orderBy(['sort_order' => SORT_DESC]) ->one(); if ($lastChildCat) { $nodeSort = $lastChildCat->sort_order + 1; } // 父类目数据 $parent = null; if ($parentId != 0) { $parent = DeviceCatRepository::selectOne($parentId); if (!$parent) { $result->code = 101; // 操作有误,请重新操作! return json_encode($result); } } // 新建 $cat = new DeviceCatModel(); $cat->parent_id = $parentId; $cat->name = $newName ? $newName : ''; $cat->level = $parent ? ($parent->level + 1) : 1; $cat->path = $parent ? $parent->path : ''; $cat->sort_order = $nodeSort; // 新建类目, 不能超过设定的数量 if ($cat->level >= DeviceCatModel::CAT_TREE_MAX_LEVEL) { $result->code = 201;//新建类目,不能超于设定的长度 return json_encode($result); } $tr = Yii::$app->db->beginTransaction(); try { if ($cat->save()) { $saveCatId = $cat->attributes['id']; if ($parentId != 0) { // 一级分类不需要更新路径 // 更新新建子类的路径 $cat = DeviceCatRepository::selectOne($saveCatId); $cat->path = $parent ? $parent->path . ',' .$saveCatId : $saveCatId; if ($cat->save()) { $result->success = true; $result->datas = $saveCatId; } else { throw new ErrorException('save create dir path fail.'); } } } else { throw new ErrorException('create dir fail.'); } $tr->commit(); } catch (Exception $e) { $tr->rollBack(); } return json_encode($result); } /** * AJAX * 修改类目名字 */ public function actionAjaxRenameNode() { $result = new stdClass(); $result->code = null; $result->success = false; $result->datas = []; // 类目ID $catId = (int)$this->request->post('id'); // 更新后的类目名称, jsTree提交过来数据 $newName = (string)$this->request->post('text'); // 类目数据 $cat = DeviceCatRepository::selectOne($catId); if (!$cat) { $result->code = 101; return json_encode($result); } $cat->name = $newName; if ($cat->save()) { $result->success = true; } return json_encode($result); } /** * ajax * 类目移动 */ public function actionAjaxMoveNode() { $result = new stdClass(); $result->code = null; $result->success = false; $result->datas = []; // 获取数据 $newParentId = (int)$this->request->post('newParentId'); $newChildNodeIds = (array)$this->request->post('newChildNodeIds'); $currentNodeId = (int)$this->request->post('currentNodeId'); // 处理 if (0 == $currentNodeId) { $result->code = 101; // 请选择操作的类目; return json_encode($result); } // 大于1000不能操作~~ if (1000 < count($newChildNodeIds)) { $result->code = 201; // 操作类目的数量过多,请联系管理员; return json_encode($result); } if (0 == intval($newParentId)) { $order = 0; foreach ($newChildNodeIds as $i=>$newNodeId) { $parentCat = DeviceCatRepository::selectOne($newNodeId); $parentCat->sort_order = $order; $parentCat->save(); $order++; } } else { // 开始排序的基数 $orderBase = 0; // 新父节点数据 $newParentCat = DeviceCatRepository::selectOne($newParentId); // 移动节点数据 $nodeCat = DeviceCatRepository::selectOne($currentNodeId); if (!$nodeCat) { $result->code = 101; // 请选择操作的类目; return json_encode($result); } // 启动事务入库 $tr = Yii::$app->db->beginTransaction(); try { // 处理 新父类 下子节点的排序 $order = $orderBase; $result->datas = $newChildNodeIds; foreach ($newChildNodeIds as $i=>$newNodeId) { $cat = DeviceCatRepository::selectOne($newNodeId); // 移动节点 if ($currentNodeId == $newNodeId) { $cat->parent_id = $newParentCat ? $newParentCat->id : 0; $cat->path = $newParentCat ? $newParentCat->path . ',' . $currentNodeId : $currentNodeId; $cat->level = $newParentCat ? $newParentCat->level + 1 : 1; } $cat->sort_order = $order; if (!$cat->save()) { throw new Exception('save id='. $newNodeId . ' fail.'); } $order++; } $tr->commit(); } catch (Exception $e) { $tr->rollBack(); } } $result->success = true; return json_encode($result); } /** * AJAX * 删除类目的显示 */ public function actionAjaxRemoveNode() { $result = new stdClass(); $result->code = null; $result->success = false; $result->datas = []; $catIds = (array) $this->request->post('catIds'); // 大于100不能操作~~ if (100 < count($catIds)) { $result->code = 301; // 操作类目的数量过多,请联系管理员; return json_encode($result); } // 验证 $children = DeviceCatRepository::getCatsByWhere(['parent_id' => $catIds], 100); if ($children) { $result->code = 101; // 类目还有子类目,不能进行删除操作 return json_encode($result); } $cats = DeviceCatRepository::getCatsByIds($catIds); $cats = (array)$cats; $catResult = []; foreach ($cats AS $cat) { if (!empty($cat->devices)) { $result->code = 201; // 类目下还有设备, 不能进行删除操作 return json_encode($result); } $catResult[] = [ 'id' => $cat->id ]; } $result->datas = $catResult; $result->success = true; return json_encode($result); } /** * AJAX * 删除类目 删除 */ public function actionAjaxDoRemoveNode() { $result = new stdClass(); $result->code = null; $result->datas = []; $result->success = false; $catIds = (array)$this->request->post('ids'); // 大于100不能操作~~ if (1000 < count($catIds)) { $result->code = 401; // 操作类目的数量过多,请联系管理员; return json_encode($result); } // 处理获取的数据 $cats = DeviceCatRepository::getCatsByIds($catIds); if (!$cats) { $result->code = 101; // 操作有误,请重新操作 return json_encode($result); } $cats = (array)$cats; foreach ($cats as $cat) { if ((DeviceCatModel::CAT_TREE_MAX_LEVEL > $cat->level)) { // 不是根目类目,也不是末位类目 // 验证是不明是末位类目 if (!$this->validateLastNode($cat->id)) { $result->code = 301; // 该类目下还有子类目,请删除该类目的子类. return json_encode($result); } } } // 删除类目 //$all = DeviceCatModel::find()->where(['id' => $catIds])->all(); foreach ($cats as $a) { $a->delete(); } $result->datas = $catIds; $result->pid = $cats[0]->parent_id; $result->success = true; return json_encode($result); } /** * 判断是否叶子节点 * @param $dirId * @return bool * 返回 TRUE 表示是末位 false表示不是 */ private function validateLastNode($catId) { //true 是末位 false 不是末位 $result = false; // 处理获取数据 $catId = (int)$catId; // 查询数据 $cat = DeviceCatRepository::getSubCatsByParentId($catId); if (!$cat) { $result = true; } return $result; } /** * 三级联动回调 */ public function actionAjaxChildren($parentId) { $options = DeviceCatRepository::options($parentId); echo $this->renderPartial('options', [ 'options' => $options, ]); } /** * AJAX * 保存分类图标题 */ public function actionAjaxUploadLogo($cid) { $cat = DeviceCatRepository::selectOne($cid); if (empty($_FILES['logo']['name'])) { return json_encode([ 'success' => false ]); } $image = $_FILES['logo']; // 图片路径数据整理 $tmp = explode('.', $image['name']); $suffix = end($tmp); $savePath = ImageManager::getDeviceCatIconPath($cid, $suffix); ImageManager::add($image["tmp_name"], $savePath); $cat->img_path = $savePath; $cat->save(); /** * 后台操作日志 */ AdminLogs::doImport('设备分类图片', 1); return json_encode([ 'success' => true, ]); } /** * 执行运营分类数据导入操作 * @return string * @throws ErrorException * @throws yii\db\Exception */ public function actionAjaxDoImport() { // 采用虚拟根目录方式 $virtaulRootcat = new DeviceCatModel(); $virtaulRootcat->id = $this::VIRTUAL_ROOT_CAT_ID; $virtaulRootcat->parent_id = -1; $virtaulRootcat->name = '设备分类'; $virtaulRootcat->level = 0; $virtaulRootcat->sort_order = 0; $virtaulRootcat->path = '0'; // 初始化 $result = new stdClass(); $result->code = null; $result->datas = []; $result->success = false; // 先清空运营分类表 Yii::$app->db->createCommand()->truncateTable('device_cat')->execute(); // 换成用户上传的Excel表文件路径 $importFilePath = Yii::getAlias('@webroot') . '/tmp/device_cat.xlsx';; $objReader = null; $objPHPExcel = null; $currentSheet = null; try { $objReader = \PHPExcel_IOFactory::createReaderForFile($importFilePath); $objPHPExcel = $objReader->load($importFilePath); $objPHPExcel->setActiveSheetIndex(0); $currentSheet = $objPHPExcel->getSheet(0);//载入文件并获取第一个sheet $total_line = $currentSheet->getHighestRow(); $total_column = $currentSheet->getHighestColumn(); } catch (\Exception $e) { $result->code = 101; // Excel表格式错误; return json_encode($result); } // 当前一级父类ID $parentId1 = $this::VIRTUAL_ROOT_CAT_ID; // 当前二级父类ID $parentId2 = $this::VIRTUAL_ROOT_CAT_ID; // 事务 $transaction = Yii::$app->db->beginTransaction(); try { for ($row = 2; $row <= $total_line; $row++) { $data = array(); for ($column = 'A'; $column <= $total_column; $column++) { $cellValue = $currentSheet->getCell($column . $row)->getValue(); if (!$cellValue) { continue; // 无效空单元格(因为分类表按照三级结构,出现占用多个单元格情况) } // 当前单元格内容值作为要创建的[分类名称] $catName = $cellValue; // 当前分类层级 $level = ord($column) - ord('A') + 1; $createParentId = $this::VIRTUAL_ROOT_CAT_ID; // 一级分类直接插入数据库, 并更新当前父类ID: if ($level == 1) { // 当前创建的是一级分类, 父类是[根分类] $createParentId = $this::VIRTUAL_ROOT_CAT_ID; } elseif ($level == 2) { // 当前创建的是二级分类 $createParentId = $parentId1; } elseif ($level == 3) { // 当前创建的是三级分类 $createParentId = $parentId2; } // 父类目数据 $parent = null; if ($level == 1) { $parent = $virtaulRootcat; } else { $parent = DeviceCatRepository::selectOne($createParentId); if (!$parent) { $result->code = 201; // 找不到父级分类; return json_encode($result); } } // 父类下的原有所有子类目IDS,如为空 即新建类目sort_order = 1; $nodes = DeviceCatRepository::findAll(['parent_id' => $createParentId]); $sortOrderArray[0] = $parent['sort_order']; // 第一个元素是父类的排序ID $index = 0; foreach ($nodes AS $nodeData) { $sortOrderArray[$index++] = $nodeData['sort_order']; } // 获取最后的一个ID $sort_order = max($sortOrderArray); unset($nodes); unset($sortOrderArray); // 新建类目的SORT_ORDER值 $nodeSort = $sort_order + 1; // 新建 $cat = new DeviceCatModel(); $cat->parent_id = $parent->id; $cat->name = $catName ? $catName : ''; $cat->level = (int)$parent->level + 1; $cat->path = $parent->path; $cat->sort_order = $nodeSort; // 保存 if ($cat->save()) { // 获取新记录的ID $saveCatId = $cat->attributes['id']; // 更新新建子类的路径 $cat = DeviceCatRepository::selectOne($saveCatId); $cat->path = $parent->path . ',' . $saveCatId; if ($cat->save()) { // 添加成功, 把当前分类ID设置为父类ID, 用于创建它的子分类 if ($level == 1) { $parentId1 = $saveCatId; } elseif ($level == 2) { $parentId2 = $saveCatId; } elseif ($level == 3) { } } else { throw new ErrorException('添加分类path路径失败!'); } } else { throw new ErrorException('添加分类失败!'); } // 销毁变量 unset($cat, $parent); } } // 提交事务 $transaction->commit(); } catch (Exception $e) { // 回滚 $transaction->rollBack(); $result->code = 301; // 数据库写入失败; return json_encode($result); } $result->success = true; return json_encode($result); } }