Todo.php 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. <?php
  2. namespace app\common\model;
  3. use app\common\util\AppMsg;
  4. use app\hander\HelpHander;
  5. use think\Db;
  6. use think\Exception;
  7. class Todo extends Base
  8. {
  9. public $table = 'todo';
  10. public function formatTodo($v){
  11. $v['order_type'] = '';
  12. $v['order_type_matter'] = '';
  13. $v['address_title'] = '';
  14. $v['repair_priority'] = '';
  15. if($v['work_type_mode']==1){
  16. $typeInfo = (new \app\common\model\OrderType())
  17. ->getTypeByOrderId($v['order_id']);
  18. $v['order_type'] = isset($typeInfo['title'])?$typeInfo['title']:'';
  19. $v['order_type_matter'] = isset($typeInfo['child_title'])?$typeInfo['child_title']:'';
  20. $v['address_title'] = isset($typeInfo['address_title'])?$typeInfo['address_title']:'';
  21. $v['repair_priority'] = isset($typeInfo['repair_priority'])?$typeInfo['repair_priority']:'';
  22. $v['bx_sign'] = Db::name('todo')->where('id',$v['id'])->value('sign');
  23. }
  24. $v['work_type_mode_text'] = $this->getTableField('work_type_mode', ['id'=>$v['work_type_mode']], 'name');
  25. $v['real_name'] = $this->getTableField('user',['id'=>$v['create_user_id']],'real_name');
  26. $v['pause_cost'] = '';
  27. if(!empty($v['pause_time']) && !empty($v['pause_end']) && $v['todo_mode']==3){
  28. if(!empty($v['confirm_time'])){
  29. $v['time_cost'] = $this->getM1($v['done_time'],$v['confirm_time'],$v['pause_end'],$v['pause_time']);
  30. }else{
  31. $v['time_cost'] = '';
  32. }
  33. $v['pause_cost'] = $this->getM($v['pause_time'],$v['pause_end']);
  34. }else{
  35. $v['time_cost'] = $v['todo_mode']==3 && !empty($v['confirm_time'])?$this->getM($v['done_time'],$v['confirm_time']):'';
  36. }
  37. $pDep = '';
  38. $depInfo = Db::name('dep')
  39. ->where('id',$v['dep_id'])
  40. ->find();
  41. if($depInfo){
  42. $pDep = Db::name('dep_cate')
  43. ->where('id',$depInfo['cate_id'])
  44. ->value('title');
  45. }
  46. $v['dep_cate_name'] = $pDep;
  47. $v['source_type_text'] =$v['from']>0? isset(model('Orders')->source_type[$v['from']])?model('Orders')->source_type[$v['from']]:'':$this->getTableField('work_type_mode', ['id' => $v['work_type_mode']], 'name');
  48. $v['dispatch_time'] = $this->getM($v['to_create_time'],$v['create_time']);
  49. $v['jiedan_time'] = !empty($v['confirm_time'])?$this->getM($v['confirm_time'],$v['to_create_time']):'';
  50. $orderInfo = Db::name('orders')
  51. ->where('id',$v['order_id'])
  52. ->find();
  53. $v['dep'] = $this->getTableField('dep', ['id'=>$orderInfo['dep_id']], 'title');
  54. $v['order_info'] = model('orders')->formatOrder($orderInfo,1);
  55. if($v['work_type_mode']==3){
  56. $oc = Db::name('order_convey')
  57. ->where('order_id',$v['order_id'])
  58. ->find();
  59. $oc['type_name']=$v['type_name'] = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'title'):"";
  60. $oc['start_name']=$v['start_name'] = isset($oc['start'])?$this->getTableField('address',['id'=>$oc['start']],'title'):"";
  61. $oc['end_name'] =$v['end_name'] =isset($oc['end'])?$this->getTableField('address',['id'=>$oc['end']],'title'):'';
  62. $oc['device_name']= $v['device_name'] = isset($oc['device_id'])?$this->getTableField('convey_device',['id'=>$oc['device_id']],'title'):'';
  63. $v['xq_time'] = isset($oc['xq_time'])?$oc['xq_time']:'';
  64. $v['ywc_time'] = isset($oc['ywc_time'])?$oc['ywc_time']:"";
  65. $v['oc'] = $oc;
  66. $v['ocp'] = [];
  67. $todoConvey = Db::name('todo_convey')->where('todo_id',$v['id'])->find();
  68. $v['tc'] = $todoConvey;
  69. $cate = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'cate'):'';
  70. if($cate==1){
  71. $ocp = Db::name('order_convey_patient')
  72. ->where('order_id',$v['order_id'])
  73. ->find();
  74. $v['ocp'] = $ocp;
  75. }
  76. $v['tco'] = [
  77. 'start_time'=>'',
  78. 'end_time'=>'',
  79. ];
  80. $tco = Db::name('todo_convey')
  81. ->where('todo_id',$v['id'])
  82. ->find();
  83. if($tco){
  84. $v['tco'] = $tco;
  85. }
  86. }
  87. $pauseList = [];
  88. if($v['todo_mode']==2 && $v['pause']==1){
  89. $ll = Db::name('todo_puase')
  90. ->where('todo_id',$v['id'])
  91. ->select();
  92. foreach ($ll as $pp=>$dd) {
  93. $pauseList[$pp]['content'] = $dd['reason'];
  94. $pauseList[$pp]['timestamp'] = $dd['create_time'];
  95. $pauseList[$pp]['color'] ='#0bbd87';
  96. }
  97. }
  98. $v['pauseList'] = $pauseList;
  99. $todo_mate = Db::name('todo_mate')
  100. ->where('todo_id',$v['id'])
  101. ->select();
  102. if(!empty($todo_mate)){
  103. $cons = Db::name('todo_mate_item')
  104. ->alias('a')
  105. ->join('mate_goods b','b.id = a.items_id')
  106. ->where('a.todo_mate_id','in',array_column($todo_mate,'id'))
  107. ->field('a.*,b.title')
  108. ->select();
  109. foreach ($cons as $k1=>$v1){
  110. $v['cons'][] = [
  111. 'title' =>$v1['title'],
  112. 'total' =>$v1['total'],
  113. 'money' =>$v1['money'],
  114. 'total_money' =>$v1['total_money'],
  115. 'realName' =>$this->getTableField('user',['id'=>$v1['user_id']],'real_name'),
  116. ];
  117. }
  118. }
  119. return $v;
  120. }
  121. public function newFormatTodo($v){
  122. $v['order_type'] = '';
  123. $v['order_type_matter'] = '';
  124. $v['address_title'] = '';
  125. $v['repair_priority'] = '';
  126. if($v['work_type_mode']==1){
  127. $typeInfo = (new \app\common\model\OrderType())
  128. ->getTypeByOrderId($v['order_id']);
  129. $v['order_type'] = isset($typeInfo['title'])?$typeInfo['title']:'';
  130. $v['order_type_matter'] = isset($typeInfo['child_title'])?$typeInfo['child_title']:'';
  131. $v['address_title'] = isset($typeInfo['address_title'])?$typeInfo['address_title']:'';
  132. $v['repair_priority'] = isset($typeInfo['repair_priority'])?$typeInfo['repair_priority']:'';
  133. $v['bx_sign'] = Db::name('todo')->where('id',$v['id'])->value('sign');
  134. }
  135. $v['work_type_mode_text'] = $this->getTableField('work_type_mode', ['id'=>$v['work_type_mode']], 'name');
  136. $v['real_name'] = $this->getTableField('user',['id'=>$v['create_user_id']],'real_name');
  137. $v['sq_real_name'] = $this->getTableField('user',['id'=>$v['user_id']],'real_name');
  138. $v['pause_cost'] = '';
  139. if(!empty($v['pause_time']) && !empty($v['pause_end']) && $v['todo_mode']==3){
  140. if(!empty($v['confirm_time'])){
  141. $v['time_cost'] = $this->getM1($v['done_time'],$v['confirm_time'],$v['pause_end'],$v['pause_time']);
  142. }else{
  143. $v['time_cost'] = '';
  144. }
  145. $v['pause_cost'] = $this->getM($v['pause_time'],$v['pause_end']);
  146. }else{
  147. $v['time_cost'] = $v['todo_mode']==3 && !empty($v['confirm_time'])?$this->getM($v['done_time'],$v['confirm_time']):'';
  148. }
  149. $pDep = '';
  150. $depInfo = Db::name('dep')
  151. ->where('id',$v['dep_id'])
  152. ->find();
  153. if($depInfo){
  154. $pDep = Db::name('dep_cate')
  155. ->where('id',$depInfo['cate_id'])
  156. ->value('title');
  157. }
  158. $v['dep_cate_name'] = $pDep;
  159. $v['source_type_text'] =$v['from']>0? isset(model('Orders')->source_type[$v['from']])?model('Orders')->source_type[$v['from']]:'':$this->getTableField('work_type_mode', ['id' => $v['work_type_mode']], 'name');
  160. $v['dispatch_time'] = $this->getM($v['to_create_time'],$v['create_time']);
  161. $v['jiedan_time'] = !empty($v['confirm_time'])?$this->getM($v['confirm_time'],$v['to_create_time']):'';
  162. $orderInfo = Db::name('orders')
  163. ->where('id',$v['order_id'])
  164. ->find();
  165. $v['dep'] = $this->getTableField('dep', ['id'=>$orderInfo['dep_id']], 'title');
  166. if($v['work_type_mode']==3){
  167. $oc = Db::name('order_convey')
  168. ->where('order_id',$v['order_id'])
  169. ->find();
  170. $oc['type_name']=$v['type_name'] = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'title'):"";
  171. $oc['start_name']=$v['start_name'] = isset($oc['start'])?$this->getTableField('address',['id'=>$oc['start']],'title'):"";
  172. $oc['end_name'] =$v['end_name'] =isset($oc['end'])?$this->getTableField('address',['id'=>$oc['end']],'title'):'';
  173. $oc['device_name']= $v['device_name'] = isset($oc['device_id'])?$this->getTableField('convey_device',['id'=>$oc['device_id']],'title'):'';
  174. $v['xq_time'] = isset($oc['xq_time'])?$oc['xq_time']:'';
  175. $v['ywc_time'] = isset($oc['ywc_time'])?$oc['ywc_time']:"";
  176. $v['oc'] = $oc;
  177. $v['ocp'] = [];
  178. $v['ocps'] = [
  179. 'bed_number'=>'',
  180. 'name'=>'',
  181. ];
  182. $cate = isset($oc['type'])?$this->getTableField('convey_cate',['id'=>$oc['type']],'cate'):'';
  183. if($cate==1){
  184. $ocp = Db::name('order_convey_patient')
  185. ->where('order_id',$v['order_id'])
  186. ->find();
  187. $v['ocp'] = $ocp;
  188. $v['ocps'] = $ocp;
  189. }
  190. $v['tco'] = [
  191. 'start_time'=>'',
  192. 'end_time'=>'',
  193. ];
  194. $tco = Db::name('todo_convey')
  195. ->where('todo_id',$v['id'])
  196. ->find();
  197. if($tco){
  198. $v['tco'] = $tco;
  199. }
  200. }
  201. // $pauseList = [];
  202. // if($v['todo_mode']==2 && $v['pause']==1){
  203. // $ll = Db::name('todo_puase')
  204. // ->where('todo_id',$v['id'])
  205. // ->select();
  206. // foreach ($ll as $pp=>$dd) {
  207. // $pauseList[$pp]['content'] = $dd['reason'];
  208. // $pauseList[$pp]['timestamp'] = $dd['create_time'];
  209. // $pauseList[$pp]['color'] ='#0bbd87';
  210. // }
  211. // }
  212. // $v['pauseList'] = $pauseList;
  213. return $v;
  214. }
  215. public function apiFormatTodo($v){
  216. $v['work_type_mode_text'] = $this->getTableField('work_type_mode', ['id'=>$v['work_type_mode']], 'name');
  217. $v['todo_mode_text'] = $this->getTableField('todo_mode', ['id'=>$v['todo_mode']], 'out_content');
  218. $v['real_name'] = $this->getTableField('user',['id'=>$v['to_user_id']],'real_name');
  219. $v['time_cost'] = $v['todo_mode']==3 && !empty($v['confirm_time'])?$this->getM($v['done_time'],$v['confirm_time']):'';
  220. $v['confirm_time'] = $v['confirm_time']?$v['confirm_time']:"";
  221. $v['done_time'] = $v['done_time']?$v['done_time']:"";
  222. $orderInfo = Db::name('orders')
  223. ->where('id',$v['order_id'])
  224. ->find();
  225. $v['dep'] = $this->getTableField('dep', ['id'=>$orderInfo['dep_id']], 'title');
  226. return $v;
  227. }
  228. public function getM($do,$cof){
  229. $diff = strtotime($do) - strtotime($cof);
  230. $days = floor(($diff )/ (60*60*24));
  231. $hours = floor(($diff - $days*60*60*24) / (60*60));
  232. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  233. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  234. if ($diff < 60) {
  235. $time_cost = $seconds."秒";
  236. } else if ($diff >= 60 && $diff < 60*60) {
  237. $time_cost = $minutes."分钟".$seconds."秒";
  238. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  239. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  240. } else {
  241. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  242. }
  243. return $time_cost;
  244. }
  245. public function getM1($do,$cof,$e,$a){
  246. $diff = strtotime($do) - strtotime($cof);
  247. $aa = strtotime($e) - strtotime($a);
  248. $diff = $diff-$aa;
  249. $days = floor(($diff )/ (60*60*24));
  250. $hours = floor(($diff - $days*60*60*24) / (60*60));
  251. $minutes = floor(($diff - $days*60*60*24 - $hours*60*60)/ 60);
  252. $seconds = floor(($diff - $days*60*60*24 - $hours*60*60 - $minutes*60));
  253. if ($diff < 60) {
  254. $time_cost = $seconds."秒";
  255. } else if ($diff >= 60 && $diff < 60*60) {
  256. $time_cost = $minutes."分钟".$seconds."秒";
  257. } else if ($diff >= 60*60 && $diff < 60*60*24) {
  258. $time_cost = $hours."小时".$minutes."分钟".$seconds."秒";
  259. } else {
  260. $time_cost = $days."天".$hours."小时".$minutes."分钟".$seconds."秒";
  261. }
  262. return $time_cost;
  263. }
  264. // 检查工单状态变化后续的操作
  265. public function checkToDo($orderId,$todoId,$todoMode){
  266. $list = Db::name('todo')
  267. ->where('todo_mode','in',array(1,2,4))
  268. ->where('order_id',$orderId)
  269. ->where('id','<>',$todoId)
  270. ->where('del',0)
  271. ->field('todo_mode')
  272. ->select();
  273. $todoInfo = Db::name('todo')
  274. ->where('id',$todoId)
  275. ->find();
  276. Db::name('task')
  277. ->where('bus_id', $todoId)
  278. ->where('user_id', $todoInfo['to_user_id'])
  279. ->where('type', 1)
  280. ->delete();
  281. if($list){
  282. return true; //不需要修改
  283. }
  284. if($todoMode == 3){ // 完成
  285. $res = Db::name('orders')
  286. ->where('id',$orderId)->update([
  287. 'order_mode' => 5,
  288. 'finish_time' => date('Y-m-d H:i:s')
  289. ]);
  290. if(!$res){
  291. return false;
  292. }
  293. $this->finishTodoPush($orderId,$todoId);
  294. return true;
  295. }else if ($todoMode==5){//无法完成
  296. $check = Db::name('todo')
  297. ->where('todo_mode',3)
  298. ->where('order_id',$orderId)
  299. ->where('id','<>',$todoId)
  300. ->field('todo_mode')
  301. ->find();
  302. if($check){
  303. $res = Db::name('orders')
  304. ->where('id',$orderId)->update([
  305. 'order_mode' => 5,
  306. 'finish_time' => date('Y-m-d H:i:s')
  307. ]);
  308. if($res){
  309. $this->finishTodoPush($orderId,$todoId);
  310. return true;
  311. }
  312. return false;
  313. }else{
  314. $res = Db::name('orders')
  315. ->where('id',$orderId)
  316. ->update(['order_mode'=>7,'update_time'=>getTime()]);
  317. if($res){
  318. return true;
  319. }
  320. return false;
  321. }
  322. } else { //取消
  323. $res = Db::name('orders')
  324. ->where('id',$orderId)->update([
  325. 'order_mode' =>3,
  326. ]);
  327. return $res?true:false;
  328. }
  329. }
  330. public function finishTodoPush($orderId,$todoId){
  331. $todoInfo = Db::name('todo')
  332. ->where('id',$todoId)
  333. ->find();
  334. // 投诉完成推送
  335. model('Complain')->pushCreateUser($orderId,0);
  336. // 是病人运送订单且需要收费时需要生成,缴费单
  337. // 检查运送收费开发是否开启
  338. $ysoff = model('Config')->getConfig('org_ys_switch',$todoInfo['org_id']);
  339. $money1 = model('Config')->getConfig('org_ys_init_money',$todoInfo['org_id']);
  340. $money2 = model('Config')->getConfig('org_ys_lj_money',$todoInfo['org_id']);
  341. $money1 = $money1?$money1:0;
  342. $money2 = $money2?$money2:0;
  343. if($ysoff){
  344. // 检查订单是不是病人运送
  345. $convey = Db::name('order_convey')
  346. ->alias('a')
  347. ->join('convey_cate b','a.type = b.id')
  348. ->where('a.order_id',$orderId)
  349. ->where('b.cate',1)
  350. ->field('a.*')
  351. ->find();
  352. if($convey){
  353. $count = Db::name('order_convey_end')->where('order_convey_id',$convey['id'])->count();
  354. $money = round($money1 + $count*$money2,2);
  355. if($money > 0){
  356. $ret = Db::name('order_convey_pay')->insert([
  357. 'sn' => get_unique_id('YS'),
  358. 'org_id' => $todoInfo['org_id'],
  359. 'order_id' => $convey['order_id'],
  360. 'order_convey_id' => $convey['id'],
  361. 'money' => $money,
  362. 'status' => 0,
  363. 'create_time' => date('Y-m-d H:i:s'),
  364. 'type' => 0
  365. ]);
  366. if(!$ret){
  367. return false;
  368. }
  369. }
  370. }
  371. }
  372. }
  373. public function cancel($id,$reason){
  374. $info = $this->where('id',$id)->find();
  375. if (!$info) {
  376. $this->error='工单不存在';
  377. return false;
  378. }
  379. if (!in_array($info['todo_mode'], array(1, 2, 4))) {
  380. $this->error='此状态不能取消工单';
  381. return false;
  382. }
  383. $this->startTrans();
  384. try {
  385. if ($info['todo_mode'] == 1 || $info['todo_mode'] == 2) {
  386. $mode = 6;
  387. } else {
  388. $mode = 7;
  389. }
  390. $ret = $this->where('id', $id)->update(['todo_mode'=>$mode,'cancel_reason'=>$reason]);
  391. if (!$ret) {
  392. exception('工单状态修改失败');
  393. }
  394. $ret = $this->checktodo($info['order_id'],$id,6);
  395. if(!$ret){
  396. exception('订单修改失败');
  397. }
  398. $this->commit();
  399. return true;
  400. } catch (Exception $e) {
  401. $this->rollback();
  402. $this->error=$e->getMessage();
  403. return false;
  404. }
  405. }
  406. public function finish($id){
  407. $info = $this->where('id',$id)->find();
  408. if (!$info) {
  409. $this->error='工单不存在';
  410. return false;
  411. }
  412. if (!in_array($info['todo_mode'], array(1, 2))) {
  413. $this->error='此状态不能完成工单';
  414. return false;
  415. }
  416. $this->startTrans();
  417. try {
  418. $curTime = date('Y-m-d H:i:s');
  419. $cfTime = $info['confirm_time'];
  420. $sData = array(
  421. 'todo_mode' => 3,
  422. 'done_time' => $curTime,
  423. );
  424. if($info['todo_mode'] == 1){
  425. $cfTime = $sData['confirm_time'] = $info['create_time'];
  426. }
  427. $wc_time = time() - strtotime($cfTime);
  428. $sData['wc_time'] = $cfTime?$wc_time:0;
  429. $ret = $this->where('id',$id)->update($sData);
  430. if(!$ret){
  431. exception('操作失败');
  432. }
  433. $ret = $this->checktodo($info['order_id'],$info['id'],3);
  434. if(!$ret){
  435. exception('订单修改失败');
  436. }
  437. $this->commit();
  438. return true;
  439. } catch (Exception $e) {
  440. $this->rollback();
  441. $this->error=$e->getMessage();
  442. return false;
  443. }
  444. }
  445. //后台重新分配
  446. public function send($id,$userId,$data){
  447. $info = Db::name('todo_view')->where('id',$id)->find();
  448. if(!$info||$info['org_id']!=$data['org_id']){
  449. $this->error='订单不存在';
  450. return false;
  451. }
  452. if(!in_array($info['todo_mode'],array(4))){
  453. $this->error='此状态不能重新下发任务';
  454. return false;
  455. }
  456. if($info['order_mode'] != 4){
  457. $this->error='订单已完成不能重新下发任务';
  458. return false;
  459. }
  460. if(!isset($data['to_user_id'])||empty($data['to_user_id'])){
  461. $this->error='请选择执行人';
  462. return false;
  463. }
  464. $send_user_num = (new Orders())->sendUserNum($info['work_type_mode'],$data['org_id']);
  465. $users = explode(',', $data['to_user_id']);
  466. if($send_user_num==1 && count($users) >1){
  467. $this->error = '执行人只能选择单人';
  468. return false;
  469. }
  470. $to_user_id = array_unique($users);
  471. $todo = array();
  472. $this->startTrans();
  473. try{
  474. //todo::订单状态暂时不做修改
  475. //取消驳回的订单
  476. $res = $this
  477. ->where('id',$id)->update(['todo_mode'=>7]);
  478. if(!$res){
  479. exception('订单状态更改失败');
  480. }
  481. $todoData = [
  482. 'order_id' => $info['order_id'],
  483. 'todo_content' => $data['todo_content'],
  484. 'create_user_id' => $userId,
  485. 'org_id' => $data['org_id'],
  486. 'create_time' => getTime(),
  487. 'todo_mode' => 1,
  488. 'work_type_mode' => $info['work_type_mode'],
  489. 'create_yyyy' => date('Y'),
  490. 'create_yyyymm' => date('Ym'),
  491. 'create_yyyymmdd' => date('Ymd'),
  492. ];
  493. $taskData=[
  494. 'org_id'=>$data['org_id'],
  495. 'type'=>1,
  496. 'start_time'=>getTime(),
  497. 'create_time'=>getTime(),
  498. ];
  499. $pusharr =[];
  500. $sns = [];
  501. foreach ($to_user_id as $k => $v) {
  502. if(empty($v)){
  503. continue;
  504. }
  505. $todoData['to_user_id'] = $v;
  506. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  507. while (true){
  508. if(in_array($todoData['sn'],$sns)){
  509. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  510. }else{
  511. $sns[] = $todoData['sn'];
  512. break;
  513. }
  514. }
  515. $res = Db::name('todo')
  516. ->insertGetId($todoData);
  517. if (!$res){
  518. \exception('执行人:'.$v.'派单失败');
  519. }
  520. $taskData['user_id'] = $v;
  521. $taskData['bus_id'] = $res;
  522. $res = Db::name('task')
  523. ->insert($taskData);
  524. if (!$res){
  525. \exception('执行人:'.$v.'任务保存失败');
  526. }
  527. $pusharr[] = [
  528. 'user_id'=>$v,
  529. 'todo_id'=>$res
  530. ];
  531. }
  532. $res = Db::name('orders')->where('id',$info['order_id'])
  533. ->update(['order_mode'=>4,'send_time'=>getTime()]);
  534. if (!$res){
  535. \exception('订单更新失败');
  536. }
  537. if($info['work_type_mode']==1){//报修订单
  538. $rData = [];
  539. if(isset($data['type_id']) && !empty($data['type_id'])){
  540. $rData['type_id'] = $data['type_id'];
  541. }
  542. if(isset($data['address_id']) && !empty($data['address_id'])){
  543. $rData['address_id'] = $data['address_id'];
  544. }
  545. if(!empty($rData)){
  546. $rData['order_id'] = $info['order_id'];
  547. Db::name('order_repair')
  548. ->where('order_id',$info['order_id'])->delete();
  549. $res = Db::name('order_repair')
  550. ->insert($rData);
  551. if(!$res){
  552. \exception('保存维修扩展失败');
  553. }
  554. }
  555. }
  556. $this->commit();
  557. if($pusharr){
  558. foreach ($pusharr as $k=>$v){
  559. // 极光推送
  560. send_jpush([$v['user_id']],AppMsg::PUSH_WORKER_ORDER_SEND,'',['id'=>$v['todo_id']]);
  561. }
  562. }
  563. return true;
  564. }catch (Exception $e){
  565. $this->rollback();
  566. $this->error=$e->getMessage();
  567. return false;
  568. }
  569. }
  570. //api 工单列表
  571. public function lists($page,$size,$userId,$orgId,$type){
  572. $offset = ($page-1)*$size;
  573. if($type==1){//已完成
  574. $map[] = ['org_id','=',$orgId];
  575. $map[] = ['del','=',0];
  576. $map[] = ['to_user_id','=',$userId];
  577. $map[] = ['todo_mode','=',3];
  578. $list = $this->where($map)
  579. ->limit($offset,$size)
  580. ->order('id','desc')
  581. ->select();
  582. $list = $list?$list->toArray():[];
  583. }else if ($type==2){//已评价
  584. $list = Db::name('todo')
  585. ->alias('a')
  586. ->join('orders b','b.id=a.order_id','left')
  587. ->where('a.to_user_id',$userId)
  588. ->where('a.del',0)
  589. ->where('b.del',0)
  590. ->where('a.org_id',$orgId)
  591. ->where('b.order_mode',6)
  592. ->field('a.*')
  593. ->order('a.id','desc')
  594. ->limit($offset,$size)
  595. ->select();
  596. }else if ($type==0){//所有
  597. $list = Db::name('todo')
  598. ->alias('a')
  599. ->join('orders b','b.id=a.order_id','left')
  600. ->where('a.to_user_id',$userId)
  601. ->where('a.del',0)
  602. ->where('b.del',0)
  603. ->where('a.org_id',$orgId)
  604. ->where(function ($query){
  605. $query->where('a.todo_mode', 3)->whereor('b.order_mode', 6);
  606. })
  607. ->field('a.*')
  608. ->order('a.id','desc')
  609. ->limit($offset,$size)
  610. ->select();
  611. }
  612. $n = [];
  613. foreach ($list as $k=>$v){
  614. $a= $this->apiFormatTodo($v);
  615. $n[] = formatArray(
  616. [
  617. 'id',
  618. 'confirm_time',
  619. 'done_time',
  620. 'work_type_mode',
  621. 'sn'
  622. ]
  623. , $a);
  624. }
  625. return $n;
  626. }
  627. //api工单详情
  628. public function apiDetail($todoId){
  629. $info = Db::name('todo_view')->where('id',$todoId)
  630. ->find();
  631. if(empty($info)){
  632. HelpHander::error('工单信息不存在');
  633. }
  634. $order = Db::name('orders')
  635. ->where('id',$info['order_id'])
  636. ->find();
  637. $orderInfo = (new Orders())->apiFormatOrder($order,1,$todoId);
  638. if($order['work_type_mode'] == 3){
  639. // 地点路径
  640. $conveyends = Db::name('order_convey_end')
  641. ->alias('a')
  642. ->join('address b','b.id = a.addr')
  643. ->where('a.order_id',$order['id'])
  644. ->where('a.del',0)
  645. ->order('a.id asc')
  646. ->field('a.*,b.title')
  647. ->select();
  648. $orderInfo['ends'] = $conveyends?$conveyends:[];
  649. $payinfo = [
  650. 'is_pay' => 0,
  651. 'id' => 0,
  652. 'url' => '',
  653. 'money' => 0,
  654. 'remark' => '',
  655. 'type' => 1,
  656. 'pay_time' => '',
  657. ];
  658. // 是否需要支付
  659. $pay = Db::name('order_convey_pay')->where('order_id',$order['id'])->find();
  660. if($pay){
  661. $payinfo['is_pay'] = $pay['status'] == 0?0:1;
  662. $payinfo['url'] = url('h5/Index/pay',['id'=>$pay['id']],false,true);
  663. $payinfo['money'] = round($pay['money'],2);
  664. $payinfo['remark'] = $pay['remark'];
  665. $payinfo['pay_time'] = $pay['pay_time']?$pay['pay_time']:'';
  666. $payinfo['id'] = $pay['id'];
  667. }
  668. $orderInfo['pay'] = $payinfo;
  669. }
  670. return $orderInfo;
  671. }
  672. //处理驳回订单
  673. public function createNtbo($todoId,$toUserIdArray,$todoContent,$userId,$typeId,$addressId){
  674. $todo=$this
  675. ->where('id',$todoId)->find();
  676. if(!$todo || $todo['del'] == 1){
  677. $this->error = '工单不存在';
  678. return false;
  679. }
  680. if($todo['todo_mode'] != 4){
  681. $this->error = '无权限分配订单';
  682. return false;
  683. }
  684. if(!isset($toUserIdArray)||empty($toUserIdArray)){
  685. $this->error='请选择执行人';
  686. return false;
  687. }
  688. $send_user_num = (new Orders())->sendUserNum($todo['work_type_mode'],$todo['org_id']);
  689. $users = explode(',', $toUserIdArray);
  690. if($send_user_num==1 && count($users) >1){
  691. $this->error = '执行人只能选择单人';
  692. return false;
  693. }
  694. $to_user_id = array_unique($users);
  695. $this->startTrans();
  696. try{
  697. $res = $this
  698. ->where('id',$todoId)->update(['todo_mode'=>7]);
  699. if(!$res){
  700. \exception('订单状态更改失败');
  701. }
  702. if($todo['work_type_mode']==1){//报修订单
  703. $rData = [];
  704. if(!empty($typeId) && $typeId>0 ){
  705. $rData['type_id'] =$typeId;
  706. }
  707. if(!empty($addressId) && $addressId>0){
  708. $rData['address_id'] = $addressId;
  709. }
  710. if(!empty($rData)){
  711. $rData['order_id'] = $todo['order_id'];
  712. Db::name('order_repair')
  713. ->where('order_id',$todo['order_id'])->delete();
  714. $res = Db::name('order_repair')
  715. ->insert($rData);
  716. if(!$res){
  717. \exception('保存维修扩展失败');
  718. }
  719. }
  720. }
  721. $todoData = [
  722. 'order_id' => $todo['order_id'],
  723. 'todo_content' => $todoContent,
  724. 'create_user_id' => $userId,
  725. 'org_id' => $todo['org_id'],
  726. 'create_time' => getTime(),
  727. 'todo_mode' => 1,
  728. 'work_type_mode' => $todo['work_type_mode'],
  729. 'create_yyyy' => date('Y'),
  730. 'create_yyyymm' => date('Ym'),
  731. 'create_yyyymmdd' => date('Ymd'),
  732. ];
  733. $taskData=[
  734. 'org_id'=>$todo['org_id'],
  735. 'type'=>1,
  736. 'start_time'=>getTime(),
  737. 'create_time'=>getTime(),
  738. ];
  739. $sns = [];
  740. foreach ($to_user_id as $k => $v) {
  741. if(empty($v)){
  742. continue;
  743. }
  744. $todoData['to_user_id'] = $v;
  745. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  746. while (true){
  747. if(in_array($todoData['sn'],$sns)){
  748. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  749. }else{
  750. $sns[] = $todoData['sn'];
  751. break;
  752. }
  753. }
  754. $res = Db::name('todo')
  755. ->insertGetId($todoData);
  756. if (!$res){
  757. \exception('执行人:'.$v.'派单失败');
  758. }
  759. $taskData['user_id'] = $v;
  760. $taskData['bus_id'] = $res;
  761. $res = Db::name('task')
  762. ->insert($taskData);
  763. if (!$res){
  764. \exception('执行人:'.$v.'任务保存失败');
  765. }
  766. // 极光推送
  767. send_jpush([$v],AppMsg::PUSH_WORKER_ORDER_SEND,'',['id'=>$res]);
  768. }
  769. $this->commit();
  770. return true;
  771. }catch (Exception $e){
  772. $this->rollback();
  773. return false;
  774. }
  775. }
  776. //修改工单状态 4 驳回 5客观原因
  777. public function updateState($todoId,$todoMode,$nodoReason,$userId,$rejectVoice){
  778. $todo = $this
  779. ->where('id',$todoId)
  780. ->where('del',0)
  781. ->find();
  782. if(!$todo){
  783. $this->error = '工单不存在';
  784. return false;
  785. }
  786. if($todoMode == 4){ // 驳回
  787. $bxConfigOff = model('Config')->getConfig('bh_orders_off',$todo['org_id']);
  788. if($bxConfigOff !=1){
  789. $this->error = '驳回开关已关闭,不能驳回';
  790. return false;
  791. }
  792. if($todo['todo_mode']!==1){
  793. $this->error = '当前状态不能驳回';
  794. return false;
  795. }
  796. $this->startTrans();
  797. try{
  798. $ret = $this
  799. ->where('id',$todoId)
  800. ->update(['todo_mode'=>$todoMode,
  801. 'nodo_reason'=>$nodoReason,
  802. 'reject_voice'=>$rejectVoice,
  803. 'reject_time' => date('Y-m-d H:i:s')]);
  804. if(!$ret){
  805. \exception('操作失败');
  806. }
  807. Db::name('task')
  808. ->where('org_id',$todo['org_id'])
  809. ->where('user_id',$userId)
  810. ->where('type',1)
  811. ->where('bus_id',$todoId)
  812. ->delete();
  813. $this->commit();
  814. }catch (Exception $e){
  815. $this->rollback();
  816. $this->error = $e->getMessage();
  817. return false;
  818. }
  819. }else if($todoMode == 2){
  820. if($todo['todo_mode']!==1){
  821. $this->error = '当前状态不能领取';
  822. return false;
  823. }
  824. $XY_TIME = time() - strtotime($todo['create_time']);
  825. $ret = $this->where('id',$todoId)->update([
  826. 'todo_mode'=>$todoMode,
  827. 'confirm_time' => date('Y-m-d H:i:s'),
  828. 'xy_time' => $XY_TIME
  829. ]);
  830. // $todoIds = Db::name('todo')
  831. // ->where('id','<>',$todoId)
  832. // ->where('order_id','=',$todo['order_id'])
  833. // ->column('id');
  834. // if(!empty($todoIds)){
  835. // $r = Db::name('todo')
  836. // ->where('id','in',$todoIds)
  837. // ->delete();
  838. // Db::name('task')
  839. // ->where('bus_id', 'in', $todoIds)
  840. // ->where('type', 1)
  841. // ->delete();
  842. // if(!$r){
  843. // $this->error = '操作失败';
  844. // return false;
  845. // }
  846. // }
  847. if(!$ret){
  848. $this->error = '操作失败';
  849. return false;
  850. }
  851. }else if($todoMode == 6){ // 取消驳回工单
  852. $this->startTrans();
  853. try{
  854. $ret = $this
  855. ->where('id',$todoId)
  856. ->update(['todo_mode'=>$todoMode,
  857. 'cancel_reason' => $nodoReason]);
  858. if(!$ret){
  859. \exception('订单错误失败');
  860. }
  861. $ret = $this->checkToDo($todo['order_id'],$todoId,$todoMode);
  862. if(!$ret){
  863. \exception('订单修改失败');
  864. }
  865. Db::name('task')
  866. ->where('org_id',$todo['org_id'])
  867. ->where('user_id',$userId)
  868. ->where('type',1)
  869. ->where('bus_id',$todoId)
  870. ->delete();
  871. $this->commit();
  872. }catch (Exception $e){
  873. $this->rollback();
  874. $this->error = $e->getMessage();
  875. return false;
  876. }
  877. }
  878. return true;
  879. }
  880. // 工人完成提交任务/无法完成
  881. public function finishTodo($todoId,$todoMode,$content,$userId,$images,$consItems,$sign){
  882. $todo = $this
  883. ->where('id',$todoId)
  884. ->where('del',0)->find();
  885. if(!$todo){
  886. $this->error = '工单不存在';
  887. return false;
  888. }
  889. if($todo['to_user_id'] != $userId || $todo['todo_mode'] != 2){
  890. $this->error = '无权限操作';
  891. return false;
  892. }
  893. if($todo['work_type_mode']== 1 && $todo['todo_mode'] == 2 && $todo['pause'] == 1){
  894. $this->error = '工单正在挂起,无法完成';
  895. return false;
  896. }
  897. if($todo['work_type_mode']==1 && $todoMode==3){
  898. $off =(new Config())->getConfig('org_sign',$todo['org_id']);
  899. if($off==1 && empty($sign)){
  900. $this->error = '请上传签名';
  901. return false;
  902. }
  903. }
  904. $this->startTrans();
  905. try{
  906. if($todo['pause'] == 2){
  907. $ct = strtotime($todo['confirm_time']);
  908. $pst = strtotime($todo['pause_time']);
  909. $pet = strtotime($todo['pause_end']);
  910. $WC_TIME = ($pst - $ct) + time()-$pet;
  911. }else{
  912. $WC_TIME = time() - strtotime($todo['confirm_time']);
  913. }
  914. $curTime = date('Y-m-d H:i:s');
  915. $ret = $this
  916. ->where('id',$todoId)->update([
  917. 'nodo_reason' => $content,
  918. 'images' => $images,
  919. 'todo_mode' => $todoMode,
  920. 'done_time' => $curTime,
  921. 'wc_time' => $WC_TIME,
  922. 'sign' => $sign
  923. ]);
  924. if(!$ret){
  925. \exception('工单修改失败');
  926. }
  927. if($todoMode == 3 && $consItems){ // 工单完成且有耗材
  928. $consItems = json_decode($consItems,true);
  929. $mate = [
  930. 'todo_id'=>$todoId,
  931. 'order_id'=>$todo['order_id'],
  932. 'org_id'=>$todo['org_id'],
  933. 'user_id'=>$userId,
  934. 'create_time'=>getTime()
  935. ];
  936. $todo_mate_id = Db::name('todo_mate')
  937. ->insertGetId($mate);
  938. if(!$todo_mate_id){
  939. \exception('订单使用物品记录失败');
  940. }
  941. $items = [];
  942. foreach ($consItems as $k=>$v){
  943. $itemInfo = Db::name('mate_goods')
  944. ->where('id',$v['itemsId'])
  945. ->find();
  946. if($itemInfo['nums'] < $v['total']){
  947. \exception($itemInfo['title'].' 库存不足');
  948. }
  949. $items[] = [
  950. 'todo_mate_id'=>$todo_mate_id,
  951. 'items_id'=>$v['itemsId'],
  952. 'total'=>$v['total'],
  953. 'create_time'=>getTime(),
  954. 'user_id'=>$userId,
  955. 'money'=>$itemInfo['price'],
  956. 'total_money'=>$itemInfo['price']*$v['total'],
  957. ];
  958. $res = Db::name('mate_goods')
  959. ->where('id',$v['itemsId'])
  960. ->setDec('nums',$v['total']);
  961. if(!$res){
  962. \exception($itemInfo['title'].' 数量修改失败');
  963. }
  964. }
  965. $res = Db::name('todo_mate_item')
  966. ->insertAll($items);
  967. if(!$res){
  968. \exception('物品使用记录失败');
  969. }
  970. }
  971. $ret = $this->checkToDo($todo['order_id'],$todoId,$todoMode);
  972. Db::name('task')
  973. ->where('bus_id', '=', $todoId)
  974. ->where('type', 1)
  975. ->delete();
  976. if(!$ret){
  977. \exception('订单修改失败');
  978. }
  979. $this->commit();
  980. }catch (Exception $e){
  981. $this->error = $e->getMessage();
  982. $this->rollback();
  983. return false;
  984. }
  985. return true;
  986. }
  987. //获取物品列表
  988. public function getMateGoods($orgId,$userId,$title,$page,$size){
  989. $map[] = ['org_id','=',$orgId];
  990. $map[] = ['enable','=',1];
  991. $map[] = ['del','=',0];
  992. if($title){
  993. $map[] = ['title','like','%'.$title.'%'];
  994. }
  995. $offset = ($page-1)*$size;
  996. $list = (new MateGoods())->getList($offset,$size,$map,'id desc');
  997. $a = [];
  998. foreach ($list as $k=>$v){
  999. $user_cons = Db::name('user_cons')
  1000. ->where('user_id',$userId)
  1001. ->where('goods_id',$v['id'])
  1002. ->find();
  1003. $v['is_fav'] = $user_cons?1:0;
  1004. $a[] = formatArray([
  1005. 'id','price','nums','title','spec','is_fav'
  1006. ],$v);
  1007. }
  1008. return $a;
  1009. }
  1010. //收藏/取消收藏
  1011. public function favGoods($userId,$type,$goodsId){
  1012. if($type==0){
  1013. $res = Db::name('user_cons')
  1014. ->where('goods_id',$goodsId)
  1015. ->where('user_id',$userId)
  1016. ->delete();
  1017. }else{
  1018. if(Db::name('user_cons')
  1019. ->where('goods_id',$goodsId)
  1020. ->where('user_id',$userId)->find()){
  1021. HelpHander::error('该物品已收藏');
  1022. }
  1023. $res = Db::name('user_cons')
  1024. ->insertGetId([
  1025. 'goods_id'=>$goodsId,
  1026. 'user_id'=>$userId,
  1027. ]);
  1028. }
  1029. return $res;
  1030. }
  1031. //收藏物品列表
  1032. public function favList($userId,$title){
  1033. if($title){
  1034. $map[] = ['b.title','like','%'.$title.'%'];
  1035. }
  1036. $map[] = ['a.user_id','=',$userId];
  1037. $map[] = ['b.enable','=',1];
  1038. $map[] = ['b.del','=',0];
  1039. $list = Db::name('user_cons')
  1040. ->alias('a')
  1041. ->join('mate_goods b','a.goods_id = b.id')
  1042. ->where($map)
  1043. ->order('a.id desc')
  1044. ->field('b.*')
  1045. ->select();
  1046. $a = [];
  1047. foreach ($list as $k=>$v){
  1048. $a[] = formatArray([
  1049. 'id','price','nums','title','spec',
  1050. ],$v);
  1051. }
  1052. return $a;
  1053. }
  1054. }