444 lines
12 KiB
PHP
444 lines
12 KiB
PHP
<?php
|
|
|
|
namespace app\admin\controller\course;
|
|
|
|
use app\common\controller\Backend;
|
|
use think\Db;
|
|
|
|
/**
|
|
* 课程分组管理
|
|
*/
|
|
class Group extends Backend
|
|
{
|
|
|
|
protected $model = null;
|
|
protected $groupBindModel = null;
|
|
|
|
public function _initialize()
|
|
{
|
|
parent::_initialize();
|
|
$this->model = new \app\admin\model\course\Group;
|
|
$this->groupBindModel = new \app\admin\model\course\GroupBind();
|
|
}
|
|
|
|
/**
|
|
* 查看
|
|
*/
|
|
public function index()
|
|
{
|
|
$this->request->filter(['strip_tags', 'trim']);
|
|
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
|
|
|
|
$list = $this->model
|
|
->where($where)
|
|
->where(['uniacid' => UNIACID])
|
|
->order($sort, $order)
|
|
->paginate($limit);
|
|
|
|
$rows = $list->toArray();
|
|
|
|
if (!empty($rows['data'])) {
|
|
foreach ($rows['data'] as &$item) {
|
|
$item['course_count'] = $this->groupBindModel->groupGetCourseBindCount($item['id']);
|
|
}
|
|
}
|
|
|
|
$result = array("total" => $rows['total'], "rows" => $rows['data'], 'attr' => [
|
|
'status' => $this->model->getStatusList()
|
|
]);
|
|
|
|
return $this->success("获取成功", $result);
|
|
}
|
|
|
|
/**
|
|
* 获取分组树(4级)
|
|
*/
|
|
public function tree()
|
|
{
|
|
$list = $this->model
|
|
->where(['uniacid' => UNIACID, 'parent_id' => 0])
|
|
->order('sort', 'asc')
|
|
->order('id', 'asc')
|
|
->select();
|
|
|
|
$result = [];
|
|
foreach ($list as $item) {
|
|
$result[] = $this->getGroupTree($item);
|
|
}
|
|
|
|
return $this->success("获取成功", $result);
|
|
}
|
|
|
|
/**
|
|
* 递归获取分组树(4级)
|
|
*/
|
|
protected function getGroupTree($group)
|
|
{
|
|
$data = $group->toArray();
|
|
$children = $this->model
|
|
->where(['uniacid' => UNIACID, 'parent_id' => $group['id']])
|
|
->order('sort', 'asc')
|
|
->order('id', 'asc')
|
|
->select();
|
|
|
|
if (!empty($children)) {
|
|
$data['children'] = [];
|
|
foreach ($children as $child) {
|
|
$data['children'][] = $this->getGroupTree($child);
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 添加
|
|
*/
|
|
public function add()
|
|
{
|
|
$params = $this->request->param('row/a');
|
|
if (empty($params)) {
|
|
$this->error(__('Parameter %s can not be empty', ''));
|
|
}
|
|
$params = $this->preExcludeFields($params);
|
|
|
|
$params['uniacid'] = UNIACID;
|
|
$params['createtime'] = time();
|
|
|
|
if (!isset($params['sort'])) {
|
|
$params['sort'] = $this->model->defineSort();
|
|
}
|
|
|
|
$result = $this->model->allowField(true)->save($params);
|
|
|
|
if ($result !== false) {
|
|
$this->success("添加成功");
|
|
} else {
|
|
$this->error(__('No rows were inserted'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 编辑
|
|
*/
|
|
public function edit($ids = null)
|
|
{
|
|
$params = $this->request->param('row/a');
|
|
if (empty($params)) {
|
|
$this->error(__('Parameter %s can not be empty', ''));
|
|
}
|
|
$params = $this->preExcludeFields($params);
|
|
|
|
$row = $this->model->where('id', $ids)->where('uniacid', UNIACID)->find();
|
|
if (!$row) {
|
|
$this->error(__('No Results were found'));
|
|
}
|
|
|
|
$result = $row->allowField(true)->save($params);
|
|
|
|
if ($result !== false) {
|
|
$this->success("更新成功");
|
|
} else {
|
|
$this->error(__('No rows were updated'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 删除
|
|
*/
|
|
public function del($ids = "")
|
|
{
|
|
if ($ids) {
|
|
// 检查是否有子分组
|
|
$hasChildren = $this->model->where('parent_id', 'in', $ids)->where('uniacid', UNIACID)->find();
|
|
if ($hasChildren) {
|
|
$this->error('该分组下存在子分组,请先删除子分组');
|
|
}
|
|
|
|
$count = $this->model->where('id', 'in', $ids)->where('uniacid', UNIACID)->delete();
|
|
if ($count) {
|
|
// 删除关联的课程绑定
|
|
foreach (explode(',', $ids) as $id) {
|
|
$this->groupBindModel->groupDelCourseBind($id);
|
|
}
|
|
$this->success("删除成功");
|
|
} else {
|
|
$this->error(__('No rows were deleted'));
|
|
}
|
|
}
|
|
$this->error(__('Parameter %s can not be empty', 'ids'));
|
|
}
|
|
|
|
/**
|
|
* 获取状态列表
|
|
*/
|
|
public function getStatusList()
|
|
{
|
|
$this->success("获取成功", $this->model->getStatusList());
|
|
}
|
|
|
|
/**
|
|
* 根据ID获取分组信息
|
|
*/
|
|
public function info($ids = null)
|
|
{
|
|
$row = $this->model
|
|
->where('id', $ids)
|
|
->where('uniacid', UNIACID)
|
|
->find();
|
|
|
|
if (!$row) {
|
|
$this->error(__('No Results were found'));
|
|
}
|
|
|
|
$data = $row->toArray();
|
|
|
|
// 获取父级信息
|
|
if ($data['parent_id'] > 0) {
|
|
$parent = $this->model
|
|
->where('id', $data['parent_id'])
|
|
->where('uniacid', UNIACID)
|
|
->find();
|
|
$data['parent_name'] = $parent ? $parent['name'] : '';
|
|
} else {
|
|
$data['parent_name'] = '';
|
|
}
|
|
|
|
$this->success("获取成功", $data);
|
|
}
|
|
|
|
/**
|
|
* 批量保存分组(前端完成所有操作后一次性提交)
|
|
*
|
|
* @param array original_ids 原始数据中的所有分组ID列表
|
|
* @param array groups 完整的树形分组结构数据
|
|
*/
|
|
public function save()
|
|
{
|
|
$originalIds = $this->request->param('original_ids/a', []);
|
|
$groups = $this->request->param('groups/a', []);
|
|
|
|
if (empty($groups)) {
|
|
$this->error('分组数据不能为空');
|
|
}
|
|
|
|
// 提取当前提交的所有ID
|
|
$currentIds = $this->extractAllIds($groups);
|
|
|
|
// 找出需要删除的ID(在original_ids中存在,但不在currentIds中)
|
|
$toDelete = array_diff($originalIds, $currentIds);
|
|
|
|
// 分组处理数据,按层级分组(4级:0, 1, 2, 3)
|
|
$toAdd = [0 => [], 1 => [], 2 => [], 3 => []];
|
|
$toUpdate = [0 => [], 1 => [], 2 => [], 3 => []];
|
|
|
|
$this->categorizeDataByLevel($groups, $toAdd, $toUpdate);
|
|
|
|
// 开始事务
|
|
Db::startTrans();
|
|
$result = null;
|
|
$error = null;
|
|
|
|
try {
|
|
$addedCount = 0;
|
|
$updatedCount = 0;
|
|
$deletedCount = 0;
|
|
|
|
// 1. 先删除(从叶子节点开始,避免外键约束问题)
|
|
if (!empty($toDelete)) {
|
|
$deleteList = $this->model
|
|
->where('id', 'in', $toDelete)
|
|
->where('uniacid', UNIACID)
|
|
->order('id', 'desc')
|
|
->select();
|
|
|
|
foreach ($deleteList as $item) {
|
|
$deletedCount += $this->deleteGroupRecursive($item['id']);
|
|
}
|
|
}
|
|
|
|
// 2. 更新现有数据(按层级顺序)
|
|
$idMapping = [];
|
|
|
|
for ($level = 0; $level <= 3; $level++) {
|
|
usort($toUpdate[$level], function ($a, $b) {
|
|
return $a['sort'] - $b['sort'];
|
|
});
|
|
|
|
foreach ($toUpdate[$level] as $item) {
|
|
$id = $item['id'];
|
|
unset($item['id']);
|
|
unset($item['children']);
|
|
unset($item['level']);
|
|
|
|
$this->model->where('id', $id)->where('uniacid', UNIACID)->update($item);
|
|
$updatedCount++;
|
|
}
|
|
}
|
|
|
|
// 3. 新增数据 - 按原始树形结构顺序保存
|
|
$this->saveAddedGroups($groups, $idMapping, $addedCount);
|
|
|
|
Db::commit();
|
|
|
|
$result = [
|
|
'added' => $addedCount,
|
|
'updated' => $updatedCount,
|
|
'deleted' => $deletedCount,
|
|
'id_mapping' => $idMapping
|
|
];
|
|
} catch (\Exception $e) {
|
|
Db::rollback();
|
|
$error = $e->getMessage();
|
|
}
|
|
|
|
if ($error) {
|
|
$this->error('保存失败:' . $error);
|
|
} else {
|
|
$this->success('保存成功', $result);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 递归删除分组及其子分组
|
|
*/
|
|
protected function deleteGroupRecursive($groupId)
|
|
{
|
|
$count = 0;
|
|
|
|
// 先删除子分组
|
|
$children = $this->model
|
|
->where('parent_id', $groupId)
|
|
->where('uniacid', UNIACID)
|
|
->column('id');
|
|
|
|
foreach ($children as $childId) {
|
|
$count += $this->deleteGroupRecursive($childId);
|
|
}
|
|
|
|
// 删除关联的课程绑定
|
|
$this->groupBindModel->groupDelCourseBind($groupId);
|
|
|
|
// 再删除当前分组
|
|
$count += $this->model->where('id', $groupId)->where('uniacid', UNIACID)->delete();
|
|
|
|
return $count;
|
|
}
|
|
|
|
/**
|
|
* 从树形结构中提取所有ID
|
|
*/
|
|
protected function extractAllIds($groups)
|
|
{
|
|
$ids = [];
|
|
foreach ($groups as $item) {
|
|
$ids[] = abs($item['id']);
|
|
if (!empty($item['children'])) {
|
|
$ids = array_merge($ids, $this->extractAllIds($item['children']));
|
|
}
|
|
}
|
|
return array_unique($ids);
|
|
}
|
|
|
|
/**
|
|
* 将数据按层级分类为新增和更新(4级)
|
|
*/
|
|
protected function categorizeDataByLevel($groups, &$toAdd, &$toUpdate, $parentId = 0, $level = 0)
|
|
{
|
|
foreach ($groups as $item) {
|
|
$currentParentId = $item['id'];
|
|
|
|
$item['parent_id'] = $parentId;
|
|
$item['level'] = $level;
|
|
|
|
if ($item['id'] < 0) {
|
|
$toAdd[$level][] = $item;
|
|
} else {
|
|
$toUpdate[$level][] = $item;
|
|
}
|
|
|
|
if (!empty($item['children'])) {
|
|
$this->categorizeDataByLevel($item['children'], $toAdd, $toUpdate, $currentParentId, $level + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 递归保存新增分组(按原始树形结构顺序)
|
|
*/
|
|
protected function saveAddedGroups($groups, &$idMapping, &$addedCount, $parentId = 0)
|
|
{
|
|
usort($groups, function ($a, $b) {
|
|
return $a['sort'] - $b['sort'];
|
|
});
|
|
|
|
foreach ($groups as $item) {
|
|
$isNew = $item['id'] < 0;
|
|
|
|
if ($isNew) {
|
|
$tempId = $item['id'];
|
|
|
|
$data = [
|
|
'name' => $item['name'],
|
|
'parent_id' => $parentId,
|
|
'status' => isset($item['status']) ? intval($item['status']) : 1,
|
|
'sort' => isset($item['sort']) ? $item['sort'] : 0,
|
|
'uniacid' => UNIACID,
|
|
'createtime' => time(),
|
|
];
|
|
|
|
$newId = $this->model->insertGetId($data);
|
|
$idMapping[$tempId] = $newId;
|
|
$addedCount++;
|
|
|
|
if (!empty($item['children'])) {
|
|
$this->saveAddedGroups($item['children'], $idMapping, $addedCount, $newId);
|
|
}
|
|
} else {
|
|
if (!empty($item['children'])) {
|
|
$this->saveAddedGroups($item['children'], $idMapping, $addedCount, $item['id']);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 设置排序
|
|
*/
|
|
public function setSort($id, $type = 'up')
|
|
{
|
|
$self = $this->model->where('id', $id)->where('uniacid', UNIACID)->find();
|
|
|
|
if (!$self) {
|
|
$this->error(__('No Results were found'));
|
|
}
|
|
|
|
$direction = $type == 'up' ? '<' : '>';
|
|
$sort = $type == 'up' ? 'desc' : 'asc';
|
|
|
|
$brother = $this->model
|
|
->where('sort', $direction, $self['sort'])
|
|
->where('uniacid', UNIACID)
|
|
->order('sort', $sort)
|
|
->find();
|
|
|
|
if (!$brother) {
|
|
$this->error(__('无继续调节空间'));
|
|
}
|
|
|
|
$this->model->where([
|
|
'id' => $self['id']
|
|
])->update([
|
|
'sort' => $brother['sort']
|
|
]);
|
|
|
|
$this->model->where([
|
|
'id' => $brother['id']
|
|
])->update([
|
|
'sort' => $self['sort']
|
|
]);
|
|
|
|
return $this->success("操作成功");
|
|
}
|
|
}
|