Todo.php 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  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. if($info['work_type_mode'] == 3){
  438. // $wlps = Db::connect('db_config_jili')->name('wlps')->where('order_id',$info['order_id'])->find();
  439. $wlps = Db::name('wlps')->where('order_id',$info['order_id'])->find();
  440. if($wlps){
  441. $user = Db::name('user')->where('id',$info['to_user_id'])->find();
  442. // Db::connect('db_config_jili')->name('wlps')
  443. // ->where('id',$wlps['id'])
  444. // ->update([
  445. // 'paisr' => $user?$user['user_id']:'',
  446. // 'paisr_name' => $user?$user['real_name']:'',
  447. // 'paisr_phone' => $user?$user['mobile']:'',
  448. // 'pais_time' => date('Y-m-d H:i:s')
  449. // ]);
  450. Db::name('wlps')
  451. ->where('id',$wlps['id'])
  452. ->update([
  453. 'paisr' => $user?$user['id']:'',
  454. 'paisr_name' => $user?$user['real_name']:'',
  455. 'paisr_phone' => $user?$user['mobile']:'',
  456. 'pais_time' => date('Y-m-d H:i:s')
  457. ]);
  458. }
  459. }
  460. $this->commit();
  461. return true;
  462. } catch (Exception $e) {
  463. $this->rollback();
  464. $this->error=$e->getMessage();
  465. return false;
  466. }
  467. }
  468. //后台重新分配
  469. public function send($id,$userId,$data){
  470. $info = Db::name('todo_view')->where('id',$id)->find();
  471. if(!$info||$info['org_id']!=$data['org_id']){
  472. $this->error='订单不存在';
  473. return false;
  474. }
  475. if(!in_array($info['todo_mode'],array(4))){
  476. $this->error='此状态不能重新下发任务';
  477. return false;
  478. }
  479. if($info['order_mode'] != 4){
  480. $this->error='订单已完成不能重新下发任务';
  481. return false;
  482. }
  483. if(!isset($data['to_user_id'])||empty($data['to_user_id'])){
  484. $this->error='请选择执行人';
  485. return false;
  486. }
  487. $send_user_num = (new Orders())->sendUserNum($info['work_type_mode'],$data['org_id']);
  488. $users = explode(',', $data['to_user_id']);
  489. if($send_user_num==1 && count($users) >1){
  490. $this->error = '执行人只能选择单人';
  491. return false;
  492. }
  493. $to_user_id = array_unique($users);
  494. $todo = array();
  495. $this->startTrans();
  496. try{
  497. //todo::订单状态暂时不做修改
  498. //取消驳回的订单
  499. $res = $this
  500. ->where('id',$id)->update(['todo_mode'=>7]);
  501. if(!$res){
  502. exception('订单状态更改失败');
  503. }
  504. $todoData = [
  505. 'order_id' => $info['order_id'],
  506. 'todo_content' => $data['todo_content'],
  507. 'create_user_id' => $userId,
  508. 'org_id' => $data['org_id'],
  509. 'create_time' => getTime(),
  510. 'todo_mode' => 1,
  511. 'work_type_mode' => $info['work_type_mode'],
  512. 'create_yyyy' => date('Y'),
  513. 'create_yyyymm' => date('Ym'),
  514. 'create_yyyymmdd' => date('Ymd'),
  515. ];
  516. $taskData=[
  517. 'org_id'=>$data['org_id'],
  518. 'type'=>1,
  519. 'start_time'=>getTime(),
  520. 'create_time'=>getTime(),
  521. ];
  522. $pusharr =[];
  523. $sns = [];
  524. foreach ($to_user_id as $k => $v) {
  525. if(empty($v)){
  526. continue;
  527. }
  528. $todoData['to_user_id'] = $v;
  529. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  530. while (true){
  531. if(in_array($todoData['sn'],$sns)){
  532. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  533. }else{
  534. $sns[] = $todoData['sn'];
  535. break;
  536. }
  537. }
  538. $res = Db::name('todo')
  539. ->insertGetId($todoData);
  540. if (!$res){
  541. \exception('执行人:'.$v.'派单失败');
  542. }
  543. $taskData['user_id'] = $v;
  544. $taskData['bus_id'] = $res;
  545. $res = Db::name('task')
  546. ->insert($taskData);
  547. if (!$res){
  548. \exception('执行人:'.$v.'任务保存失败');
  549. }
  550. $pusharr[] = [
  551. 'user_id'=>$v,
  552. 'todo_id'=>$res
  553. ];
  554. }
  555. $res = Db::name('orders')->where('id',$info['order_id'])
  556. ->update(['order_mode'=>4,'send_time'=>getTime()]);
  557. if (!$res){
  558. \exception('订单更新失败');
  559. }
  560. if($info['work_type_mode']==1){//报修订单
  561. $rData = [];
  562. if(isset($data['type_id']) && !empty($data['type_id'])){
  563. $rData['type_id'] = $data['type_id'];
  564. }
  565. if(isset($data['address_id']) && !empty($data['address_id'])){
  566. $rData['address_id'] = $data['address_id'];
  567. }
  568. if(!empty($rData)){
  569. $rData['order_id'] = $info['order_id'];
  570. Db::name('order_repair')
  571. ->where('order_id',$info['order_id'])->delete();
  572. $res = Db::name('order_repair')
  573. ->insert($rData);
  574. if(!$res){
  575. \exception('保存维修扩展失败');
  576. }
  577. }
  578. }
  579. if($data['work_type_mode'] == 3){
  580. // $wlps = Db::connect('db_config_jili')->name('wlps')->where('order_id',$data['order_id'])->find();
  581. $wlps = Db::name('wlps')->where('order_id',$data['order_id'])->find();
  582. if($wlps){
  583. // Db::connect('db_config_jili')->name('wlps')->where('id',$wlps['id'])->update([
  584. // 'send_time' => date('Y-m-d H:i:s')
  585. // ]);
  586. Db::name('wlps')->where('id',$wlps['id'])->update([
  587. 'send_time' => date('Y-m-d H:i:s')
  588. ]);
  589. }
  590. }
  591. $this->commit();
  592. if($pusharr){
  593. foreach ($pusharr as $k=>$v){
  594. // 极光推送
  595. send_jpush([$v['user_id']],AppMsg::PUSH_WORKER_ORDER_SEND,'',['id'=>$v['todo_id']]);
  596. }
  597. }
  598. return true;
  599. }catch (Exception $e){
  600. $this->rollback();
  601. $this->error=$e->getMessage();
  602. return false;
  603. }
  604. }
  605. //api 工单列表
  606. public function lists($page,$size,$userId,$orgId,$type){
  607. $offset = ($page-1)*$size;
  608. if($type==1){//已完成
  609. $map[] = ['org_id','=',$orgId];
  610. $map[] = ['del','=',0];
  611. $map[] = ['to_user_id','=',$userId];
  612. $map[] = ['todo_mode','=',3];
  613. $list = $this->where($map)
  614. ->limit($offset,$size)
  615. ->order('id','desc')
  616. ->select();
  617. $list = $list?$list->toArray():[];
  618. }else if ($type==2){//已评价
  619. $list = Db::name('todo')
  620. ->alias('a')
  621. ->join('orders b','b.id=a.order_id','left')
  622. ->where('a.to_user_id',$userId)
  623. ->where('a.del',0)
  624. ->where('b.del',0)
  625. ->where('a.org_id',$orgId)
  626. ->where('b.order_mode',6)
  627. ->field('a.*')
  628. ->order('a.id','desc')
  629. ->limit($offset,$size)
  630. ->select();
  631. }else if ($type==0){//所有
  632. $list = Db::name('todo')
  633. ->alias('a')
  634. ->join('orders b','b.id=a.order_id','left')
  635. ->where('a.to_user_id',$userId)
  636. ->where('a.del',0)
  637. ->where('b.del',0)
  638. ->where('a.org_id',$orgId)
  639. ->where(function ($query){
  640. $query->where('a.todo_mode', 3)->whereor('b.order_mode', 6);
  641. })
  642. ->field('a.*')
  643. ->order('a.id','desc')
  644. ->limit($offset,$size)
  645. ->select();
  646. }
  647. $n = [];
  648. foreach ($list as $k=>$v){
  649. $a= $this->apiFormatTodo($v);
  650. $n[] = formatArray(
  651. [
  652. 'id',
  653. 'confirm_time',
  654. 'done_time',
  655. 'work_type_mode',
  656. 'sn'
  657. ]
  658. , $a);
  659. }
  660. return $n;
  661. }
  662. //api工单详情
  663. public function apiDetail($todoId){
  664. $info = Db::name('todo_view')->where('id',$todoId)
  665. ->find();
  666. if(empty($info)){
  667. HelpHander::error('工单信息不存在');
  668. }
  669. $order = Db::name('orders')
  670. ->where('id',$info['order_id'])
  671. ->find();
  672. $orderInfo = (new Orders())->apiFormatOrder($order,1,$todoId);
  673. if($order['work_type_mode'] == 3){
  674. // 地点路径
  675. $conveyends = Db::name('order_convey_end')
  676. ->alias('a')
  677. ->join('address b','b.id = a.addr')
  678. ->where('a.order_id',$order['id'])
  679. ->where('a.del',0)
  680. ->order('a.id asc')
  681. ->field('a.*,b.title')
  682. ->select();
  683. $orderInfo['ends'] = $conveyends?$conveyends:[];
  684. $payinfo = [
  685. 'is_pay' => 0,
  686. 'id' => 0,
  687. 'url' => '',
  688. 'money' => 0,
  689. 'remark' => '',
  690. 'type' => 1,
  691. 'pay_time' => '',
  692. ];
  693. // 是否需要支付
  694. $pay = Db::name('order_convey_pay')->where('order_id',$order['id'])->find();
  695. if($pay){
  696. $payinfo['is_pay'] = $pay['status'] == 0?0:1;
  697. $payinfo['url'] = url('h5/Index/pay',['id'=>$pay['id']],false,true);
  698. $payinfo['money'] = round($pay['money'],2);
  699. $payinfo['remark'] = $pay['remark'];
  700. $payinfo['pay_time'] = $pay['pay_time']?$pay['pay_time']:'';
  701. $payinfo['id'] = $pay['id'];
  702. }
  703. $orderInfo['pay'] = $payinfo;
  704. }
  705. return $orderInfo;
  706. }
  707. //处理驳回订单
  708. public function createNtbo($todoId,$toUserIdArray,$todoContent,$userId,$typeId,$addressId){
  709. $todo=$this
  710. ->where('id',$todoId)->find();
  711. if(!$todo || $todo['del'] == 1){
  712. $this->error = '工单不存在';
  713. return false;
  714. }
  715. if($todo['todo_mode'] != 4){
  716. $this->error = '无权限分配订单';
  717. return false;
  718. }
  719. if(!isset($toUserIdArray)||empty($toUserIdArray)){
  720. $this->error='请选择执行人';
  721. return false;
  722. }
  723. $send_user_num = (new Orders())->sendUserNum($todo['work_type_mode'],$todo['org_id']);
  724. $users = explode(',', $toUserIdArray);
  725. if($send_user_num==1 && count($users) >1){
  726. $this->error = '执行人只能选择单人';
  727. return false;
  728. }
  729. $to_user_id = array_unique($users);
  730. $this->startTrans();
  731. try{
  732. $res = $this
  733. ->where('id',$todoId)->update(['todo_mode'=>7]);
  734. if(!$res){
  735. \exception('订单状态更改失败');
  736. }
  737. if($todo['work_type_mode']==1){//报修订单
  738. $rData = [];
  739. if(!empty($typeId) && $typeId>0 ){
  740. $rData['type_id'] =$typeId;
  741. }
  742. if(!empty($addressId) && $addressId>0){
  743. $rData['address_id'] = $addressId;
  744. }
  745. if(!empty($rData)){
  746. $rData['order_id'] = $todo['order_id'];
  747. Db::name('order_repair')
  748. ->where('order_id',$todo['order_id'])->delete();
  749. $res = Db::name('order_repair')
  750. ->insert($rData);
  751. if(!$res){
  752. \exception('保存维修扩展失败');
  753. }
  754. }
  755. }
  756. $todoData = [
  757. 'order_id' => $todo['order_id'],
  758. 'todo_content' => $todoContent,
  759. 'create_user_id' => $userId,
  760. 'org_id' => $todo['org_id'],
  761. 'create_time' => getTime(),
  762. 'todo_mode' => 1,
  763. 'work_type_mode' => $todo['work_type_mode'],
  764. 'create_yyyy' => date('Y'),
  765. 'create_yyyymm' => date('Ym'),
  766. 'create_yyyymmdd' => date('Ymd'),
  767. ];
  768. $taskData=[
  769. 'org_id'=>$todo['org_id'],
  770. 'type'=>1,
  771. 'start_time'=>getTime(),
  772. 'create_time'=>getTime(),
  773. ];
  774. $sns = [];
  775. foreach ($to_user_id as $k => $v) {
  776. if(empty($v)){
  777. continue;
  778. }
  779. $todoData['to_user_id'] = $v;
  780. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  781. while (true){
  782. if(in_array($todoData['sn'],$sns)){
  783. $todoData['sn'] = get_unique_sn(get_config('sn_prefix'));
  784. }else{
  785. $sns[] = $todoData['sn'];
  786. break;
  787. }
  788. }
  789. $res = Db::name('todo')
  790. ->insertGetId($todoData);
  791. if (!$res){
  792. \exception('执行人:'.$v.'派单失败');
  793. }
  794. $taskData['user_id'] = $v;
  795. $taskData['bus_id'] = $res;
  796. $res = Db::name('task')
  797. ->insert($taskData);
  798. if (!$res){
  799. \exception('执行人:'.$v.'任务保存失败');
  800. }
  801. // 极光推送
  802. send_jpush([$v],AppMsg::PUSH_WORKER_ORDER_SEND,'',['id'=>$res]);
  803. }
  804. $this->commit();
  805. return true;
  806. }catch (Exception $e){
  807. $this->rollback();
  808. return false;
  809. }
  810. }
  811. //修改工单状态 4 驳回 5客观原因
  812. public function updateState($todoId,$todoMode,$nodoReason,$userId,$rejectVoice){
  813. $todo = $this
  814. ->where('id',$todoId)
  815. ->where('del',0)
  816. ->find();
  817. if(!$todo){
  818. $this->error = '工单不存在';
  819. return false;
  820. }
  821. if($todoMode == 4){ // 驳回
  822. $bxConfigOff = model('Config')->getConfig('bh_orders_off',$todo['org_id']);
  823. if($bxConfigOff !=1){
  824. $this->error = '驳回开关已关闭,不能驳回';
  825. return false;
  826. }
  827. if($todo['todo_mode']!==1){
  828. $this->error = '当前状态不能驳回';
  829. return false;
  830. }
  831. $this->startTrans();
  832. try{
  833. $ret = $this
  834. ->where('id',$todoId)
  835. ->update(['todo_mode'=>$todoMode,
  836. 'nodo_reason'=>$nodoReason,
  837. 'reject_voice'=>$rejectVoice,
  838. 'reject_time' => date('Y-m-d H:i:s')]);
  839. if(!$ret){
  840. \exception('操作失败');
  841. }
  842. Db::name('task')
  843. ->where('org_id',$todo['org_id'])
  844. ->where('user_id',$userId)
  845. ->where('type',1)
  846. ->where('bus_id',$todoId)
  847. ->delete();
  848. $this->commit();
  849. }catch (Exception $e){
  850. $this->rollback();
  851. $this->error = $e->getMessage();
  852. return false;
  853. }
  854. }else if($todoMode == 2){
  855. if($todo['todo_mode']!==1){
  856. $this->error = '当前状态不能领取';
  857. return false;
  858. }
  859. $XY_TIME = time() - strtotime($todo['create_time']);
  860. $ret = $this->where('id',$todoId)->update([
  861. 'todo_mode'=>$todoMode,
  862. 'confirm_time' => date('Y-m-d H:i:s'),
  863. 'xy_time' => $XY_TIME
  864. ]);
  865. // $todoIds = Db::name('todo')
  866. // ->where('id','<>',$todoId)
  867. // ->where('order_id','=',$todo['order_id'])
  868. // ->column('id');
  869. // if(!empty($todoIds)){
  870. // $r = Db::name('todo')
  871. // ->where('id','in',$todoIds)
  872. // ->delete();
  873. // Db::name('task')
  874. // ->where('bus_id', 'in', $todoIds)
  875. // ->where('type', 1)
  876. // ->delete();
  877. // if(!$r){
  878. // $this->error = '操作失败';
  879. // return false;
  880. // }
  881. // }
  882. if(!$ret){
  883. $this->error = '操作失败';
  884. return false;
  885. }
  886. if($todo['work_type_mode'] == 3){
  887. // $wlps = Db::connect('db_config_jili')->name('wlps')->where('order_id',$todo['order_id'])->find();
  888. $wlps = Db::name('wlps')->where('order_id',$todo['order_id'])->find();
  889. if($wlps){
  890. $user = Db::name('user')->where('id',$todo['to_user_id'])->find();
  891. // Db::connect('db_config_jili')->name('wlps')
  892. // ->where('id',$wlps['id'])
  893. // ->update([
  894. // 'paisr' => $user?$user['user_id']:'',
  895. // 'paisr_name' => $user?$user['real_name']:'',
  896. // 'paisr_phone' => $user?$user['mobile']:'',
  897. // 'pais_time' => date('Y-m-d H:i:s')
  898. // ]);
  899. Db::name('wlps')
  900. ->where('id',$wlps['id'])
  901. ->update([
  902. 'paisr' => $user?$user['id']:'',
  903. 'paisr_name' => $user?$user['real_name']:'',
  904. 'paisr_phone' => $user?$user['mobile']:'',
  905. 'pais_time' => date('Y-m-d H:i:s')
  906. ]);
  907. }
  908. }
  909. }else if($todoMode == 6){ // 取消驳回工单
  910. $this->startTrans();
  911. try{
  912. $ret = $this
  913. ->where('id',$todoId)
  914. ->update(['todo_mode'=>$todoMode,
  915. 'cancel_reason' => $nodoReason]);
  916. if(!$ret){
  917. \exception('订单错误失败');
  918. }
  919. $ret = $this->checkToDo($todo['order_id'],$todoId,$todoMode);
  920. if(!$ret){
  921. \exception('订单修改失败');
  922. }
  923. Db::name('task')
  924. ->where('org_id',$todo['org_id'])
  925. ->where('user_id',$userId)
  926. ->where('type',1)
  927. ->where('bus_id',$todoId)
  928. ->delete();
  929. $this->commit();
  930. }catch (Exception $e){
  931. $this->rollback();
  932. $this->error = $e->getMessage();
  933. return false;
  934. }
  935. }
  936. return true;
  937. }
  938. // 工人完成提交任务/无法完成
  939. public function finishTodo($todoId,$todoMode,$content,$userId,$images,$consItems,$sign){
  940. $todo = $this
  941. ->where('id',$todoId)
  942. ->where('del',0)->find();
  943. if(!$todo){
  944. $this->error = '工单不存在';
  945. return false;
  946. }
  947. if($todo['to_user_id'] != $userId || $todo['todo_mode'] != 2){
  948. $this->error = '无权限操作';
  949. return false;
  950. }
  951. if($todo['work_type_mode']== 1 && $todo['todo_mode'] == 2 && $todo['pause'] == 1){
  952. $this->error = '工单正在挂起,无法完成';
  953. return false;
  954. }
  955. if($todo['work_type_mode']==1 && $todoMode==3){
  956. $off =(new Config())->getConfig('org_sign',$todo['org_id']);
  957. if($off==1 && empty($sign)){
  958. $this->error = '请上传签名';
  959. return false;
  960. }
  961. }
  962. $this->startTrans();
  963. try{
  964. if($todo['pause'] == 2){
  965. $ct = strtotime($todo['confirm_time']);
  966. $pst = strtotime($todo['pause_time']);
  967. $pet = strtotime($todo['pause_end']);
  968. $WC_TIME = ($pst - $ct) + time()-$pet;
  969. }else{
  970. $WC_TIME = time() - strtotime($todo['confirm_time']);
  971. }
  972. $curTime = date('Y-m-d H:i:s');
  973. $ret = $this
  974. ->where('id',$todoId)->update([
  975. 'nodo_reason' => $content,
  976. 'images' => $images,
  977. 'todo_mode' => $todoMode,
  978. 'done_time' => $curTime,
  979. 'wc_time' => $WC_TIME,
  980. 'sign' => $sign
  981. ]);
  982. if(!$ret){
  983. \exception('工单修改失败');
  984. }
  985. if($todoMode == 3 && $consItems){ // 工单完成且有耗材
  986. $consItems = json_decode($consItems,true);
  987. $mate = [
  988. 'todo_id'=>$todoId,
  989. 'order_id'=>$todo['order_id'],
  990. 'org_id'=>$todo['org_id'],
  991. 'user_id'=>$userId,
  992. 'create_time'=>getTime()
  993. ];
  994. $todo_mate_id = Db::name('todo_mate')
  995. ->insertGetId($mate);
  996. if(!$todo_mate_id){
  997. \exception('订单使用物品记录失败');
  998. }
  999. $items = [];
  1000. foreach ($consItems as $k=>$v){
  1001. $itemInfo = Db::name('mate_goods')
  1002. ->where('id',$v['itemsId'])
  1003. ->find();
  1004. if($itemInfo['nums'] < $v['total']){
  1005. \exception($itemInfo['title'].' 库存不足');
  1006. }
  1007. $items[] = [
  1008. 'todo_mate_id'=>$todo_mate_id,
  1009. 'items_id'=>$v['itemsId'],
  1010. 'total'=>$v['total'],
  1011. 'create_time'=>getTime(),
  1012. 'user_id'=>$userId,
  1013. 'money'=>$itemInfo['price'],
  1014. 'total_money'=>$itemInfo['price']*$v['total'],
  1015. ];
  1016. $res = Db::name('mate_goods')
  1017. ->where('id',$v['itemsId'])
  1018. ->setDec('nums',$v['total']);
  1019. if(!$res){
  1020. \exception($itemInfo['title'].' 数量修改失败');
  1021. }
  1022. }
  1023. $res = Db::name('todo_mate_item')
  1024. ->insertAll($items);
  1025. if(!$res){
  1026. \exception('物品使用记录失败');
  1027. }
  1028. }
  1029. $ret = $this->checkToDo($todo['order_id'],$todoId,$todoMode);
  1030. Db::name('task')
  1031. ->where('bus_id', '=', $todoId)
  1032. ->where('type', 1)
  1033. ->delete();
  1034. if(!$ret){
  1035. \exception('订单修改失败');
  1036. }
  1037. $this->commit();
  1038. }catch (Exception $e){
  1039. $this->error = $e->getMessage();
  1040. $this->rollback();
  1041. return false;
  1042. }
  1043. return true;
  1044. }
  1045. //获取物品列表
  1046. public function getMateGoods($orgId,$userId,$title,$page,$size){
  1047. $map[] = ['org_id','=',$orgId];
  1048. $map[] = ['enable','=',1];
  1049. $map[] = ['del','=',0];
  1050. if($title){
  1051. $map[] = ['title','like','%'.$title.'%'];
  1052. }
  1053. $offset = ($page-1)*$size;
  1054. $list = (new MateGoods())->getList($offset,$size,$map,'id desc');
  1055. $a = [];
  1056. foreach ($list as $k=>$v){
  1057. $user_cons = Db::name('user_cons')
  1058. ->where('user_id',$userId)
  1059. ->where('goods_id',$v['id'])
  1060. ->find();
  1061. $v['is_fav'] = $user_cons?1:0;
  1062. $a[] = formatArray([
  1063. 'id','price','nums','title','spec','is_fav'
  1064. ],$v);
  1065. }
  1066. return $a;
  1067. }
  1068. //收藏/取消收藏
  1069. public function favGoods($userId,$type,$goodsId){
  1070. if($type==0){
  1071. $res = Db::name('user_cons')
  1072. ->where('goods_id',$goodsId)
  1073. ->where('user_id',$userId)
  1074. ->delete();
  1075. }else{
  1076. if(Db::name('user_cons')
  1077. ->where('goods_id',$goodsId)
  1078. ->where('user_id',$userId)->find()){
  1079. HelpHander::error('该物品已收藏');
  1080. }
  1081. $res = Db::name('user_cons')
  1082. ->insertGetId([
  1083. 'goods_id'=>$goodsId,
  1084. 'user_id'=>$userId,
  1085. ]);
  1086. }
  1087. return $res;
  1088. }
  1089. //收藏物品列表
  1090. public function favList($userId,$title){
  1091. if($title){
  1092. $map[] = ['b.title','like','%'.$title.'%'];
  1093. }
  1094. $map[] = ['a.user_id','=',$userId];
  1095. $map[] = ['b.enable','=',1];
  1096. $map[] = ['b.del','=',0];
  1097. $list = Db::name('user_cons')
  1098. ->alias('a')
  1099. ->join('mate_goods b','a.goods_id = b.id')
  1100. ->where($map)
  1101. ->order('a.id desc')
  1102. ->field('b.*')
  1103. ->select();
  1104. $a = [];
  1105. foreach ($list as $k=>$v){
  1106. $a[] = formatArray([
  1107. 'id','price','nums','title','spec',
  1108. ],$v);
  1109. }
  1110. return $a;
  1111. }
  1112. }