ApplyRecord.php 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. <?php
  2. namespace app\common\model;
  3. use app\hander\HelpHander;
  4. use think\Db;
  5. use think\Exception;
  6. use think\Model;
  7. class ApplyRecord extends Model
  8. {
  9. public function add($data,$orgId,$title){
  10. try{
  11. $recordId = Db::name('apply_record')->insertGetId($data);
  12. if(!$recordId){
  13. \exception('数据保存失败');
  14. }
  15. // 生成消息及推送提醒
  16. if($data['type'] == 3){
  17. $context = $title.',抄送给您,请知晓。';
  18. } else if($data['type'] == 9){
  19. $context = $title.',需要您去执行,请知晓。';
  20. } else {
  21. if(isset($data['back']) && $data['back'] == 1){
  22. $context = $title.'被打回,请您重新审批。';
  23. }else{
  24. $context = $title.'需要您审批。';
  25. }
  26. }
  27. $res = model('Message')->add(2,$recordId,2,$data['user_id'],$orgId,$context);
  28. if(!$res){
  29. \exception('消息生成失败');
  30. }
  31. return true;
  32. }catch (Exception $e){
  33. $this->error = $e->getMessage();
  34. return false;
  35. }
  36. }
  37. // 审批单生成时审批记录生成
  38. public function createRecord($applyId,$data){
  39. // flowJson排序
  40. $flowJson = sort_flow_json(json_decode($data['flow_json'],true));
  41. $curTime = date('Y-m-d H:i:s');
  42. $nodeid = '';
  43. $status = 1;
  44. $users = [];
  45. foreach ($flowJson as $k=>$v){
  46. $nodeid = $v['id'];
  47. if($v['type'] == 9||$v['type'] == 3){ // 节点是执行人或审批人时
  48. foreach ($v['userList'] as $kk=>$vv){
  49. $users[] = [
  50. 'user_id' => $vv['userId'],
  51. 'nodeid' => $v['id'],
  52. 'type' => $v['type']
  53. ];
  54. }
  55. } else if($v['type'] == 2||$v['type'] == 8){ // 审批人
  56. foreach ($v['userList'] as $kk=>$vv){
  57. $users[] = [
  58. 'user_id' => $vv['userId'],
  59. 'nodeid' => $v['id'],
  60. 'type' => $v['type']
  61. ];
  62. }
  63. break;
  64. } else if($v['type'] == 5){ // 流程结束
  65. $status = 2;
  66. }
  67. }
  68. try{
  69. if($status == 2){ // 流程结束
  70. $ret = Db::name('apply')->where('id',$applyId)->update([
  71. 'status' => 2,
  72. 'finish_time' => $curTime,
  73. 'update_time' => $curTime,
  74. 'nodeid' => $nodeid
  75. ]);
  76. if(!$ret){
  77. \exception('流程状态修改失败1');
  78. }
  79. // 生成消息记录
  80. $context = "温馨提醒,".$data['title']."(编号:".$data['apply_sn'].")已通过。";
  81. $mres = model('Message')->add(3,$applyId,4,$data['user_id'],$data['org_id'],$context);
  82. if(!$mres){
  83. \exception('消息生成失败');
  84. }
  85. if($data['advanced'] > 0){ // 流程结束高级组件执行逻辑
  86. $aret = $this->advancedEndAction($applyId,$data['org_id'],$data['user_id'],$data['form_json'],$data['advanced']);
  87. if(!$aret){
  88. \exception('操作失败');
  89. }
  90. }
  91. } else { // 审批中
  92. $ret = Db::name('apply')->where('id',$applyId)->update([
  93. 'status' => 1,
  94. 'update_time' => $curTime,
  95. 'nodeid' => $nodeid
  96. ]);
  97. if(!$ret){
  98. \exception('流程状态修改失败2'.$ret);
  99. }
  100. }
  101. if($users){
  102. foreach ($users as $k=>$v){
  103. $v['apply_id'] = $applyId;
  104. $v['status'] = 0;
  105. $v['create_time'] = $curTime;
  106. $res = model('ApplyRecord')->add($v,$data['org_id'],$data['title']);
  107. if(!$res){
  108. \exception('流程记录生成失败');
  109. }
  110. }
  111. }
  112. return true;
  113. }catch (Exception $e){
  114. $this->error = $e->getMessage();
  115. return false;
  116. }
  117. }
  118. // 记录修改为已阅
  119. public function updateStatus($id,$userId){
  120. $info = Db::name('apply_record')->where('id',$id)->where('user_id',$userId)->find();
  121. if($info && $info['status'] == 0){
  122. Db::name('apply_record')
  123. ->where('id',$id)
  124. ->update(['status' => 1,'finish_time' => date('Y-m-d H:i:s')]);
  125. }
  126. }
  127. // 打回到上一级
  128. public function back($id,$userId){
  129. $info = Db::name('apply_record')
  130. ->alias('ar')
  131. ->join('apply a','a.id = ar.apply_id')
  132. ->where('ar.id',$id)
  133. ->where('ar.del',0)
  134. ->where('a.del',0)
  135. ->where('ar.type','in',[2,8])
  136. ->where('ar.user_id',$userId)
  137. ->field('ar.*,a.title,a.org_id,a.flow_json')
  138. ->find();
  139. if(!$info){
  140. HelpHander::error('数据不存在');
  141. }
  142. // 判断是否有上个审批节点
  143. $f = Db::name('apply_record')
  144. ->where('status',1)
  145. ->where('apply_id',$info['apply_id'])
  146. ->where('type','in',[2,8])
  147. ->where('del',0)
  148. ->where('nodeid','<>',$info['nodeid'])
  149. ->order('id desc')
  150. ->find();
  151. if(!$f){
  152. HelpHander::error('不能打回到拟稿人');
  153. }
  154. $flist = Db::name('apply_record')
  155. ->where('apply_id',$info['apply_id'])
  156. ->where('type','in',[2,8])
  157. // ->where('status','<>',3) // 已转交的记录不用审核
  158. ->where('del',0)
  159. ->where('nodeid',$f['nodeid'])
  160. ->select();
  161. $flist = $flist?$flist:[];
  162. Db::startTrans();
  163. try{
  164. // 删除上一节点
  165. $fids = [];
  166. foreach ($flist as $k=>$v){
  167. $fids[] = $v['id'];
  168. }
  169. // 同节点已审批的人发通知提醒打回上一节点
  170. $ulist = Db::name('apply_record')
  171. ->where('apply_id',$info['apply_id'])
  172. ->where('nodeid',$info['nodeid'])
  173. ->where('del',0)
  174. ->where('status',1)
  175. ->field('user_id,id')
  176. ->select();
  177. $ulist = $ulist?$ulist:[];
  178. // 操作节点记录删除
  179. $ids = Db::name('apply_record')
  180. ->where('apply_id',$info['apply_id'])
  181. ->where('nodeid',$info['nodeid'])
  182. ->where('del',0)
  183. ->column('id');
  184. $rids = array_merge($fids,$ids);
  185. $res = Db::name('apply_record')->where('id','in',$rids)->setField('del',1);
  186. if(!$res){
  187. \exception('操作失败');
  188. }
  189. // 给每条记录打回人
  190. $res = Db::name('apply_record')->where('id','in',$ids)->setField('back_user_id',$id);
  191. if(!$res){
  192. \exception('操作失败');
  193. }
  194. Db::name('message')
  195. ->where('type',2)
  196. ->where('bus_type',2)
  197. ->where('org_id',$info['org_id'])
  198. ->where('bus_id','in',$rids)
  199. ->delete();
  200. // 修改申请记录当前节点
  201. $ret = Db::name('apply')->where('id',$info['apply_id'])->setField('nodeid',$f['nodeid']);
  202. if(!$ret){
  203. \exception('操作失败');
  204. }
  205. //把上一节点的审核人记录,重新生成,重新通知
  206. foreach ($flist as $k=>$v){
  207. if($v['status'] == 3){ // 被转交的不生成记录
  208. continue;
  209. }
  210. $data = [
  211. 'user_id' => $v['user_id'],
  212. 'apply_id' => $v['apply_id'],
  213. 'status' => 0,
  214. 'nodeid' => $v['nodeid'],
  215. 'type' => $v['type'],
  216. 'create_time' => date('Y-m-d H:i:s'),
  217. 'back' => 1,
  218. 'back_user_id' => $userId
  219. ];
  220. $res = $this->add($data,$info['org_id'],$info['title']);
  221. if(!$res){
  222. \exception('转交失败');
  223. }
  224. // 提醒放到最后
  225. $backusername = Db::name('user_info')->where('user_id',$userId)->value('name');
  226. $context = '['.$backusername.']把'.$info['title'].'打回上一审批节点,请知晓。';
  227. foreach ($ulist as $k=>$v){
  228. model('Message')->add(3,$v['id'],0,$v['user_id'],$info['org_id'],$context);
  229. }
  230. }
  231. Db::commit();
  232. }catch (Exception $e){
  233. Db::rollback();
  234. HelpHander::error('操作失败');
  235. }
  236. return true;
  237. }
  238. // 转交
  239. public function transferApply($id,$userId,$transferUserId){
  240. if($userId == $transferUserId){
  241. HelpHander::error('被转交人不能是自己');
  242. }
  243. if($transferUserId <= 0){
  244. HelpHander::error('未选择被转交人');
  245. }
  246. $info = Db::name('apply_record')
  247. ->alias('ar')
  248. ->join('apply a','a.id = ar.apply_id')
  249. ->where('ar.id',$id)
  250. ->where('ar.del',0)
  251. ->where('a.del',0)
  252. ->where('ar.user_id',$userId)
  253. ->field('ar.*,a.title,a.org_id')
  254. ->find();
  255. if(!$info){
  256. HelpHander::error('数据不存在');
  257. }
  258. if($info['type'] == 3||$info['type'] == 9){
  259. HelpHander::error('无法转交');
  260. }
  261. if($info['status'] != 0){
  262. HelpHander::error('已处理,无法转交');
  263. }
  264. $transfer = Db::name('apply_record')->where('del',0)->where('apply_id',$info['apply_id'])->where('user_id',$transferUserId)->find();
  265. if($transfer){
  266. HelpHander::error('被转交人已参与审批,无法再次转交');
  267. }
  268. Db::startTrans();
  269. try{
  270. $ret = Db::name('apply_record')->where('id',$id)->setField('status',3);
  271. if(!$ret){
  272. \exception('转交失败');
  273. }
  274. $data = [
  275. 'user_id' => $transferUserId,
  276. 'apply_id' => $info['apply_id'],
  277. 'status' => 0,
  278. 'nodeid' => $info['nodeid'],
  279. 'type' => 2,
  280. 'transfer' => 1,
  281. 'create_time' => date('Y-m-d H:i:s')
  282. ];
  283. $res = $this->add($data,$info['org_id'],$info['title']);
  284. if(!$res){
  285. \exception('转交失败');
  286. }
  287. Db::commit();
  288. }catch (Exception $e){
  289. Db::rollback();
  290. HelpHander::error('转交失败');
  291. }
  292. return true;
  293. }
  294. // 会签
  295. public function aggregationApproval($id,$userId,$userIds){
  296. $userIds = explode(',',$userIds);
  297. $info = Db::name('apply_record')
  298. ->alias('ar')
  299. ->join('apply a','a.id = ar.apply_id')
  300. ->where('ar.id',$id)
  301. ->where('ar.del',0)
  302. ->where('a.del',0)
  303. ->where('ar.user_id',$userId)
  304. ->field('ar.*,a.title,a.org_id,a.flow_json')
  305. ->find();
  306. if(!$info){
  307. HelpHander::error('数据不存在');
  308. }
  309. if($info['type'] == 3||$info['type'] == 9){
  310. HelpHander::error('无法会签');
  311. }
  312. if($info['status'] != 0){
  313. HelpHander::error('已处理,无法会签');
  314. }
  315. // 检查当前节点是会签还是或签,或签无法加人会签
  316. $flowJson = json_decode($info['flow_json'],true);
  317. foreach ($flowJson as $k=>$v){
  318. if($v['id'] == $info['nodeid'] && $v['mode'] == 2){
  319. HelpHander::error('该节点为或签,无法添加会签');
  320. }
  321. }
  322. $oldusers = Db::name('apply_record')
  323. ->where('nodeid',$info['nodeid'])
  324. ->where('apply_id',$id)
  325. ->where('del',0)
  326. ->column('user_id');
  327. $jjuser = array_intersect($userIds, $oldusers);
  328. if($jjuser){
  329. HelpHander::error('存在用户已是会签人员');
  330. }
  331. Db::startTrans();
  332. try{
  333. foreach ($userIds as $k=>$v){
  334. $data = [
  335. 'user_id' => $v,
  336. 'apply_id' => $info['apply_id'],
  337. 'status' => 0,
  338. 'nodeid' => $info['nodeid'],
  339. 'type' => 2,
  340. 'countersign' => 1,
  341. 'create_time' => date('Y-m-d H:i:s')
  342. ];
  343. $res = $this->add($data,$info['org_id'],$info['title']);
  344. if(!$res){
  345. \exception('会签失败');
  346. }
  347. }
  348. Db::commit();
  349. }catch (Exception $e){
  350. Db::rollback();
  351. HelpHander::error('会签失败');
  352. }
  353. return true;
  354. }
  355. // 加签
  356. public function addSign($id,$userId,$addUserId,$type=0){
  357. $info = Db::name('apply_record')
  358. ->alias('ar')
  359. ->join('apply a','a.id = ar.apply_id')
  360. ->where('ar.id',$id)
  361. ->where('ar.del',0)
  362. ->where('a.del',0)
  363. ->where('ar.user_id',$userId)
  364. ->field('ar.*,a.title,a.org_id,a.flow_json')
  365. ->find();
  366. if(!$info){
  367. HelpHander::error('数据不存在');
  368. }
  369. if($info['type'] == 3||$info['type'] == 9){
  370. HelpHander::error('无法加签');
  371. }
  372. if($info['status'] != 0){
  373. HelpHander::error('已处理,无法加签');
  374. }
  375. $lastNode = ''; // 最后一个审批节点
  376. $node = [];
  377. // 检查当前节点是会签还是或签,或签无法加签
  378. $flowJson = sort_flow_json(json_decode($info['flow_json'],true));
  379. foreach ($flowJson as $k=>$v){
  380. if($v['id'] == $info['nodeid'] && $v['mode'] == 2){
  381. HelpHander::error('该节点为或签,无法加签');
  382. }
  383. if($v['type'] == 2||$v['type'] == 8){
  384. $lastNode = $v['id'];
  385. }
  386. if($v['id'] == $info['nodeid']){
  387. $node = $v;
  388. }
  389. }
  390. // 检查是否多人会签,多人会签无法加签
  391. $oldusers = Db::name('apply_record')
  392. ->where('nodeid',$info['nodeid'])
  393. ->where('apply_id',$id)
  394. ->where('del',0)
  395. ->column('user_id');
  396. if(count($oldusers) > 1 || in_array($addUserId,$oldusers)){
  397. HelpHander::error('无权限加签');
  398. }
  399. if($type == 1 && $lastNode != $info['nodeid']){ // 往后加签,检查是否是最后一个审批节点
  400. HelpHander::error('无权限加签');
  401. }
  402. $user = Db::name('user_info')
  403. ->where('user_id',$addUserId)
  404. ->field('user_id,name')
  405. ->find();
  406. Db::startTrans();
  407. try{
  408. if($type == 0){
  409. $addnode = $node;
  410. $addnode['id'] = 'addnode'.time().rand(1000,9999);
  411. $addnode['nextId'] = $node['id'];
  412. $addnode['type'] = 8;
  413. $addnode['name'] = '加签';
  414. $addnode['userList'] = [[
  415. "userName" => $user['name'],
  416. "shortName" => mb_strlen($user['name']) > 2 ? mb_substr($user['name'], 0, -2) : $user['name'],
  417. "userId" => $user['user_id']
  418. ]];
  419. foreach ($flowJson as $k=>$v){
  420. if($v['nextId'] == $info['nodeid']){
  421. $flowJson[$k]['nextId'] = $addnode['id'];
  422. }
  423. }
  424. $flowJson[] = $addnode;
  425. $flowJson = sort_flow_json($flowJson);
  426. // 修改审批单信息
  427. $ret = Db::name('apply')->where('id',$info['apply_id'])->update([
  428. 'nodeid' => $addnode['id'],
  429. 'flow_json' => json_encode($flowJson,JSON_UNESCAPED_UNICODE),
  430. 'update_time' => date('Y-m-d H:i:s')
  431. ]);
  432. if(!$ret){
  433. \exception('加签失败');
  434. }
  435. // 删除原来节点记录及消息
  436. $ids = Db::name('apply_record')
  437. ->where('apply_id',$info['apply_id'])
  438. ->where('nodeid',$info['nodeid'])
  439. ->where('del',0)
  440. ->column('id');
  441. Db::name('apply_record')->where('id','in',$ids)->setField('del',1);
  442. Db::name('message')
  443. ->where('type',2)
  444. ->where('bus_type',2)
  445. ->where('org_id',$info['org_id'])
  446. ->where('bus_id','in',$ids)
  447. ->delete();
  448. $data = [
  449. 'user_id' => $addUserId,
  450. 'apply_id' => $info['apply_id'],
  451. 'status' => 0,
  452. 'nodeid' => $addnode['id'],
  453. 'type' => 8,
  454. 'create_time' => date('Y-m-d H:i:s')
  455. ];
  456. $res = $this->add($data,$info['org_id'],$info['title']);
  457. if(!$res){
  458. \exception('加签失败');
  459. }
  460. }else{
  461. $addnode = $node;
  462. $addnode['id'] = 'addnoder'.time().rand(1000,9999);
  463. $addnode['type'] = 8;
  464. $addnode['name'] = '加签';
  465. $addnode['userList'] = [[
  466. "userName" => $user['name'],
  467. "shortName" => mb_strlen($user['name']) > 2?mb_substr($user['name'], 0, -2):$user['name'],
  468. "userId" => $user['user_id']
  469. ]];
  470. foreach ($flowJson as $k=>$v){
  471. if($v['id'] == $info['nodeid']){
  472. $flowJson[$k]['nextId'] = $addnode['id'];
  473. }
  474. }
  475. $flowJson[] = $addnode;
  476. $flowJson = sort_flow_json($flowJson);
  477. // 修改审批单信息
  478. $ret = Db::name('apply')->where('id',$info['apply_id'])->update([
  479. 'flow_json' => json_encode($flowJson,JSON_UNESCAPED_UNICODE),
  480. 'update_time' => date('Y-m-d H:i:s')
  481. ]);
  482. if(!$ret){
  483. \exception('加签失败');
  484. }
  485. }
  486. Db::commit();
  487. }catch (Exception $e){
  488. Db::rollback();
  489. HelpHander::error('加签失败'.$e->getMessage());
  490. }
  491. return true;
  492. }
  493. // 同意
  494. public function audit($id,$userId,$content,$formJson,$userList){
  495. $info = Db::name('apply_record')
  496. ->where('id',$id)
  497. ->where('del',0)
  498. ->where('user_id',$userId)
  499. ->find();
  500. if(!$info){
  501. HelpHander::error('数据不存在');
  502. }
  503. if($info['type'] == 3||$info['type'] == 9){
  504. HelpHander::error('无法执行此操作');
  505. }
  506. if($info['status'] != 0){
  507. HelpHander::error('已处理');
  508. }
  509. $apply = Db::name('apply')->where('del',0)->where('id',$info['apply_id'])->find();
  510. if(!$apply){
  511. HelpHander::error('数据不存在');
  512. }
  513. $flowJson = sort_flow_json(json_decode($apply['flow_json'],true));
  514. $curNode = $this->getNodeFlowJson($flowJson,$info['nodeid']);
  515. $next = 0; // 是否走到下一流程
  516. if($curNode['mode'] == '1'){ // 会签
  517. // 检查是否该到下一流程
  518. $count = Db::name('apply_record')
  519. ->where('apply_id',$info['apply_id'])
  520. ->where('nodeid',$info['nodeid'])
  521. ->where('status',0)
  522. ->where('del',0)
  523. ->count();
  524. if($count == 1){ // 下一流程
  525. $next = 1;
  526. }
  527. } else { // 或签
  528. $next = 1;
  529. }
  530. $isexecutor = 0;
  531. foreach ($flowJson as $k=>$v){
  532. if($v['type'] == 9){
  533. $isexecutor = 1;
  534. break;
  535. }
  536. }
  537. $curTime = date('Y-m-d H:i:s');
  538. $duration = round((strtotime($curTime) - strtotime($info['create_time']))/3600,2); // 时长
  539. $applyduration = round((strtotime($curTime) - strtotime($apply['create_time']))/3600,2); // 时长
  540. Db::startTrans();
  541. try{
  542. $ret = Db::name('apply_record')
  543. ->where('id',$id)
  544. ->update([
  545. 'status' => 1,
  546. 'finish_time'=>$curTime,
  547. 'content' => $content,
  548. 'duration' => $duration
  549. ]);
  550. if(!$ret){
  551. \exception('操作失败');
  552. }
  553. if($formJson || $userList){ // formJson或$userList有变化
  554. if($formJson){
  555. $ad['form_json'] = $formJson;
  556. // formJson日志记录
  557. $res = Db::name('apply_form_log')->insert([
  558. 'apply_id' => $info['apply_id'],
  559. 'user_id' => $userId,
  560. 'form_json' => $formJson,
  561. 'create_time' => $curTime
  562. ]);
  563. if(!$res){
  564. \exception('数据保存失败');
  565. }
  566. }
  567. if($isexecutor == 1){
  568. foreach ($flowJson as $k=>$v){
  569. if($v['type'] == 9){
  570. $flowJson[$k]['userList'] = json_decode($userList,true);
  571. break;
  572. }
  573. }
  574. $ad['flow_json'] = json_encode($flowJson,JSON_UNESCAPED_UNICODE);
  575. }
  576. $ad['update_time'] = $curTime;
  577. $ret = Db::name('apply')->where('id',$info['apply_id'])->update($ad);
  578. if(!$ret){
  579. \exception('数据修改失败');
  580. }
  581. }
  582. if($next == 1){ // 流转到下一节点
  583. Db::name('apply_record')
  584. ->where('id','<>',$id)
  585. ->where('apply_id',$info['apply_id'])
  586. ->where('status',0)
  587. ->where('del',0)
  588. ->where('nodeid',$info['nodeid'])
  589. ->setField('status',4);
  590. $nodeid = $curNode['nextId'];
  591. $status = 1;
  592. $users = [];
  593. while (true){
  594. $nextNode = $this->getNodeFlowJson($flowJson,$nodeid);
  595. if($nextNode['type'] == 9||$nextNode['type'] == 3){ // 节点是执行人或审批人时
  596. foreach ($nextNode['userList'] as $kk=>$vv){
  597. $users[] = [
  598. 'user_id' => $vv['userId'],
  599. 'nodeid' => $nextNode['id'],
  600. 'type' => $nextNode['type']
  601. ];
  602. }
  603. $nodeid = $nextNode['nextId'];
  604. } else if($nextNode['type'] == 2||$nextNode['type'] == 8){ // 审批人
  605. // 检查当前nodeid是否有记录,有记录按记录的生成(下级的审核人与原始的不同,需要从删除的记录中取)
  606. $buid = Db::name('apply_record')
  607. ->where('apply_id',$info['apply_id'])
  608. ->where('del',1)
  609. ->where('nodeid',$nextNode['id'])
  610. ->where('status','<>',3) // 被转交的不用取
  611. ->where('back_user_id','>',0) // 被转交的不用取
  612. ->order('id desc')
  613. ->value('back_user_id');
  614. if($buid){
  615. $ulist = Db::name('apply_record')
  616. ->where('apply_id',$info['apply_id'])
  617. ->where('del',1)
  618. ->where('nodeid',$nextNode['id'])
  619. ->where('status','<>',3) // 被转交的不用取
  620. ->where('back_user_id',$buid) // 被转交的不用取
  621. ->field('user_id as userId')
  622. ->select();
  623. }else{
  624. $ulist = $nextNode['userList'];
  625. }
  626. foreach ($ulist as $kk=>$vv){
  627. $users[] = [
  628. 'user_id' => $vv['userId'],
  629. 'nodeid' => $nextNode['id'],
  630. 'type' => $nextNode['type']
  631. ];
  632. }
  633. break;
  634. } else if($nextNode['type'] == 5){ // 流程结束
  635. $status = 2;
  636. break;
  637. }
  638. }
  639. if($status == 2){ // 流程结束
  640. $ret = Db::name('apply')->where('id',$info['apply_id'])->update([
  641. 'status' => 2,
  642. 'finish_time' => $curTime,
  643. 'update_time' => $curTime,
  644. 'nodeid' => $nodeid,
  645. 'duration' => $applyduration
  646. ]);
  647. if(!$ret){
  648. \exception('信息修改失败');
  649. }
  650. // 生成消息记录
  651. $context = "温馨提醒,".$apply['title']."(编号:".$apply['apply_sn'].")已通过。";
  652. $mres = model('Message')->add(3,$info['apply_id'],4,$apply['user_id'],$apply['org_id'],$context);
  653. if(!$mres){
  654. \exception('消息生成失败');
  655. }
  656. if($apply['advanced'] > 0){ // 流程结束高级组件执行逻辑
  657. $aret = $this->advancedEndAction($apply['id'],$apply['org_id'],$apply['user_id'],$apply['form_json'],$apply['advanced']);
  658. if(!$aret){
  659. \exception('操作失败');
  660. }
  661. }
  662. } else { // 审批中
  663. $ret = Db::name('apply')->where('id',$info['apply_id'])->update([
  664. 'status' => 1,
  665. 'update_time' => $curTime,
  666. 'nodeid' => $nodeid
  667. ]);
  668. if(!$ret){
  669. \exception('信息修改失败');
  670. }
  671. }
  672. if($users){
  673. foreach ($users as $k=>$v){
  674. $v['apply_id'] = $info['apply_id'];
  675. $v['status'] = 0;
  676. $v['create_time'] = $curTime;
  677. $res = $this->add($v,$apply['org_id'],$apply['title']);
  678. if(!$res){
  679. \exception('流程记录生成失败');
  680. }
  681. }
  682. }
  683. }
  684. Db::commit();
  685. }catch (Exception $e){
  686. trace($e->getMessage());
  687. Db::rollback();
  688. HelpHander::error('操作失败'.$e->getMessage());
  689. }
  690. return true;
  691. }
  692. // 打回/拒绝
  693. public function toBack($applyId,$userId,$content){
  694. $info = Db::name('apply_record')
  695. ->alias('ar')
  696. ->join('apply a','a.id = ar.apply_id')
  697. ->where('a.id',$applyId)
  698. ->where('ar.user_id',$userId)
  699. ->where('ar.status',0)
  700. ->where('ar.del',0)
  701. ->field('ar.*')
  702. ->find();
  703. if(!$info){
  704. HelpHander::error('数据不存在');
  705. }
  706. if($info['type'] == 3||$info['type'] == 9){
  707. HelpHander::error('无法操作');
  708. }
  709. if($info['status'] != 0){
  710. HelpHander::error('已处理');
  711. }
  712. $apply = Db::name('apply')->where('id',$info['apply_id'])->where('del',0)->find();
  713. if(!$apply){
  714. HelpHander::error('数据不存在');
  715. }
  716. $curTime = date('Y-m-d H:i:s');
  717. $duration = round((strtotime($curTime) - strtotime($info['create_time']))/3600,2); // 时长
  718. $applyduration = round((strtotime($curTime) - strtotime($apply['create_time']))/3600,2); // 时长
  719. Db::startTrans();
  720. try{
  721. $ret = Db::name('apply_record')->where('id',$info['id'])->update([
  722. 'status' => 2,
  723. 'content' => $content,
  724. 'finish_time' => $curTime,
  725. 'duration' => $duration
  726. ]);
  727. if(!$ret){
  728. \exception('操作失败');
  729. }
  730. Db::name('apply_record')
  731. ->where('id','<>',$info['id'])
  732. ->where('status',0)
  733. ->where('apply_id',$info['apply_id'])
  734. ->where('nodeid',$info['nodeid'])
  735. ->setField('status',4);
  736. $res = Db::name('apply')->where('id',$applyId)->update([
  737. 'status' => 5,
  738. 'finish_time' => $curTime,
  739. 'duration' => $applyduration
  740. ]);
  741. if(!$res){
  742. \exception('操作失败');
  743. }
  744. $result = $this->advancedDisagreeAction($applyId,$apply['advanced']);
  745. if(!$result){
  746. \exception('操作失败');
  747. }
  748. Db::commit();
  749. }catch (Exception $e){
  750. Db::rollback();
  751. HelpHander::error('操作失败'.$e->getMessage());
  752. }
  753. return true;
  754. }
  755. // 获取node信息
  756. public function getNodeFlowJson($flowJson,$nodeId){
  757. $curNode = [];
  758. foreach ($flowJson as $k=>$v){
  759. if($v['id'] == $nodeId){
  760. $curNode = $v;
  761. break;
  762. }
  763. }
  764. return $curNode;
  765. }
  766. // 高级组件执行操作 -- 流程申请时
  767. public function advancedStartAction($id,$orgId,$userId,$formJson,$advanced,$extra=[]){
  768. switch ($advanced){
  769. case '1': // 请假
  770. $ret = model('AttendanceLeave')->advancedStartLeave($id,$orgId,$userId,$formJson);
  771. break;
  772. case '3': // 合同
  773. $ret = model('Contract')->advancedStartContract($id,$orgId,$userId,$formJson);
  774. break;
  775. case '4': // 追加合同
  776. $ret = model('Contract')->advancedStartAddContract($id,$orgId,$userId,$formJson);
  777. break;
  778. case '5': // 合同付款
  779. $ret = model('ContractPay')->advancedStartContractPay($id,$orgId,$userId,$formJson);
  780. break;
  781. case '6': // 会议室预定
  782. $ret = model('MeetingRoom')->advancedStartMeetingRoom($id,$orgId,$userId,$formJson,$extra);
  783. break;
  784. case '7': // 合同收款
  785. $ret = model('ContractPay')->advancedStartContractGet($id,$orgId,$userId,$formJson);
  786. break;
  787. case '8': // 销假
  788. $ret = model('AttendanceLeaveTerminate')->advancedStartLeaveTerminate($id,$orgId,$userId,$formJson);
  789. break;
  790. case '9': // 离京报告
  791. $ret = model('LeaveBj')->advancedStartLeaveBj($id,$orgId,$userId,$formJson);
  792. break;
  793. case '10': // 办公物品
  794. $ret = model('OfficeReceive')->advancedStartOfficeReceive($id,$orgId,$userId,$formJson,$extra);
  795. break;
  796. case '11': // 用车
  797. $ret = model('CarRecord')->advancedStartCarRecord($id,$orgId,$userId,$formJson,$extra);
  798. break;
  799. case '13': // 资产领取
  800. $ret = model('AssetReceive')->advancedStartAssetReceive($id,$orgId,$userId,$formJson,$extra);
  801. break;
  802. case '14': // 资产退库
  803. $ret = model('AssetWithdraw')->advancedStartAssetWithdraw($id,$orgId,$userId,$formJson,$extra);
  804. break;
  805. case '15': // 资产维修
  806. $ret = model('AssetRepair')->advancedStartAssetRepair($id,$orgId,$userId,$formJson,$extra);
  807. break;
  808. case '16': // 资产处置
  809. $ret = model('AssetDisposal')->advancedStartAssetDisposal($id,$orgId,$userId,$formJson,$extra);
  810. break;
  811. case '17': // 预算
  812. $ret = model('BudgetApply')->advancedStartBudgetApply($id,$orgId,$userId,$formJson,$extra);
  813. break;
  814. case '18': // 用印
  815. $ret = model('OfficialSealApply')->advancedStartSealApply($id,$orgId,$userId,$formJson,$extra);
  816. break;
  817. case '19': // 中心发文
  818. $ret = model('PostApply')->advancedStartPostApply($id,$orgId,$userId,$formJson,$extra);
  819. break;
  820. case '20': // 因私出国
  821. $ret = model('AbroadApply')->advancedStartAbroadApply($id,$orgId,$userId,$formJson,$extra);
  822. break;
  823. case '21': // 日常支出
  824. $ret = model('BudgetPay')->advancedStartBudgetPay($id,$orgId,$userId,$formJson,$extra);
  825. break;
  826. default:
  827. $ret = true;
  828. break;
  829. }
  830. return $ret;
  831. }
  832. // 高级组件执行操作 -- 流程结束时
  833. public function advancedEndAction($id,$orgId,$userId,$formJson,$advanced){
  834. switch ($advanced){
  835. case '1': // 请假
  836. $ret = model('AttendanceLeave')->advancedEndLeave($id,$orgId,$userId,$formJson);
  837. break;
  838. case '3': // 合同
  839. $ret = model('Contract')->advancedEndContract($id,$orgId,$userId,$formJson);
  840. break;
  841. case '4': // 追加合同
  842. $ret = model('Contract')->advancedEndAddContract($id,$orgId,$userId,$formJson);
  843. break;
  844. case '5': // 合同支付
  845. $ret = model('ContractPay')->advancedEndContractPay($id,$orgId,$userId,$formJson);
  846. break;
  847. case '6': // 会议室预定
  848. $ret = model('MeetingRoom')->advancedEndMeetingRoom($id,$orgId,$userId,$formJson);
  849. break;
  850. case '7': // 合同收款
  851. $ret = model('ContractPay')->advancedEndContractGet($id,$orgId,$userId,$formJson);
  852. break;
  853. case '8': // 销假
  854. $ret = model('AttendanceLeaveTerminate')->advancedEndLeaveTerminate($id,$orgId,$userId,$formJson);
  855. break;
  856. case '9': // 离京报告
  857. $ret = model('LeaveBj')->advancedEndLeaveBj($id,$orgId,$userId,$formJson);
  858. break;
  859. case '10': // 办公物品
  860. $ret = model('OfficeReceive')->advancedEndOfficeReceive($id,$orgId,$userId,$formJson);
  861. break;
  862. case '11': // 用车
  863. $ret = model('CarRecord')->advancedEndCarRecord($id,$orgId,$userId,$formJson);
  864. break;
  865. case '12': // 离职或退休
  866. $ret = model('UserInfo')->advancedEndUserInfo($id,$orgId,$userId,$formJson);
  867. break;
  868. case '13': // 资产领取
  869. $ret = model('AssetReceive')->advancedEndAssetReceive($id,$orgId,$userId,$formJson);
  870. break;
  871. case '14': // 资产退库
  872. $ret = model('AssetWithdraw')->advancedEndAssetWithdraw($id,$orgId,$userId,$formJson);
  873. break;
  874. case '15': // 资产维修
  875. $ret = model('AssetRepair')->advancedEndAssetRepair($id,$orgId,$userId,$formJson);
  876. break;
  877. case '16': // 资产处置
  878. $ret = model('AssetDisposal')->advancedEndAssetDisposal($id,$orgId,$userId,$formJson);
  879. break;
  880. case '17': // 预算
  881. $ret = model('BudgetApply')->advancedEndBudgetApply($id,$orgId,$userId,$formJson);
  882. break;
  883. case '18': // 用印
  884. $ret = model('OfficialSealApply')->advancedEndSealApply($id,$orgId,$userId,$formJson);
  885. break;
  886. case '19': // 中心发文
  887. $ret = model('PostApply')->advancedEndPostApply($id,$orgId,$userId,$formJson);
  888. break;
  889. case '20': // 因私出国
  890. $ret = model('AbroadApply')->advancedEndAbroadApply($id,$orgId,$userId,$formJson);
  891. break;
  892. case '21': // 日常支出
  893. $ret = model('BudgetPay')->advancedEndBudgetPay($id,$orgId,$userId,$formJson);
  894. break;
  895. default:
  896. $ret = true;
  897. break;
  898. }
  899. return $ret;
  900. }
  901. public function advancedDisagreeAction($applyId,$advanced){
  902. switch ($advanced){
  903. case '1': // 请假
  904. $ret = model('AttendanceLeave')->advancedDisagreeLeave($applyId);
  905. break;
  906. case '3': // 合同
  907. $ret = model('Contract')->advancedDisagreeContract($applyId);
  908. break;
  909. case '4': // 追加合同
  910. $ret = model('Contract')->advancedDisagreeAddContract($applyId);
  911. break;
  912. case '5': // 合同支付
  913. $ret = model('ContractPay')->advancedDisagreeContractPay($applyId);
  914. break;
  915. case '6': // 会议室预定
  916. $ret = model('MeetingRoom')->advancedDisagreeMeetingRoom($applyId);
  917. break;
  918. case '7': // 合同收款
  919. $ret = model('ContractPay')->advancedDisagreeContractGet($applyId);
  920. break;
  921. case '8': // 销假
  922. $ret = model('AttendanceLeaveTerminate')->advancedDisagreeLeaveTerminate($applyId);
  923. break;
  924. case '9': // 离京报告
  925. $ret = model('LeaveBj')->advancedDisagreeLeaveBj($applyId);
  926. break;
  927. case '10': // 办公物品
  928. $ret = model('OfficeReceive')->advancedDisagreeOfficeReceive($applyId);
  929. break;
  930. case '11': // 用车
  931. $ret = model('CarRecord')->advancedDisagreeCarRecord($applyId);
  932. break;
  933. case '13': // 资产领取
  934. $ret = model('AssetReceive')->advancedDisagreeAssetReceive($applyId);
  935. break;
  936. case '14': // 资产退库
  937. $ret = model('AssetWithdraw')->advancedDisagreeAssetWithdraw($applyId);
  938. break;
  939. case '15': // 资产维修
  940. $ret = model('AssetRepair')->advancedDisagreeAssetRepair($applyId);
  941. break;
  942. case '16': // 资产处置
  943. $ret = model('AssetDisposal')->advancedDisagreeAssetDisposal($applyId);
  944. break;
  945. case '17': // 预算
  946. $ret = model('BudgetApply')->advancedDisagreeBudgetApply($applyId);
  947. break;
  948. case '18': // 用印
  949. $ret = model('OfficialSealApply')->advancedDisagreeSealApply($applyId);
  950. break;
  951. case '19': // 中心发文
  952. $ret = model('PostApply')->advancedDisagreePostApply($applyId);
  953. break;
  954. case '20': // 因私出国
  955. $ret = model('AbroadApply')->advancedDisagreeAbroadApply($applyId);
  956. break;
  957. case '21': // 日常支出
  958. $ret = model('BudgetPay')->advancedDisagreeBudgetPay($applyId);
  959. break;
  960. default:
  961. $ret = true;
  962. break;
  963. }
  964. return $ret;
  965. }
  966. // 获取未审批数量
  967. public function unApplyNums($userId,$orgId){
  968. $count = Db::name('apply_record')
  969. ->alias('ar')
  970. ->join('apply a','a.id = ar.apply_id')
  971. ->where('ar.status',0)
  972. ->where('ar.del',0)
  973. ->where('ar.type','in',[2,8])
  974. ->where('ar.user_id',$userId)
  975. ->where('a.org_id',$orgId)
  976. ->count();
  977. return $count;
  978. }
  979. }