50], ]; } public function scenarios() { return [ 'addDir' => ['course_id', 'name', 'level', 'sort', 'created_at', 'updated_at'], 'addSubDir' => ['course_id', 'name', 'parent_id', 'level', 'sort', 'created_at', 'updated_at'], 'rename' => ['id', 'name'], 'default' => [], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'mall_id' => '商城id', 'course_id' => '课程id', 'parent_id' => '父级目录ID', 'level' => '目录等级 默认1', 'name' => '目录名称', 'sort' => '目录排序', 'status' => '状态 0禁用,1启用,-1是删除', 'created_at' => 'Created At', 'updated_at' => 'Updated At', ]; } public static function setData(int $mall_id, array $data, string $scenarios = 'default') { if (!empty($data['id'])) { $model = self::findOne(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $data['id']]); if (empty($model)) { self::$static_error = '数据异常'; return false; } } else { $model = new self(); $model->loadDefaultValues(); $model->mall_id = $mall_id; $model->status = StatusEnum::ENABLED; } $model->scenario = $scenarios; foreach ($data as $key => $val) { $model->$key = $val; } if (!$model->save()) { self::$static_error = '保存数据失败:' . $model->getErrorMessage(); return false; } return $model; } /** * @name: * @msg: 获取某一个课程下的目录列表 * @param {int} $mall_id * @param {int} $course_id * @param {string} $field * @return {*} */ public static function getList(int $mall_id, int $course_id, string $field = '*') { $list = self::find() ->select($field) ->where(['mall_id' => $mall_id, 'course_id' => $course_id, 'status' => StatusEnum::ENABLED]) ->andWhere('id != 0') ->orderBy('sort asc,created_at desc') ->asArray() ->all(); return $list; } /** * @name: * @msg: 分别统计某一个课程下各个目录下的章节的数量 * @param {array} $list 某一个课程下的目录列表,必须包含目录id字段,并且字段名为 id * @param {int} $mall_id * @return {*} */ public static function chapterSum(array $list, int $mall_id, int $course_id) { // 目录和章节数映射 // dd($list); // 课程所有目录 id if (!empty($list)) { $dir_ids = array_values(array_flip(array_flip(array_column($list, 'id', 'id')))); // dd($dir_ids, false); foreach ($dir_ids as $idk => $idv) { // 目录下的章节数量,初始化为 0 $dir_chapter_sum[$idv] = 0; } // dd($dir_chapter_sum, false); $dir_chapter_info = AddonsCourseChapter::find() ->select('id,dir_id') ->where(['mall_id' => $mall_id, 'dir_id' => $dir_ids, 'course_id' => $course_id, 'status' => StatusEnum::ENABLED]) ->asArray() ->all(); $all_count = count($dir_chapter_info); // dd(array_unique(array_column($dir_chapter_info, 'dir_id'))); // dd($dir_chapter_info); if (!empty($dir_chapter_info)) { foreach ($dir_chapter_info as $dk => $dv) { // if (empty($dir_chapter_sum[$dv['dir_id']])) { // $dir_chapter_sum[$dv['dir_id']] = 0; // } $dir_chapter_sum[$dv['dir_id']] += 1; } } // dd($dir_chapter_sum); foreach ($list as $lk => $lv) { if (!empty($dir_chapter_sum[$lv['id']])) { $list[$lk]['chapter_number'] = $dir_chapter_sum[$lv['id']]; // $dir_chapter_number_map[$lv['id']] = $dir_chapter_sum[$lv['id']]; } else { // $dir_chapter_number_map[$lv['id']] = 0; $list[$lk]['chapter_number'] = 0; } $tmp_list[$lv['parent_id']][] = $lv; } // dd($dir_chapter_sum); // dd($tmp_list); // 组装二级目录的树形结构 $tree = $tmp_list[0]; foreach ($tree as $lpk => $lpv) { foreach ($list as $lk => $lv) { if ($lpv['id'] == $lv['parent_id']) { $tree[$lpk]['sub_dir'][] = $lv; } } } // dd($tree); foreach ($tree as $trk => $trv) { $tree[$trk]['chapter_number'] = $dir_chapter_sum[$trv['id']]; if (!empty($trv['sub_dir'])) { $tree[$trk]['chapter_number'] += array_sum(array_column($trv['sub_dir'], 'chapter_number')); } } // dd($tree); // 未分类的章节 $no_dir_chapters = AddonsCourseChapter::find() ->where(['mall_id' => $mall_id, 'dir_id' => 0, 'course_id' => $course_id, 'status' => StatusEnum::ENABLED]) ->asArray() ->all(); $no_dir_count = count($no_dir_chapters); $tree[] = [ 'id' => 0, 'name' => '未分类', 'course_id' => $course_id, 'parent_id' => 0, 'chapter_number' => $no_dir_count, ]; // dd($tree); $res = ['all_count' => $all_count + $no_dir_count, 'tree' => $tree]; } else { // dd(13213231321322331); // 当前课程没有设置目录 $dir_ids = 0; $dir_chapter_info = AddonsCourseChapter::find() ->select('id,dir_id') ->where(['mall_id' => $mall_id, 'dir_id' => $dir_ids, 'course_id' => $course_id, 'status' => StatusEnum::ENABLED]) ->asArray() ->all(); $all_count = count($dir_chapter_info); $res = [ 'all_count' => $all_count, 'tree' => [ [ 'id' => 0, 'name' => '未分类', 'course_id' => $course_id, 'parent_id' => 0, 'chapter_number' => $all_count, ] ], ]; } return $res; } public static function getDirTreeList(int $mall_id, int $course_id, string $field = '*') { // $course_id = 1212121; $list = self::getList($mall_id, $course_id, $field); $tree_info = self::chapterSum($list, $mall_id, $course_id); return $tree_info; } /** * @name: * @msg: 获取同级最后一个目录的排序 * @param {int} $mall_id * @param {int} $course_id * @param {int} $parent_id * @param {int} $level * @return {int} */ public static function getLastSort(int $mall_id, int $course_id, int $parent_id, int $level): int { $prev_sort = self::find() ->select('sort') ->where(['mall_id' => $mall_id, 'course_id' => $course_id, 'parent_id' => $parent_id, 'level' => $level, 'status' => StatusEnum::ENABLED]) ->orderBy('sort desc') ->limit(1) ->asArray() ->one(); // dd($prev_sort); if (!empty($prev_sort['sort'])) { $sort = $prev_sort['sort'] + 1; } else { $sort = 1; } return $sort; } /** * @name: * @msg: 获取某一个目录相邻的目录的排序(上一个或者下一个) * @param {int} $id 当前目录的 id * @param {int} $course_id 课程 id * @param {int} $parent_id 父级目录 id * @param {int} $level 当前目录级别 * @param {int} $type 获取目录的方向,1:上一个,2:下一个 * @return {array} 包含相邻目录的id和排序的一个一维数组 */ public static function adjoinSort(int $id, int $mall_id, int $course_id, int $parent_id, int $level, int $type): array { // var_dump($id, $mall_id, $course_id, $parent_id, $level, $type);exit; $model = self::find() ->select('id,sort') ->where(['mall_id' => $mall_id, 'course_id' => $course_id, 'parent_id' => $parent_id, 'level' => $level, 'status' => StatusEnum::ENABLED]); $current_sort = self::getCurrentSort($mall_id, $id); // dd($current_sort); if (1 == $type) { $order = 'desc'; $model->andWhere(['<', 'sort', $current_sort]); } else { $order = 'asc'; $model->andWhere(['>', 'sort', $current_sort]); } $adjoin_info = $model ->orderBy('sort ' . $order . ',created_at desc') ->limit(1) ->asArray() ->one(); // dd($adjoin_info); return $adjoin_info; } /** * @name: * @msg: 获取当前目录的排序 * @param {int} $mall_id * @param {int} $id * @return {*} */ public static function getCurrentSort(int $mall_id, int $id): int { $dir_info = self::find() ->select('sort') ->where(['mall_id' => $mall_id, 'id' => $id, 'status' => StatusEnum::ENABLED]) ->limit(1) ->asArray() ->one(); if (empty($dir_info)) { $sort = 1; } else { $sort = $dir_info['sort']; } return $sort; } public static function switchDirSort(int $dir_id, int $mall_id, int $sort_type) : bool { $dir_info = self::find() ->select('id,mall_id,course_id,parent_id,level') ->where(['id' => $dir_id, 'mall_id' => $mall_id]) ->asArray() ->one(); if (empty($dir_info)) { self::$static_error = '目录不存在'; return false; } $dir_info['type'] = $sort_type; // dd($dir_info); // 相邻目录 $adjoin_info = self::adjoinSort(...array_values($dir_info)); // dd($adjoin_info); // 当前目录 $curr_info = [ 'id' => $dir_id, 'sort' => self::getCurrentSort($mall_id, $dir_id), ]; // dd($curr_info); // 与相邻目录互换排序 $tmp_sort = $curr_info['sort']; $curr_info['sort'] = $adjoin_info['sort']; $adjoin_info['sort'] = $tmp_sort; $transaction = \Yii::$app->db->beginTransaction(); $current_params = [ 'id' => $curr_info['id'], 'sort' => $curr_info['sort'], ]; // 更新当前目录 $curr_res = self::setData($mall_id, $current_params); if (false === $curr_res) { $transaction->rollBack(); return false; } // 更新相邻目录 $adjoin_params = [ 'id' => $adjoin_info['id'], 'sort' => $adjoin_info['sort'], ]; $adjoin_res = self::setData($mall_id, $adjoin_params); if (false === $adjoin_res) { $transaction->rollBack(); return false; } $transaction->commit(); return true; } }