123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: 审批步骤
  4. // +----------------------------------------------------------------------
  5. // | Author: Michael_xu | gengxiaoxu@5kcrm.com
  6. // +----------------------------------------------------------------------
  7. namespace app\admin\model;
  8. use think\Db;
  9. use app\admin\model\Common;
  10. use think\Request;
  11. use think\Validate;
  12. class ExamineStep extends Common
  13. {
  14. /**
  15. * 为了数据库的整洁,同时又不影响Model和Controller的名称
  16. * 我们约定每个模块的数据表都加上相同的前缀,比如CRM模块用crm作为数据表前缀
  17. */
  18. protected $name = 'admin_examine_step';
  19. /**
  20. * 获取有效审批步骤列表
  21. * @param flow_id 审批流程ID
  22. * @param user_id 审批申请人ID
  23. * @return
  24. */
  25. public function getDataList($flow_id)
  26. {
  27. $userModel = new \app\admin\model\User();
  28. $list = $this->where(['flow_id' => $flow_id])->order('order_id asc')->select();
  29. foreach ($list as $k=>$v) {
  30. $list[$k]['user_id_info'] = $userModel->getListByStr($v['user_id']);
  31. }
  32. return $list ? : [];
  33. }
  34. /**
  35. * 审批步骤(创建、编辑)
  36. * @param flow_id 审批流程ID
  37. * @param status 1负责人主管,2指定用户(任意一人),3指定用户(多人会签),4上一级审批人主管
  38. * @return
  39. */
  40. public function createStepData($data, $flow_id)
  41. {
  42. if (!intval($flow_id)) {
  43. $this->error = '审批流程创建失败';
  44. return false;
  45. }
  46. //处理数据
  47. $resSuccess = true;
  48. $dataStep = [];
  49. foreach ($data as $k=>$v) {
  50. if (!intval($v['status']) || (in_array($v['status'],[2,3]) && !$v['user_id'])) {
  51. $resSuccess = false;
  52. }
  53. $dataStep[$k]['relation'] = 1;
  54. if (in_array($v['status'],[2,3])) {
  55. $dataStep[$k]['user_id'] = $v['user_id'] ? arrayToString($v['user_id']) : ''; //处理user_id
  56. $dataStep[$k]['relation'] = ($v['status'] == 3) ? 1 : 2;
  57. }
  58. if ($v['step']) {
  59. $dataStep[$k]['step_id'] = $v['step'];
  60. }
  61. $dataStep[$k]['order_id'] = $k+1;
  62. $dataStep[$k]['flow_id'] = $flow_id;
  63. $dataStep[$k]['status'] = $v['status'];
  64. $dataStep[$k]['create_time'] = time();
  65. }
  66. if ($resSuccess) {
  67. //提交事务
  68. $this->startTrans();
  69. try {
  70. $this->where(['flow_id' => $flow_id])->delete();
  71. $this->saveAll($dataStep);
  72. $this->commit();
  73. return true;
  74. } catch(\Exception $e) {
  75. $this->error = '审批步骤创建失败';
  76. $this->rollback();
  77. return false;
  78. }
  79. } else {
  80. $this->error = '参数错误';
  81. return false;
  82. }
  83. }
  84. /**
  85. * 审批步骤(排序,防止位置情况造成排序错乱)
  86. * @param flow_id 审批流程ID
  87. * @return
  88. */
  89. public function orderData($flow_id)
  90. {
  91. $step_list = db('admin_examine_step')->where(['flow_id' => $flow_id])->order('order_id')->select();
  92. foreach ($step_list as $k=>$v) {
  93. $data = [];
  94. $data = ['step_id' => $v['step_id'],'order_id' => $k];
  95. db('admin_examine_step')->update($data);
  96. }
  97. }
  98. /**
  99. * 下一审批人(审批是否结束)
  100. * @param user_id 审批申请人ID
  101. * @param flow_id 审批流ID
  102. * @param types 关联对象
  103. * @param types_id 联对象ID
  104. * @param order_id 审批排序ID
  105. * @param status 1负责人主管,2指定用户(任意一人),3指定用户(多人会签),4上一级审批人主管
  106. * @param check_user_id 当前审核人ID
  107. */
  108. public function nextStepUser($user_id, $flow_id, $types, $types_id, $order_id, $check_user_id)
  109. {
  110. $res = nextCheckData($user_id, $flow_id, $types, $types_id, $order_id, $check_user_id);
  111. return $res ? : [];
  112. }
  113. /**
  114. * 审批步骤权限
  115. * @param step_id 审批步骤ID
  116. * @param user_id 审批人ID(当前登录人)
  117. * @param create_user_id 申请人ID
  118. * @param types 关联对象
  119. * @param types_id 联对象ID
  120. * @param status 1负责人主管,2指定用户(任意一人),3指定用户(多人会签),4上一级审批人主管
  121. * @return
  122. */
  123. public function checkExamine($user_id, $types, $types_id)
  124. {
  125. $data = $this->getDataByTypes($types, $types_id);
  126. $dataInfo = $data['dataInfo']; //审批主体信息
  127. $stepInfo = $data['stepInfo']; //审批步骤信息
  128. if (!$dataInfo) {
  129. $this->error = '参数错误!';
  130. return false;
  131. }
  132. if (in_array($dataInfo['check_status'], ['2','3'])) {
  133. $this->error = '审批已经结束!';
  134. return false;
  135. }
  136. if ($dataInfo['flow_id'] > 0) {
  137. //固定流程
  138. //当前步骤已审批user_id
  139. $check_user_ids = $this->getUserByCheck($types, $types_id, $dataInfo['order_id']);
  140. if (in_array($user_id, $check_user_ids)) {
  141. $this->error = '您已审核,请勿重复操作!';
  142. return false;
  143. }
  144. $examine_user_id_arr = array();
  145. // $examine_user_id_arr = $this->getUserByStep($stepInfo['step_id'], $dataInfo['create_user_id']); //获取审批步骤审批人
  146. $examine_user_id_arr = $dataInfo['check_user_id']; //获取审批步骤审批人
  147. $examine_user_id_arr = stringToArray($examine_user_id_arr);
  148. } else {
  149. $examine_user_id_arr = $this->getUserByPer($types);
  150. }
  151. if (!in_array($user_id, $examine_user_id_arr)) {
  152. $this->error = '没有权限';
  153. return false;
  154. }
  155. return true;
  156. }
  157. /**
  158. * 审批对象获取审批相关信息
  159. * @param types 关联对象
  160. * @param types_id 联对象ID
  161. * @return
  162. */
  163. public function getDataByTypes($types, $types_id)
  164. {
  165. if (empty($types) || empty($types_id)) {
  166. $this->error = '参数错误';
  167. return false;
  168. }
  169. switch (trim($types)) {
  170. case 'oa_examine' : $dataInfo = db('oa_examine')->where(['examine_id' => intval($types_id)])->field('create_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
  171. case 'crm_contract' : $dataInfo = db('crm_contract')->where(['contract_id' => intval($types_id)])->field('create_user_id,owner_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
  172. case 'crm_receivables' : $dataInfo = db('crm_receivables')->where(['receivables_id' => intval($types_id)])->field('create_user_id,owner_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
  173. case 'crm_invoice': $dataInfo = db('crm_invoice')->where(['invoice_id' => intval($types_id)])->field('create_user_id,owner_user_id,check_user_id,flow_id,order_id,check_status,update_time')->find(); break;
  174. }
  175. $stepInfo = [];
  176. if ($dataInfo['flow_id'] && !in_array($dataInfo['check_status'],['5'])) {
  177. //固定审批流
  178. $stepInfo = db('admin_examine_step')->where(['flow_id' => $dataInfo['flow_id'],'order_id' => $dataInfo['order_id']])->find();
  179. }
  180. $data = [];
  181. $data['stepInfo'] = $stepInfo;
  182. $data['step_id'] = $stepInfo['step_id'] ? : '';
  183. $data['dataInfo'] = $dataInfo;
  184. return $data;
  185. }
  186. /**
  187. * 获取审批步骤审批人信息
  188. * @param step_id 审批步骤ID
  189. * @param status 1负责人主管,2指定用户(任意一人),3指定用户(多人会签),4上一级审批人主管
  190. * @param user_id 审批主体,申请人user_id
  191. * @return
  192. */
  193. public function getUserByStep($step_id, $user_id)
  194. {
  195. $stepInfo = db('admin_examine_step')->where(['step_id' => $step_id])->find();
  196. $examine_user_id_arr = [];
  197. //固定审批流
  198. switch ($stepInfo['status']) {
  199. case 1 :
  200. $examine_user_id = db('admin_user')->where(['id' => $user_id])->value('parent_id');
  201. if ($examine_user_id) {
  202. $examine_user_id_arr[] = $examine_user_id;
  203. } else {
  204. $examine_user_id_arr[] = 1;
  205. }
  206. break;
  207. case 2 :
  208. case 3 :$examine_user_id_arr = stringToArray($stepInfo['user_id']); break;
  209. case 4 :
  210. $order_id = $stepInfo['order_id'] ? $stepInfo['order_id']-1 : 0;
  211. $last_step_id = db('admin_examine_step')->where(['flow_id' => $stepInfo['flow_id'],'order_id' => $order_id])->value('step_id');
  212. $last_step_info = db('admin_examine_step')->where(['step_id' => $last_step_id])->find();
  213. $last_user_id = $this->getUserByStep($last_step_id, $user_id);
  214. if (count(stringToArray($last_user_id)) !== 1) {
  215. $this->error = '审批流程出错';
  216. return false;
  217. }
  218. $last_user_id_arr = stringToArray($last_user_id);
  219. $examine_user_id = $this->getUserByStep($last_step_id, $last_user_id_arr[0]);
  220. //$examine_user_id = db('admin_user')->where(['id' => $last_step_info['user_id']])->value('parent_id');
  221. $examine_user_id_arr = [];
  222. if ($examine_user_id) {
  223. $examine_user_id_arr = stringToArray($examine_user_id);
  224. }
  225. break;
  226. default : $examine_user_id_arr = [];
  227. }
  228. return array_unique($examine_user_id_arr) ? ','.implode(',',array_filter(array_unique($examine_user_id_arr))).',' : '';
  229. }
  230. /**
  231. * 获取当前步骤已审批的user_id
  232. * @param step_id 审批步骤ID
  233. * @param status 1审核通过0审核失败2撤销
  234. * @return
  235. */
  236. public function getUserByCheck($types, $types_id = 0, $order_id = 0, $status = 1)
  237. {
  238. if ($types_id == 0 && $order_id == 0) {
  239. $check_user_ids = [];
  240. } else {
  241. $check_user_ids = db('admin_examine_record')->where(['types' => $types,'types_id' => $types_id,'order_id' => $order_id,'is_end' => 0,'status' => $status])->column('check_user_id');
  242. }
  243. return $check_user_ids ? : [];
  244. }
  245. /**
  246. * 获取授权审批的user_id
  247. * @param step_id 审批步骤ID
  248. * @param
  249. * @return
  250. */
  251. public function getUserByPer($types)
  252. {
  253. if (!in_array($types,['oa_examine','crm_contract','crm_receivables'])) {
  254. $this->error = '参数错误';
  255. return false;
  256. }
  257. $userModel = new \app\admin\model\User();
  258. $adminUserId = model('User')->getAdminId(); //管理员ID
  259. //获取有审核权限的user_id
  260. switch ($types) {
  261. case 'oa_examine' : $examine_user_id_arr = $userModel->getUserByPer('oa', 'examine', 'check'); break;
  262. case 'crm_contract' : $examine_user_id_arr = $userModel->getUserByPer('crm', 'contract', 'check'); break;
  263. case 'crm_receivables' : $examine_user_id_arr = $userModel->getUserByPer('crm', 'receivables', 'check'); break;
  264. case 'crm_invoice' : $examine_user_id_arr = $userModel->getUserByPer('crm', 'invoice', 'check'); break;
  265. }
  266. $examine_user_id_arr = $examine_user_id_arr ? array_merge($examine_user_id_arr, $adminUserId) : $adminUserId;
  267. return $examine_user_id_arr;
  268. }
  269. /**
  270. * 获取审批步骤相关userId
  271. * @param flow_id 流程ID
  272. * @param order_id 排序ID
  273. * @return
  274. */
  275. public function getStepUserByOrder($flow_id, $order_id, $user_id)
  276. {
  277. $user_ids = [];
  278. if ($flow_id && $order_id) {
  279. $stepInfo = db('admin_examine_step')->where(['flow_id' => $flow_id,'order_id' => $order_id])->find();
  280. $user_ids = $this->getUserByStep($stepInfo['step_id'], $user_id);
  281. }
  282. return $user_ids ? : [];
  283. }
  284. /**
  285. * 获取有效审批步骤列表(固定审批)
  286. * @param flow_id 审批流程ID
  287. * @param user_id 审批申请人ID
  288. * @param check_user_id 当前操作人ID
  289. * @return
  290. */
  291. public function getStepList($flow_id, $user_id, $types, $types_id = 0, $check_user_id = 0, $action = '', $category_id = '')
  292. {
  293. $userModel = new \app\admin\model\User();
  294. $newlist = [];
  295. $dataInfo['order_id'] = 0;
  296. if ($types_id) {
  297. $typesInfo = $this->getDataByTypes($types, $types_id);
  298. $dataInfo = $typesInfo['dataInfo'];
  299. }
  300. $is_check = 0; //审批权限(1有)
  301. $is_recheck = 0; //撤销审批权限(1有)
  302. $admin_user_ids = $userModel->getAdminId();
  303. //创建人或负责人或管理员有撤销权限
  304. //if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id || in_array($check_user_id, $admin_user_ids)) {
  305. if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id) {
  306. if (!in_array($dataInfo['check_status'],['2','3','4'])) {
  307. $is_recheck = 1;
  308. }
  309. }
  310. if (in_array($check_user_id, stringToArray($dataInfo['check_user_id'])) && !in_array($dataInfo['check_status'],['2','3'])) {
  311. $is_check = 1;
  312. }
  313. if ($action == 'view') {
  314. $createUserInfo = $userModel->getUserById($dataInfo['create_user_id']);
  315. $createUserInfo['check_time'] = !empty($dataInfo['update_time']) ? date('Y-m-d H:i:s', $dataInfo['update_time']) : null;
  316. if ($dataInfo['check_status'] == 4) {
  317. $createUserInfo['check_type'] = 2;
  318. $newlist[0]['type'] = '2'; //撤销
  319. } else {
  320. $createUserInfo['check_type'] = 3;
  321. $newlist[0]['type'] = '3'; //创建
  322. }
  323. $newlist[0]['user_id_info'] = array($createUserInfo);
  324. $newlist[0]['time'] = !empty($dataInfo['update_time']) ? date('Y-m-d H:i:s', $dataInfo['update_time']) : null;
  325. }
  326. $stepList = [];
  327. if ($dataInfo['check_status'] !== 4 || $action !== 'view') {
  328. $list = db('admin_examine_step')->where(['flow_id' => $flow_id])->order('order_id asc')->select();
  329. $is_break = false;
  330. foreach ($list as $k=>$v) {
  331. $type = 4;
  332. $examine_user_ids = '';
  333. //判断步骤审批人是否存在
  334. $examine_user_ids = $this->getUserByStep($v['step_id'], $user_id);
  335. $examine_user_arr = stringToArray($examine_user_ids);
  336. if ($examine_user_arr) {
  337. $newStepInfo = $v;
  338. $user_id_info_arr = [];
  339. foreach ($examine_user_arr as $key=>$val) {
  340. $user_id_info = [];
  341. $user_id_info = $userModel->getUserById($val);
  342. $check_type = 4; //type 0失败,1通过,2撤销,3创建,4待审核,5未提交
  343. //当前步骤已审批user_id
  344. $check_user_ids = [];
  345. $check_user_ids = $this->getUserByCheck($types, $types_id, $v['order_id'], 1);
  346. if (in_array($val, $check_user_ids)) {
  347. $check_type = 1;
  348. $type = !empty($dataInfo['check_user_id']) ? 4 : 1;
  349. }
  350. $re_check_user_ids = $this->getUserByCheck($types, $types_id, $v['order_id'], 2); //撤销人员
  351. if ($dataInfo['check_status'] == 4) {
  352. if ($re_check_user_ids) {
  353. $is_break = true;
  354. $check_type = 2;
  355. $type = 2;
  356. }
  357. }
  358. $fail_check_user_ids = $this->getUserByCheck($types, $types_id, $v['order_id'], 0); //拒绝人员
  359. if ($dataInfo['check_status'] == 3) {
  360. if (in_array($val,$fail_check_user_ids)) {
  361. $is_break = true;
  362. $check_type = 0;
  363. $type = 0;
  364. }
  365. //if ($action == 'view') break;
  366. }
  367. $user_id_info['check_type'] = $check_type;
  368. $check_time = '';
  369. $check_time = db('admin_examine_record')->where(['types' => $types,'types_id' => $types_id,'flow_id' => $flow_id,'order_id' => $v['order_id'],'check_user_id' => $val,'is_end' =>0])->value('check_time');
  370. $user_id_info['check_time'] = !empty($check_time) ? date('Y-m-d H:i:s', $check_time) : '';
  371. $user_id_info_arr[] = $user_id_info;
  372. }
  373. $newStepInfo['user_id'] = $examine_user_ids;
  374. $newStepInfo['user_id_info'] = $user_id_info_arr;
  375. if ($dataInfo['order_id'] > $v['order_id']) {
  376. $type = 1;
  377. }
  378. //if ($is_break !== false) break;
  379. $newStepInfo['type'] = $type;
  380. $stepList[] = $newStepInfo;
  381. }
  382. }
  383. }
  384. $newStepList = [];
  385. if ($newlist && $stepList) {
  386. $newStepList = array_merge($newlist, $stepList);
  387. } elseif ($stepList) {
  388. $newStepList = $stepList;
  389. } else {
  390. $newStepList = $newlist;
  391. }
  392. $data['steplist'] = $newStepList ? : [];
  393. $data['is_check'] = $is_check;
  394. $data['is_recheck'] = $is_recheck;
  395. return $data ? : [];
  396. }
  397. /**
  398. * 根据order_id获取审批步骤
  399. * @param flow_id 审批流程ID
  400. * @param order_id 审批排序ID
  401. * @return
  402. */
  403. public function getStepByOrder($flow_id, $order_id)
  404. {
  405. $data = db('admin_examine_step')->where(['flow_id' => $flow_id,'order_id' => $order_id])->find();
  406. return $data ? : [];
  407. }
  408. /**
  409. * 获取有效审批步骤列表(自选审批)
  410. * @param types 类型
  411. * @param types_id 类型ID
  412. * @param action 操作类型: view、save
  413. * @return
  414. */
  415. public function getPerStepList($types, $types_id, $user_id, $check_user_id, $action = '')
  416. {
  417. $examineRecordModel = new \app\admin\model\ExamineRecord();
  418. $userModel = new \app\admin\model\User();
  419. $userList = [];
  420. //有效的审批记录
  421. $where = [];
  422. $where['types'] = $types;
  423. $where['types_id'] = $types_id;
  424. $where['is_end'] = 0;
  425. $recordList = $examineRecordModel->getDataList($where);
  426. $typeInfo = $this->getDataByTypes($types, $types_id);
  427. $dataInfo = $typeInfo['dataInfo'];
  428. $createUserInfo = $userModel->getUserById($dataInfo['create_user_id']);
  429. $userList[0]['userInfo'] = $createUserInfo;
  430. $userList[0]['type'] = 3; //创建
  431. $userList[0]['time'] = $dataInfo['update_time'] ? : '';
  432. //type 0失败,1通过,2撤销,3创建,4待审核,5未提交
  433. $i = 1;
  434. foreach ($recordList as $k=>$v) {
  435. $userList[$i]['userInfo'] = $userModel->getUserById($v['check_user_id']);
  436. $userList[$i]['type'] = $v['status'];
  437. $userList[$i]['time'] = $v['check_time'];
  438. $i++;
  439. }
  440. if ($dataInfo['check_status'] <= 1 && $dataInfo['check_user_id']) {
  441. $check_user_id_arr = stringToArray($dataInfo['check_user_id']);
  442. $userList[$i]['userInfo'] = $userModel->getUserById($check_user_id_arr[0]);
  443. $userList[$i]['type'] = '4';
  444. }
  445. if ($dataInfo['check_status'] == 5 && $dataInfo['check_user_id']) {
  446. $userList = [];
  447. $check_user_id_arr = stringToArray($dataInfo['check_user_id']);
  448. $userList[0]['userInfo'] = $userModel->getUserById($check_user_id_arr[0]);
  449. $userList[0]['type'] = '5';
  450. }
  451. $is_check = 0; //审批权限(1有)
  452. $is_recheck = 0; //撤销审批权限(1有)
  453. $admin_user_ids = $userModel->getAdminId();
  454. //创建人或负责人或管理员有撤销权限
  455. // if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id || in_array($check_user_id, $admin_user_ids)) {
  456. if ($dataInfo['create_user_id'] == $check_user_id || $dataInfo['owner_user_id'] == $check_user_id) {
  457. if (!in_array($dataInfo['check_status'],['2','3','4','5'])) {
  458. $is_recheck = 1;
  459. }
  460. }
  461. if (in_array($check_user_id, stringToArray($dataInfo['check_user_id'])) && !in_array($dataInfo['check_status'],['2','3','5'])) {
  462. $is_check = 1;
  463. }
  464. $data['steplist'] = $userList;
  465. $data['is_check'] = $is_check;
  466. $data['is_recheck'] = $is_recheck;
  467. return $data ? : [];
  468. }
  469. }