Org.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. <?php
  2. namespace app\admin\controller\base\org;
  3. /**
  4. * @title : 组织
  5. * @desc :
  6. * @Author : Rock
  7. * @Date : 2023-01-16 10:11:36
  8. */
  9. use app\admin\controller\Base;
  10. use app\common\model\base\org\Org as OrgModel;
  11. use app\common\model\base\org\OrgType as OrgTypeModel;
  12. use app\common\model\base\org\OrgRole as OrgRoleModel;
  13. use app\common\model\base\user\User as UserModel;
  14. use app\common\model\base\menu\Menu;
  15. use app\common\model\base\menu\Menurequest;
  16. use app\common\model\base\menu\Frontmenus;
  17. use daorui\platform\platformAuth;
  18. use think\facade\Db;
  19. class Org extends Base
  20. {
  21. private $orgModel = null;
  22. private $orgRoleModel = null;
  23. private $userModel = null;
  24. protected $noNeedLogin = [];
  25. protected $noNeedAuth = ['getTree'];
  26. public function initialize()
  27. {
  28. parent::initialize();
  29. $this->orgModel = new OrgModel;
  30. $this->orgRoleModel = new OrgRoleModel;
  31. $this->userModel = new UserModel;
  32. }
  33. /**
  34. * @title: 创建统一查询条件
  35. * @desc: 描述
  36. * @return {*}
  37. * @author: Rock
  38. * @method: POST
  39. * @Date: 2023-02-01 09:09:06
  40. */
  41. private function createWhere()
  42. {
  43. $where = [];
  44. $data = $this->request->param();
  45. if (!empty($data['type'])) {
  46. $where[] = ['type', '=', $data['type']];
  47. }
  48. if (!empty($data['status'])) {
  49. $where[] = ['status', '=', $data['status']];
  50. }
  51. if (!empty($data['pid'])) {
  52. $where[] = ['pid', '=', $data['pid']];
  53. } elseif (!$this->userinfo['is_developer']) {
  54. $data['pid'] = $this->userinfo['org_id'];
  55. $where[] = ['pid', '=', $data['pid']];
  56. } else {
  57. if (empty($data['keyword'])) {
  58. $where[] = ['pid', '=', 0];
  59. }
  60. }
  61. if (!empty($data['keyword'])) {
  62. $keyword = $data['keyword'];
  63. $where[] = ['name', 'LIKE', "%$keyword%"];
  64. }
  65. return $where;
  66. }
  67. /**
  68. * Desc :获取组织架构
  69. * User : zwq
  70. * Date : 2025-01-23 10:23
  71. */
  72. public function getOrgs()
  73. {
  74. $data = $this->request->param();
  75. $res = (new platformAuth())->interfaceRequest('getOrg', $data);
  76. if (!$res['code']) return res(2, $res['msg'] ?? '获取失败');
  77. $orgData = $res['data'];
  78. print_r($orgData);
  79. // 遍历数据并写入数据库
  80. foreach ($orgData as $item) {
  81. $primaryKey = $item['org_id']; // 假设主键字段名为 id
  82. $org = OrgModel::find($primaryKey);
  83. unset($item['menu_ids']);
  84. unset($item['request_ids']);
  85. unset($item['front_ids']);
  86. if ($org) {
  87. // 如果记录已存在,更新数据
  88. $org->save($item);
  89. } else {
  90. // 如果记录不存在,创建新记录
  91. OrgModel::create($item);
  92. }
  93. }
  94. return res(1, "获取成功");
  95. }
  96. /**
  97. * @title: 获取组织列表
  98. * @desc: 描述
  99. * @param {int} {pageNo} {0} {页码,不传或传0则不分页}
  100. * @param {int} {pageSize} {10} {每页数量}
  101. * @return {*}
  102. * @author: Rock
  103. * @method: POST
  104. * @Date: 2023-02-01 09:12:42
  105. */
  106. public function getList(int $pageNo = 0, int $pageSize = 10)
  107. {
  108. $where = $this->createWhere();
  109. if ($pageNo) {
  110. $res = OrgModel::where($where)->order("sort ASC")->paginate(['page' => $pageNo, 'list_rows' => $pageSize]);
  111. $total = $res->total();
  112. $list = $res->items();
  113. return pageRes(1, "获取成功", $total, $list);
  114. } else {
  115. $list = OrgModel::where($where)->order("sort ASC")->select();
  116. return res(1, "获取成功", $list);
  117. }
  118. }
  119. /**
  120. * @title: 获取组织简单信息列表
  121. * @param {int} {pid} {非必填,默认值为0} {上级组织ID}
  122. * @param {string} {org_type_code} {非必填} {公司类型编码搜索}
  123. * @param {string} {keyword} {非必填} {字段搜索}
  124. * @return array
  125. * @Author: wangkewei
  126. * @Date: 2021/5/18 9:46
  127. */
  128. public function getSingleList()
  129. {
  130. $field = ['org_id', 'name'];
  131. $where = $this->createWhere();
  132. $list = $this->orgModel->where($where)->field($field)->order('sort ASC,org_id ASC')->select();
  133. return res(1, "获取成功", $list, $where);
  134. }
  135. /**
  136. * @title: 获取组织/企业部门树
  137. * @desc: 描述
  138. * @param {int} {pid} {0} {上级组织ID}
  139. * @return {*}
  140. * @author: Rock
  141. * @method: POST
  142. * @Date: 2023-02-03 10:20:19
  143. */
  144. public function getTree(int $pid = 0)
  145. {
  146. $field = ['org_id', 'org_name'];
  147. $where = [];
  148. $org_id = 0;
  149. if (empty($pid) && !$this->userinfo['is_developer']) {
  150. $org_id = $this->userinfo['org_id'];
  151. }
  152. if (!empty($pid)) {
  153. $parent = OrgModel::where('org_id', $pid)->find();
  154. $where[] = ['lft', '>', $parent->lft];
  155. $where[] = ['rgt', '<', $parent->rgt];
  156. $result = OrgModel::where($where)->order('lft asc')->append(['hasChildren'])->select()->toArray();
  157. $list = array2tree($result, 'pid', 'org_id', $pid);
  158. return res(1, "获取成功", $list);
  159. } elseif (!$this->userinfo['is_developer']) {
  160. $self = OrgModel::where('org_id', $org_id)->find();
  161. $where[] = ['lft', '>=', $self->lft];
  162. $where[] = ['rgt', '<=', $self->rgt];
  163. $result = OrgModel::where($where)->order('lft asc')->append(['hasChildren'])->select()->toArray();
  164. $list = array2tree($result, 'pid', 'org_id', $self->pid);
  165. return res(1, "获取成功", $list);
  166. } else {
  167. $result = OrgModel::where($where)->order('lft asc')->append(['hasChildren'])->select()->toArray();
  168. $list = array2tree($result, 'pid', 'org_id');
  169. return res(1, "获取成功", $list);
  170. }
  171. }
  172. /**
  173. * @title: 添加组织
  174. * @desc: 描述
  175. * @return {*}
  176. * @author: Rock
  177. * @method: POST
  178. * @Date: 2023-03-17 11:23:06
  179. */
  180. public function doAdd()
  181. {
  182. $data = $this->request->param();
  183. $pid = $data['pid'];
  184. $parent = OrgModel::find($pid);
  185. $brother = OrgModel::order('rgt DESC')->find();
  186. if ($parent) {
  187. OrgModel::where('lft', '>', $parent->lft)->update(['lft' => Db::raw('lft+2')]);
  188. OrgModel::where('rgt', '>', $parent->lft)->update(['rgt' => Db::raw('rgt+2')]);
  189. }
  190. if ($parent) {
  191. $data['lft'] = $parent->lft + 1;
  192. $data['rgt'] = $parent->lft + 2;
  193. $data['parent_name'] = $parent->name;
  194. } elseif ($brother) {
  195. $data['lft'] = $brother->rgt + 1;
  196. $data['rgt'] = $brother->rgt + 2;
  197. } else {
  198. $data['lft'] = 1;
  199. $data['rgt'] = 2;
  200. }
  201. $this->orgModel->replace()->save($data);
  202. //
  203. return res(1, "添加成功");
  204. }
  205. /**
  206. * @title: 修改组织
  207. * @desc: 描述
  208. * @return {*}
  209. * @author: Rock
  210. * @method: POST
  211. * @Date: 2023-01-16 10:13:10
  212. */
  213. public function doEdit()
  214. {
  215. $data = $this->request->param();
  216. if (!isset($data['org_id'])) {
  217. return res(2, "参数错误");
  218. }
  219. $org_id = $data['org_id'];
  220. $pid = isset($data['pid']) ? $data['pid'] : 0;
  221. $oldInfo = OrgModel::find($org_id);
  222. $oldParent = OrgModel::find($oldInfo->pid);
  223. $parent = OrgModel::find($pid);
  224. $width = $oldInfo->rgt - $oldInfo->lft + 1;
  225. // 改变了上级组织时进行以下处理
  226. if ($pid != $oldInfo->pid) {
  227. // 提取本节点
  228. $nodeList = OrgModel::where('lft', '>=', $oldInfo->lft)->where('rgt', '<=', $oldInfo->rgt)->column('*', 'org_id');
  229. $nodeList[$org_id]['name'] = $data['name'] ?? '';
  230. $nodeList[$org_id]['short_name'] = $data['short_name'] ?? '';
  231. $nodeList[$org_id]['parent_name'] = $parent ? $parent->name : '';
  232. $nodeList[$org_id]['pid'] = $pid;
  233. $nodeIds = array_keys($nodeList);
  234. // 有新上级节点
  235. if (!empty($parent)) {
  236. // 先算出节点移动的距离
  237. $distance = $parent->rgt - $oldInfo->lft;
  238. // 修改本节点之后的节点
  239. OrgModel::where('lft', '>', $oldInfo->rgt)->update(['lft' => Db::raw("lft - $width")]);
  240. OrgModel::where('rgt', '>', $oldInfo->rgt)->update(['rgt' => Db::raw("rgt - $width")]);
  241. // 上级节点的lft和rgt已经发生变化
  242. $parent = OrgModel::find($pid);
  243. // 插入本节点
  244. $reList = [];
  245. foreach ($nodeList as $node) {
  246. //向后移动
  247. if ($distance >= 0) {
  248. $node['lft'] += $distance - $width;
  249. $node['rgt'] += $distance - $width;
  250. } // 向前移动
  251. else {
  252. $node['lft'] += $distance;
  253. $node['rgt'] += $distance;
  254. }
  255. $reList[] = $node;
  256. }
  257. (new OrgModel)->replace()->saveAll($reList);
  258. // 插入本节点后,修改本节点之后的节点
  259. OrgModel::where('rgt', '>', $parent->rgt)->where('lft', '>', $parent->lft)->where('org_id', 'NOT IN', $nodeIds)->update(['lft' => Db::raw("lft + $width")]);
  260. OrgModel::where('rgt', '>=', $parent->rgt)->where('org_id', 'NOT IN', $nodeIds)->update(['rgt' => Db::raw("rgt + $width")]);
  261. WLog("MoveOrg", "将" . $oldInfo->getAttr('name') . "从" . ($oldInfo->pid != 0 ? $oldInfo->getAttr('name') : "顶级组织") . "移动至" . $parent->getAttr('name') . "下");
  262. return res(1, '操作成功', ['width' => $width, 'distance' => $distance]);
  263. } else {// 无新上级节点
  264. // 修改本节点之后的节点
  265. OrgModel::where('lft', '>', $oldInfo->rgt)->update(['lft' => Db::raw("lft - $width")]);
  266. OrgModel::where('rgt', '>', $oldInfo->rgt)->update(['rgt' => Db::raw("rgt - $width")]);
  267. // 插入本节点
  268. $lastBrother = OrgModel::where('org_id', 'NOT IN', $nodeIds)->order('rgt DESC')->find();
  269. $newLft = $lastBrother->rgt + 1;
  270. $distance = $newLft - $oldInfo->lft;
  271. $reList = [];
  272. foreach ($nodeList as $node) {
  273. $node['lft'] += $distance;
  274. $node['rgt'] += $distance;
  275. $reList[] = $node;
  276. }
  277. (new OrgModel)->replace()->saveAll($reList);
  278. WLog("MoveOrg", "将" . $oldInfo->getAttr('name') . "从" . ($oldInfo->pid != 0 ? $oldInfo->getAttr('name') : "顶级组织") . "移动至顶级组织");
  279. return res(1, '操作成功', ['width' => $width, 'distance' => $distance]);
  280. }
  281. } else {
  282. // 修改本次修改的组织信息
  283. $this->orgModel->replace()->save($data);
  284. // 修改相关父组织为本次修改的组织的信息
  285. $this->orgModel->where('pid', $data['org_id'])->update(['parent_name' => $data['name']]);
  286. return res(1, "修改成功");
  287. }
  288. }
  289. /**
  290. * @title: 删除组织
  291. * @desc: 描述
  292. * @param {int} {id} {} {组织ID}
  293. * @return {*}
  294. * @author: Rock
  295. * @method: POST
  296. * @Date: 2023-02-02 09:07:12
  297. */
  298. public function doDelete(int $id = 0)
  299. {
  300. $info = OrgModel::find($id);
  301. $width = $info['rgt'] - $info['lft'] + 1;
  302. // 删除自己
  303. $info->name .= '(已删除)';
  304. $info->save();
  305. $info->delete();
  306. // 删除下级
  307. $where = [];
  308. $where[] = ['lft', '>', $info->lft];
  309. $where[] = ['lft', '<', $info->rgt];
  310. OrgModel::where($where)->update(['name' => Db::raw("CONCAT(name,'(已删除)')")]);
  311. OrgModel::destroy(function ($query) use ($where) {
  312. $query->where($where);
  313. });
  314. // 修改其他
  315. OrgModel::where('lft', '>', $info->rgt)->update(['lft' => Db::raw("lft - $width")]);
  316. OrgModel::where('rgt', '>', $info->rgt)->update(['rgt' => Db::raw("rgt - $width")]);
  317. return res(1, "删除成功");
  318. }
  319. /**
  320. * @title: 改变状态
  321. * @desc: 描述
  322. * @param {int} $id {} {}
  323. * @return {*}
  324. * @author: wangjunchong
  325. * @method: Post
  326. * @Date: 2023-03-11 09:37:43
  327. */
  328. public function changeStatus(int $org_id = 0)
  329. {
  330. // 改变本组织
  331. $info = OrgModel::find($org_id);
  332. $status = abs(5 - $info->status * 3);
  333. $info->status = $status;
  334. $info->save();
  335. // 改变下级组织
  336. OrgModel::where('lft', '>', $info->lft)->where('rgt', '<', $info->rgt)->update(['status' => $status]);
  337. return res(1, "操作成功");
  338. }
  339. /**
  340. * @title: 获取组织已有的权限
  341. * @desc: 描述
  342. * @param {int} {org_id} {} {组织ID}
  343. * @return {*}
  344. * @author: Rock
  345. * @method: POST
  346. * @Date: 2023-02-02 17:01:50
  347. */
  348. public function getAuthList(int $org_id = 0)
  349. {
  350. try {
  351. $orgInfo = OrgModel::find($org_id);
  352. if ($orgInfo && $orgInfo->isEmpty()) {
  353. return error('未找到此组织');
  354. }
  355. $menu_ids = is_string($orgInfo->menu_ids) ? explode(',', $orgInfo->menu_ids) : $orgInfo->menu_ids;
  356. $request_ids = is_string($orgInfo->request_ids) ? explode(',', $orgInfo->request_ids) : $orgInfo->request_ids;
  357. $front_ids = is_string($orgInfo->front_ids) ? explode(',', $orgInfo->front_ids) : $orgInfo->front_ids;
  358. // 此组织类型的所有菜单权限
  359. $allMenuList = Menu::where('menu_id', 'IN', $menu_ids)->with(['menurequest'])->select()->toArray();
  360. $menuAuthList = [];
  361. foreach ($allMenuList as $menu) {
  362. $MenuItemRequestIds = array_column($menu['menurequest'], 'menu_request_id');
  363. $selected = array_intersect($request_ids, $MenuItemRequestIds);
  364. // 当所有请求权限都勾选了,菜单才会被选中
  365. if (count($selected) == count($MenuItemRequestIds)) {
  366. $menuAuthList[] = $menu['menu_id'];
  367. }
  368. }
  369. $menuAuthList = !empty($menuAuthList) ? array_filter($menuAuthList) : [];
  370. $request_ids = !empty($request_ids) ? array_filter($request_ids) : [];
  371. $front_ids = !empty($front_ids) ? array_filter($front_ids) : [];
  372. $request_ids = array_map('intval', $request_ids);
  373. $front_ids = array_map('intval', $front_ids);
  374. $menuAuthList = array_map('intval', $menuAuthList);
  375. return res(1, '获取成功', ['menuAuthList' => $menuAuthList, 'requestAuthList' => $request_ids, 'frontAuthList' => $front_ids]);
  376. } catch (\Exception $e) {
  377. return res(2, '获取失败', $e->getMessage(), $e->getTrace());
  378. }
  379. }
  380. /**
  381. * @title: 设置组织权限
  382. * @desc: 描述
  383. * @param {int} {org_id} {} {组织ID}
  384. * @param {array} {menuAuthList} {} {菜单权限}
  385. * @param {array} {requestAuthList} {} {请求权限}
  386. * @param {array} {frontAuthList} {} {移动端权限}
  387. * @return {*}
  388. * @author: Rock
  389. * @method: POST
  390. * @Date: 2023-02-02 17:00:27
  391. */
  392. public function setAuth(int $org_id = 0, array $menuAuthList = [], array $requestAuthList = [], array $frontAuthList = [])
  393. {
  394. $menuAuthList = array_unique(array_filter($menuAuthList));
  395. $requestAuthList = array_unique(array_filter($requestAuthList));
  396. $frontAuthList = array_unique(array_filter($frontAuthList));
  397. try {
  398. // 事务开始
  399. OrgModel::startTrans();
  400. $orgInfo = OrgModel::find($org_id);
  401. $oldMenuIds = $orgInfo->menu_ids;
  402. $oldRequestIds = $orgInfo->request_ids;
  403. $oldFrontIds = $orgInfo->front_ids;
  404. $requestMenu = Menurequest::where('menu_request_id', 'IN', $requestAuthList)->column('menu_id');
  405. $menuAuthList = array_unique(array_merge($menuAuthList, $requestMenu));
  406. // 更新组织权限
  407. $orgInfo->menu_ids = $menuAuthList; //菜单权限
  408. $orgInfo->request_ids = $requestAuthList; //请求权限
  409. $orgInfo->front_ids = $frontAuthList; //小程序权限
  410. $orgInfo->save();
  411. // 若有移除的权限,同时企业角色的权限
  412. $delMenuIds = array_values(array_diff($oldMenuIds, $menuAuthList));
  413. $delRequestIds = array_values(array_diff($oldRequestIds, $requestAuthList));
  414. $delFrontIds = array_values(array_diff($oldFrontIds, $frontAuthList));
  415. $WhereOr = [];
  416. // 移除菜单权限
  417. if (!empty($delMenuIds)) {
  418. foreach ($delMenuIds as $menu_id) {
  419. $WhereOr[] = ['menu_ids', 'FIND IN SET', $menu_id];
  420. }
  421. }
  422. // 移除请求权限
  423. if (!empty($delRequestIds)) {
  424. foreach ($delRequestIds as $request_id) {
  425. $WhereOr[] = ['request_ids', 'FIND IN SET', $request_id];
  426. }
  427. }
  428. // 移除手机端权限
  429. if (!empty($delFrontIds)) {
  430. foreach ($delFrontIds as $front_id) {
  431. $WhereOr[] = ['front_ids', 'FIND IN SET', $front_id];
  432. }
  433. }
  434. $orgSaveData = [];
  435. $orgRoleSaveData = [];
  436. if (!empty($WhereOr)) {
  437. $where = [];
  438. $where[] = ['lft', '>=', $orgInfo->lft];
  439. $where[] = ['lft', '<=', $orgInfo->rgt];
  440. $org_ids = OrgModel::where($where)->column('org_id');
  441. // 下级组织列表(不包含本组织,本组织权限已再上面步骤处理过)
  442. $orgList = OrgModel::where('org_id', 'IN', array_diff($org_ids, [$org_id]))->where(function ($query) use ($WhereOr) {
  443. $query->whereOr($WhereOr);
  444. })->select()->toArray();
  445. foreach ($orgList as $orgItem) {
  446. $orgItem['menu_ids'] = array_diff($orgItem['menu_ids'], $delMenuIds);
  447. $orgItem['request_ids'] = array_diff($orgItem['request_ids'], $delRequestIds);
  448. $orgItem['front_ids'] = array_diff($orgItem['front_ids'], $delFrontIds);
  449. $orgSaveData[] = $orgItem;
  450. }
  451. // 本组织及下级组织角色列表
  452. $roleList = OrgRoleModel::where('org_id', 'IN', $org_ids)->where(function ($query) use ($WhereOr) {
  453. $query->whereOr($WhereOr);
  454. })->select()->toArray();
  455. foreach ($roleList as $roleItem) {
  456. $roleItem['menu_ids'] = array_diff($roleItem['menu_ids'], $delMenuIds);
  457. $roleItem['request_ids'] = array_diff($roleItem['request_ids'], $delRequestIds);
  458. $roleItem['front_ids'] = array_diff($roleItem['front_ids'], $delFrontIds);
  459. $orgRoleSaveData[] = $roleItem;
  460. }
  461. (new OrgModel)->replace()->saveAll($orgSaveData);
  462. (new OrgRoleModel)->replace()->saveAll($orgRoleSaveData);
  463. }
  464. OrgModel::commit();
  465. return res(1, '保存成功', $WhereOr);
  466. } catch (\Exception $e) {
  467. OrgModel::rollback();
  468. return res(2, '保存失败', $e->getMessage(), $e->getTrace());
  469. }
  470. }
  471. /**
  472. * @title: 获取上级组织的权限
  473. * @desc: 描述
  474. * @param {int} {pid} {0} {上级组织org_id}
  475. * @return {*}
  476. * @author: Rock
  477. * @method: POST
  478. * @Date: 2023-03-24 11:06:36
  479. */
  480. public function getParentAuth(int $pid = 0)
  481. {
  482. $parent = OrgModel::find($pid);
  483. $menuList = [];
  484. $frontList = [];
  485. if ($parent) {
  486. $menu_ids = $parent->menu_ids;
  487. $request_ids = $parent->request_ids;
  488. $front_ids = $parent->front_ids;
  489. $parentList = Menu::where('menu_id', 'IN', $menu_ids)->column('parent_path');
  490. $parentIds = explode(',', implode(',', $parentList));
  491. $menuList = Menu::where('menu_id', 'IN', $menu_ids)->whereOr('menu_id', 'IN', $parentIds)->with(['menurequest' => function ($query) use ($request_ids) {
  492. $query->where('menu_request_id', 'IN', $request_ids);
  493. }])->order('menu_id asc')->select()->toArray();
  494. $menuList = array2tree($menuList, 'pid', 'menu_id');
  495. $frontList = Frontmenus::where('menu_id', 'IN', $front_ids)->select();
  496. }
  497. return res(1, "获取成功", ['menuList' => $menuList, 'frontList' => $frontList]);
  498. }
  499. }