ThirdOrderLogic.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. <?php
  2. namespace app\common\logic;
  3. use app\api\logic\LoginLogic;
  4. use app\common\{enum\GoodsEnum,
  5. enum\PayEnum,
  6. enum\WorkEnum,
  7. model\goods\Goods,
  8. model\orders\RechargeOrder,
  9. model\recharge\OrderGoods,
  10. model\setting\PostageRegion,
  11. model\third\ThirdGoods,
  12. model\third\ThirdOrders,
  13. model\user\User,
  14. model\works\ServiceWork,
  15. model\works\ServiceWorkAppointmentLog,
  16. model\works\ServiceWorkLog};
  17. use think\facade\Db;
  18. use app\common\model\service_area\ServiceArea;
  19. use think\facade\Log;
  20. /**
  21. * 第三方平台下单逻辑层
  22. * Class UserLogic
  23. * @package app\shopapi\logic
  24. */
  25. class ThirdOrderLogic extends BaseLogic
  26. {
  27. protected const user_token = [
  28. "accessToken"=>"V2-29d801e316e9ec4eb88b3b9abd8dbda490367af539d97d754420056dc5c1329a2c1aff7d4d54729ff622d96ff7c9910aa930f7b7ad27910d199c15029ffc71aa4a84142d75b60f4a34b71a8390a89d8c01a4dd385232e4e9c9204fb5934eda89",
  29. "expireIn"=> 2592000,
  30. "opBizCode"=> "AG5MALO18KG6I5DL8LVONRSRF5G",
  31. "opBizName"=> "武汉开源节流科技有限公司",
  32. "refreshToken"=> "ab8d15b4028b7bd6aca383d230b87450436d301a2996b6bb3151d668dd2d015d68d8393e66fb2a59aa10146c70dd30728b473358ec0d156dc0bc5cc5e574a109a5680ab49c393fa9d2693ef5519ff41a16115b81259b58c71a54d79e23f26381",
  33. "scope"=> "dingdan,generalreserve,merchantreceipt,shangpin"
  34. ];
  35. protected const shop_token1 = [
  36. "accessToken"=> "V2-9667b1ce4ffaabe453d4ce847888c788c9c61762df9230ab342caf33e2b4a735ade021c559312195b7f01f30f3bdd44cf6f8528b1fd1ad1541ceabeb7da61156c852e314aae26eef9d52fb41fda585c566c18e05dc3cbb61733b2f71c05a78f6",
  37. "expireIn"=> 2592000,
  38. "opBizCode"=> "AH14KGRJ76O8PFH4GCO67F0CUKC",
  39. "opBizName"=> "众盾闪修 家电清洗 武汉",
  40. "refreshToken"=> "fd3da11174eed4c3d6b4d117f87ab7b62a72603627d2d597bed82dddb103694375ed9cab1944bc7437a204b171303cb3c0976fbddc88708e75f2169c532a28614ff36c68486a75cb9dbf0391e39d6dfa8bec0bf18b54b5d2119d895788a2281c",
  41. "scope"=> "merchantdata,poiqrcode,tuangou,ugc,yuding"
  42. ];
  43. protected const shop_token2 = [
  44. "accessToken"=> "V2-26f91ef8b515c59b97b9b4404e77dc2b2fc14b9715e3be7edb9f3f86178e193e21513ea76f021c503890172cad1863ea544d6b4c7b8b3790374ba912c15ad9e71e32ba0b195d38131da3584a59603ea55e81d1b3203a57ae280c36cbb67f5ffc",
  45. "expireIn"=> 2592000,
  46. "opBizCode"=> "AE7MKOJAV67338LIC3UD0K5TGIO",
  47. "opBizName"=> "众盾闪修 家电维修 武汉",
  48. "refreshToken"=> "bd57846c8817125f8ad7f4eb4ccad4af80c808f30c8b22e38476fc78c008b568376db34916f190e086272f6da315ac2ce4daefac6e61e4ce8889500f293e95537f6939f810f0466c8181086b052907c68b01a6d59ac5fe78abbae0ecd54578f5",
  49. "scope"=> "merchantdata,poiqrcode,tuangou,ugc,yuding"
  50. ];
  51. protected const developerId = 114657;
  52. protected const assessKey = '8471lgvnv0qcjpx6';
  53. /**
  54. * 处理订单
  55. * @param array $order
  56. * @return bool
  57. * @throws \think\db\exception\DataNotFoundException
  58. * @throws \think\db\exception\DbException
  59. * @throws \think\db\exception\ModelNotFoundException
  60. */
  61. public static function orderhandle(array $order)
  62. {
  63. $message = json_decode($order['message'], true);
  64. //查询用户是否存在
  65. $userName = $message['userName'];
  66. $mobile = $message['mobile'];
  67. $userAddress = json_decode($message['userAddress']);
  68. $user = User::where(['mobile' =>$mobile])->findOrEmpty();
  69. $product_message = json_decode($message['products'],true);
  70. if($user->isEmpty()){
  71. $user = LoginLogic::register([
  72. 'password'=>'123456',
  73. 'nickname'=>$userName,
  74. 'account'=>$mobile,
  75. 'mobile'=>$mobile,
  76. 'channel'=>1,
  77. 'user_type'=>0
  78. ]);
  79. }
  80. //查询美团商品和平台商品的对应关系
  81. $productId = $message['productId'];
  82. $product = ThirdGoods::where(['third_type'=>1,'product_id'=>$productId])->findOrEmpty();
  83. //生成第三方订单信息
  84. $orderData = [
  85. 'orderId'=>$message['orderId'],
  86. 'uni_order_id'=>$product_message[0]['uni_order_id'],
  87. 'productId'=>$message['productId'],
  88. 'productName'=>$message['productName'],
  89. 'request_msg'=>json_encode($order,JSON_UNESCAPED_UNICODE),
  90. 'bookStatus'=>1,
  91. 'third_type'=>1,//美团
  92. ];
  93. //判断美团的预约订单是否生成
  94. if(!$product->isEmpty()){
  95. //查询美团预约订单是否生成
  96. $thirdOrder = ThirdOrders::where(['uni_order_id'=>$product_message[0]['uni_order_id']])->findOrEmpty();
  97. if(!$thirdOrder->isEmpty() and $thirdOrder['work_id'] != 0){
  98. //生成第三方订单信息
  99. $orderData['sync_status'] = 1;
  100. $orderData['work_id'] = $thirdOrder['work_id'];
  101. }
  102. }
  103. $thirdOrders = ThirdOrders::where('orderId',$message['orderId'])->findOrEmpty();
  104. //生成未同步预约订单信息
  105. if($thirdOrders->isEmpty()){
  106. $thirdOrders = ThirdOrders::create($orderData);
  107. }
  108. if(!$thirdOrders->isEmpty()){
  109. $orderData['work_id'] = $thirdOrders->work_id;
  110. }
  111. if(empty($orderData['work_id']) and !$product->isEmpty() and !empty($product['goods_id'])){
  112. $goods = Goods::findOrEmpty($product['goods_id']);
  113. $pattern = '/(?:省|市)([\w\s]+市)/u';
  114. Db::startTrans();
  115. try {
  116. if (preg_match($pattern, $userAddress->receiver_address, $matches)) {
  117. $city = $matches[1];
  118. }
  119. $area_city = PostageRegion::where(['level'=>2,'name'=>$city])->value('id');
  120. //生成服务工单
  121. $work_data = [
  122. 'work_sn' => generate_sn(ServiceWork::class, 'work_sn'),
  123. 'real_name' => $userName,
  124. 'mobile' => $mobile,
  125. 'address' => $userAddress->receiver_address,
  126. 'province' => 0,
  127. 'city' => $area_city??0,
  128. 'area_name' => $userAddress->receiver_address,
  129. 'title' => $goods->goods_name,
  130. 'category_type' => $goods['category_type'],
  131. 'goods_category_ids' => $goods['goods_category_ids'],
  132. 'goods_category_id' => $goods['goods_category_id'],
  133. 'base_service_fee' => $goods['base_service_fee'],
  134. 'service_fee' => $product['product_price'],
  135. 'work_pay_status'=>WorkEnum::IS_PAY_STATUS,
  136. 'appointment_time' => strtotime($message['begintime']),
  137. 'user_id'=>$user['id'],
  138. 'lon'=>!empty($userAddress->longitude)?$userAddress->longitude:0,
  139. 'lat'=>!empty($userAddress->latitude)?$userAddress->latitude:0,
  140. 'property_activity_id'=>0,
  141. 'user_equity_id'=>0,
  142. 'third_type'=>1,
  143. 'work_total'=>$product['product_price'],
  144. 'work_amount'=>$product['product_price']
  145. ];
  146. $service_area_id = ServiceArea::serviceAreaId(['lon' => $work_data['lon'], 'lat' => $work_data['lat']]);
  147. $work_data['service_area_id'] = $service_area_id;
  148. $service_work = ServiceWork::create($work_data);
  149. //生成服务订单
  150. $data = [
  151. 'work_id'=> $service_work['id'],
  152. 'sn' => generate_sn(RechargeOrder::class, 'sn'),
  153. 'order_type'=>0,//服务订单
  154. 'order_terminal' => 1,
  155. 'payment_type'=>$goods['goods_payment_type']==GoodsEnum::ISGOODS_PAYMENT_TYPE?0:1,
  156. 'user_id' => $user['id'],
  157. 'pay_status' => PayEnum::ISPAID,
  158. 'coupon_id'=>0,
  159. 'coupon_price'=>0,
  160. 'pay_way' => 4,
  161. 'order_total' => $product['product_price'],
  162. 'order_amount' => $product['product_price'],
  163. 'paid_amount'=> $product['product_price'],
  164. ];
  165. $order = RechargeOrder::create($data);
  166. //生成订单服务详情
  167. OrderGoods::create([
  168. 'sn' => $order['sn'],
  169. 'goods_id' => $goods['id'],
  170. 'category_type' => $goods['category_type'],
  171. 'goods_category_ids' => $goods['goods_category_ids'],
  172. 'goods_category_id' => $goods['goods_category_id'],
  173. 'goods_name' => $goods['goods_name'],
  174. 'goods_image' => $goods['goods_image'],
  175. 'goods_video' => $goods['goods_video'],
  176. 'goods_number' => $goods['goods_number'],
  177. 'good_unit' => $goods['good_unit'],
  178. 'goods_size' => $goods['goods_size'],
  179. 'goods_type' => $goods['goods_type'],
  180. 'goods_brand' => $goods['goods_brand'],
  181. 'install_guide' => $goods['install_guide'],
  182. 'goods_payment_type'=>$goods['goods_payment_type'],
  183. 'base_service_fee' => $goods['base_service_fee'],
  184. 'service_total' => $goods['service_total'],
  185. 'service_fee' => $product['product_price'],
  186. 'service_image' => $goods['service_image'],
  187. 'warranty_period'=>$goods['warranty_period'],
  188. 'fee_schedule' => $goods['fee_schedule'],
  189. 'goods_status' => $goods['goods_status'],
  190. ]);
  191. //判断是否是一口价预支付订单,支付成功后生成尾款订单
  192. if(!$goods->isEmpty() and $goods->goods_payment_type == 3 and bcsub($goods->base_service_fee,$goods->service_fee,2)>=0){
  193. //新增待支付尾款
  194. $order_weikuan_data = [
  195. 'order_type'=>$order['order_type'],
  196. 'sn'=>generate_sn(\app\common\model\orders\RechargeOrder::class, 'sn'),
  197. 'work_id'=>$order['work_id'],
  198. 'user_id'=>$order['user_id'],
  199. 'payment_type'=>2,
  200. 'order_total'=>bcsub($goods->base_service_fee,$product['product_price'],2),
  201. 'order_amount'=>bcsub($goods->base_service_fee,$product['product_price'],2),
  202. 'order_terminal'=>$order['order_terminal']
  203. ];
  204. \app\common\model\recharge\RechargeOrder::create($order_weikuan_data);
  205. }
  206. $thirdOrders->work_id = $service_work->id;
  207. $thirdOrders->save();
  208. self::bookresultcallback($order['opBizCode'],$message['orderId'],2);
  209. Db::commit();
  210. } catch (\Exception $e) {
  211. Db::rollback();
  212. self::setError($e->getMessage());
  213. return false;
  214. }
  215. }
  216. if(!empty($orderData['work_id']) and !$product->isEmpty() and !empty($product['goods_id'])) {
  217. //更改预约时间
  218. $serviceWorkInfo = ServiceWork::find($orderData['work_id']);
  219. if(!empty($serviceWorkInfo)){
  220. $appointment_time = $message['begintime'];
  221. ServiceWorkAppointmentLog::create([
  222. 'work_id'=>$serviceWorkInfo->id,
  223. 'last_appointment_time'=>strtotime($serviceWorkInfo->appointment_time),
  224. 'this_appointment_time'=>strtotime($appointment_time),
  225. ]);
  226. //修改预计完成时间
  227. if ($serviceWorkInfo->estimated_finish_time) {
  228. $serviceWorkInfo->estimated_finish_time = strtotime($appointment_time) + (strtotime($serviceWorkInfo->estimated_finish_time) - strtotime($serviceWorkInfo->appointment_time));
  229. }
  230. $serviceWorkInfo->appointment_time = strtotime($appointment_time);
  231. $serviceWorkInfo->save();
  232. }
  233. }
  234. return true;
  235. }
  236. //手动添加订单
  237. public static function submitOrders(array $message)
  238. {
  239. //查询用户是否存在
  240. $userName = $message['userName'];
  241. $mobile = $message['mobile'];
  242. $user = User::where(['mobile' =>$mobile])->findOrEmpty();
  243. if($user->isEmpty()){
  244. $user = LoginLogic::register([
  245. 'password'=>'123456',
  246. 'nickname'=>$userName,
  247. 'account'=>$mobile,
  248. 'mobile'=>$mobile,
  249. 'channel'=>1,
  250. 'user_type'=>0,
  251. ]);
  252. }
  253. $goods = Goods::findOrEmpty($message['goods_id']);
  254. $pattern = '/(?:省|市)([\w\s]+市)/u';
  255. Db::startTrans();
  256. try {
  257. // TODO tmp防抖1m
  258. $isExist = ServiceWork::where(['user_id'=>$user['id'],'goods_category_id'=>$goods['goods_category_id']])->where('create_time','>',(time() - 60))->findOrEmpty();
  259. if(!$isExist->isEmpty()){
  260. throw new \Exception('请勿重复下单!');
  261. }
  262. if (preg_match($pattern, $message['userAddress'], $matches)) {
  263. $city = $matches[1];
  264. }
  265. $area_city = PostageRegion::where(['level'=>2,'name'=>$city])->value('id');
  266. //生成服务工单
  267. $work_data = [
  268. 'work_sn' => generate_sn(ServiceWork::class, 'work_sn'),
  269. 'real_name' => $userName,
  270. 'mobile' => $mobile,
  271. 'address' => $message['userAddress'],
  272. 'province' => 0,
  273. 'city' => $area_city??0,
  274. 'area_name' => $area_city??'',
  275. 'title' => $goods->goods_name,
  276. 'category_type' => $goods['category_type'],
  277. 'goods_category_ids' => $goods['goods_category_ids'],
  278. 'goods_category_id' => $goods['goods_category_id'],
  279. 'base_service_fee' => $goods['base_service_fee'],
  280. 'service_fee' => $message['amount'],
  281. 'work_pay_status'=>WorkEnum::IS_PAY_STATUS,
  282. 'appointment_time' => strtotime($message['appointment_time']),
  283. 'user_id'=>$user['id'],
  284. 'lon'=>$message['lon'],
  285. 'lat'=>$message['lat'],
  286. 'property_activity_id'=>0,
  287. 'user_equity_id'=>0,
  288. 'external_platform_id'=>$message['external_platform_id']??0,
  289. 'work_total'=>$message['amount'],
  290. 'work_amount'=>$message['amount']
  291. ];
  292. $service_area_id = ServiceArea::serviceAreaId(['lon' => $work_data['lon'], 'lat' => $work_data['lat']]);
  293. $work_data['service_area_id'] = $service_area_id;
  294. $service_work = ServiceWork::create($work_data);
  295. //生成服务订单
  296. $data = [
  297. 'work_id'=> $service_work['id'],
  298. 'sn' => generate_sn(RechargeOrder::class, 'sn'),
  299. 'order_type'=>0,//服务订单
  300. 'order_terminal' => 1,
  301. 'payment_type'=>$goods['goods_payment_type']==GoodsEnum::ISGOODS_PAYMENT_TYPE?0:1,
  302. 'user_id' => $user['id'],
  303. 'pay_status' => PayEnum::ISPAID,
  304. 'coupon_id'=>0,
  305. 'coupon_price'=>0,
  306. 'pay_way' => 4,
  307. 'order_total' => $message['amount'],
  308. 'order_amount' => $message['amount'],
  309. 'paid_amount'=>$message['amount']
  310. ];
  311. $order = RechargeOrder::create($data);
  312. //生成订单服务详情
  313. OrderGoods::create([
  314. 'sn' => $order['sn'],
  315. 'goods_id' => $goods['id'],
  316. 'category_type' => $goods['category_type'],
  317. 'goods_category_ids' => $goods['goods_category_ids'],
  318. 'goods_category_id' => $goods['goods_category_id'],
  319. 'goods_name' => $goods['goods_name'],
  320. 'goods_image' => $goods['goods_image'],
  321. 'goods_video' => $goods['goods_video'],
  322. 'goods_number' => $goods['goods_number'],
  323. 'good_unit' => $goods['good_unit'],
  324. 'goods_size' => $goods['goods_size'],
  325. 'goods_type' => $goods['goods_type'],
  326. 'goods_brand' => $goods['goods_brand'],
  327. 'install_guide' => $goods['install_guide'],
  328. 'goods_payment_type'=>$goods['goods_payment_type'],
  329. 'base_service_fee' => $goods['base_service_fee'],
  330. 'service_total' => $goods['service_total'],
  331. 'service_fee' => $message['amount'],
  332. 'service_image' => $goods['service_image'],
  333. 'warranty_period'=>$goods['warranty_period'],
  334. 'fee_schedule' => $goods['fee_schedule'],
  335. 'goods_status' => $goods['goods_status'],
  336. ]);
  337. //判断是否是一口价预支付订单,支付成功后生成尾款订单
  338. if(!$goods->isEmpty() and $goods->goods_payment_type == 3 and bcsub($goods->base_service_fee,$goods->service_fee,2)>=0){
  339. //新增待支付尾款
  340. $order_weikuan_data = [
  341. 'order_type'=>$order['order_type'],
  342. 'sn'=>generate_sn(\app\common\model\orders\RechargeOrder::class, 'sn'),
  343. 'work_id'=>$order['work_id'],
  344. 'user_id'=>$order['user_id'],
  345. 'payment_type'=>2,
  346. 'order_total'=>bcsub($goods->base_service_fee,$message['amount'],2),
  347. 'order_amount'=>bcsub($goods->base_service_fee,$message['amount'],2),
  348. 'order_terminal'=>$order['order_terminal']
  349. ];
  350. \app\common\model\recharge\RechargeOrder::create($order_weikuan_data);
  351. }
  352. Db::commit();
  353. // 用户下单后,给订单运营专员(配置固定ID)发送公众号提醒(订单信息)
  354. $order = \app\common\model\recharge\RechargeOrder::where('sn', $order['sn'])
  355. ->where('payment_type','IN',[0,1])
  356. ->where('pay_status','=',1)
  357. ->findOrEmpty();
  358. if(!$order->isEmpty()){
  359. $workDetail = ServiceWork::findOrEmpty($order->work_id);
  360. if(!$workDetail->isEmpty()){
  361. event('Notice', [
  362. 'scene_id' => 100,
  363. 'params' => [
  364. 'user_id' => 0,
  365. 'order_id' => $workDetail['id'],
  366. 'thing3' => $workDetail['title'],
  367. 'time6' => $workDetail['appointment_time'],
  368. 'phone_number8' => asteriskString($workDetail['mobile']),
  369. 'thing5' => (iconv_strlen($workDetail['address'])>15)?(mb_substr($workDetail['address'],0,15,'UTF-8').'...'):$workDetail['address'],
  370. ]
  371. ]);
  372. }
  373. }
  374. return $service_work['id'];
  375. } catch (\Exception $e) {
  376. Db::rollback();
  377. self::setError($e->getMessage());
  378. return false;
  379. }
  380. }
  381. public static function get_sign($sign_key, $data)
  382. {
  383. if ($data == null) {
  384. return null;
  385. }
  386. ksort($data);
  387. $result_str = "";
  388. foreach ($data as $key => $val) {
  389. if ($key != "sign" && $val != null && $val != "") {
  390. $result_str = $result_str . $key . $val;
  391. }
  392. }
  393. $result_str = $sign_key . $result_str;
  394. $ret = bin2hex(sha1($result_str, true));
  395. return $ret;
  396. }
  397. /**
  398. * 商家接单接口
  399. * @param $orderId
  400. * @param $bookStatus
  401. * @return string
  402. */
  403. public static function bookresultcallback($opBizCode,$orderId,$bookStatus=2)
  404. {
  405. return '';
  406. http_request('https://developer.kyjlkj.com/platf/kaidianbao/reservationSuccessful',http_build_query([$opBizCode,$orderId,$bookStatus]));
  407. //预订结果,2-预订成功,3-预订失败
  408. $url = 'https://api-open-cater.meituan.com/ddzh/yuding/bookresultcallback';
  409. $accessToken = $opBizCode == 'AE7MKOJAV67338LIC3UD0K5TGIO' ? self::shop_token2['accessToken'] : self::shop_token1['accessToken'];
  410. $data = [
  411. 'timestamp'=>time(),
  412. 'appAuthToken'=>$accessToken,
  413. 'charset'=>'utf-8',
  414. 'version'=>'2',
  415. 'developerId'=>self::developerId,
  416. 'businessId'=>58,
  417. 'biz'=>json_encode([
  418. 'orderId'=>$orderId,
  419. 'bookStatus'=>$bookStatus,
  420. "code"=>200,
  421. "type"=>2
  422. ],JSON_UNESCAPED_UNICODE)
  423. ];
  424. $sign_data = self::get_sign(self::assessKey, $data);
  425. $data['sign'] = $sign_data;
  426. return http_request($url,http_build_query($data));
  427. }
  428. /**
  429. * 取消预订
  430. * @param array
  431. * $order
  432. * @return bool
  433. */
  434. public static function cancelOrderHandle(array $order)
  435. {
  436. $message = json_decode($order['message'], true);
  437. Db::startTrans();
  438. try {
  439. $thirdOrders = ThirdOrders::where('orderId',$message['orderId'])->findOrEmpty();
  440. if(!$thirdOrders->isEmpty()){
  441. $thirdOrders->bookStatus = 3;
  442. $thirdOrders->save();
  443. $serviceWorkInfo = ServiceWork::find($thirdOrders->work_id);
  444. if(!empty($serviceWorkInfo)){
  445. $appointment_time = '2099-12-31 23:59:59';
  446. ServiceWorkAppointmentLog::create([
  447. 'work_id'=>$serviceWorkInfo->id,
  448. 'last_appointment_time'=>strtotime($serviceWorkInfo->appointment_time),
  449. 'this_appointment_time'=>strtotime($appointment_time),
  450. ]);
  451. //修改预计完成时间
  452. if ($serviceWorkInfo->estimated_finish_time) {
  453. $serviceWorkInfo->estimated_finish_time = strtotime($appointment_time) + (strtotime($serviceWorkInfo->estimated_finish_time) - strtotime($serviceWorkInfo->appointment_time));
  454. }
  455. $serviceWorkInfo->appointment_time = strtotime($appointment_time);
  456. $serviceWorkInfo->save();
  457. }
  458. }
  459. Db::commit();
  460. return true;
  461. } catch (\Exception $e) {
  462. Db::rollback();
  463. self::setError($e->getMessage());
  464. return false;
  465. }
  466. }
  467. /**
  468. * 美团改约通知
  469. * @param array $order
  470. * @return bool
  471. */
  472. public static function updateOrderHandle(array $order)
  473. {
  474. $message = json_decode($order['message'], true);
  475. Db::startTrans();
  476. try {
  477. $thirdOrders = ThirdOrders::where('orderId',$message['orderId'])->findOrEmpty();
  478. if(!$thirdOrders->isEmpty()){
  479. $thirdOrders->bookStatus = 2;
  480. $thirdOrders->save();
  481. $serviceWorkInfo = ServiceWork::find($thirdOrders->work_id);
  482. if(!empty($serviceWorkInfo)){
  483. $appointment_time = $message['reserveEndtime'];
  484. ServiceWorkAppointmentLog::create([
  485. 'work_id'=>$serviceWorkInfo->id,
  486. 'last_appointment_time'=>strtotime($serviceWorkInfo->appointment_time),
  487. 'this_appointment_time'=>strtotime($appointment_time),
  488. ]);
  489. //修改预计完成时间
  490. if ($serviceWorkInfo->estimated_finish_time) {
  491. $serviceWorkInfo->estimated_finish_time = strtotime($appointment_time) + (strtotime($serviceWorkInfo->estimated_finish_time) - strtotime($serviceWorkInfo->appointment_time));
  492. }
  493. $serviceWorkInfo->appointment_time = strtotime($appointment_time);
  494. $serviceWorkInfo->save();
  495. }
  496. }
  497. Db::commit();
  498. return true;
  499. } catch (\Exception $e) {
  500. Db::rollback();
  501. self::setError($e->getMessage());
  502. return false;
  503. }
  504. }
  505. /**
  506. * 获取美团商品信息
  507. * @param $offset
  508. * @return string
  509. */
  510. public static function queryshopdeal($offset=1)
  511. {
  512. $url = 'https://api-open-cater.meituan.com/ddzh/tuangou/deal/queryshopdeal';
  513. $data = [
  514. 'timestamp'=>time(),
  515. 'appAuthToken'=>self::shop_token2['accessToken'],
  516. 'charset'=>'utf-8',
  517. 'version'=>'2',
  518. 'developerId'=>self::developerId,
  519. 'businessId'=>58,
  520. 'biz'=>json_encode([
  521. 'offset'=>$offset,
  522. 'limit'=>100,
  523. "source"=>2,
  524. ],JSON_UNESCAPED_UNICODE)
  525. ];
  526. $sign_data = self::get_sign(self::assessKey, $data);
  527. $data['sign'] = $sign_data;
  528. return http_request($url,http_build_query($data));
  529. }
  530. /**
  531. * 获取美团商品信息
  532. * @param $offset
  533. * @return string
  534. */
  535. public static function queryshopdeal1($offset=1)
  536. {
  537. $url = 'https://api-open-cater.meituan.com/ddzh/tuangou/deal/queryshopdeal';
  538. $data = [
  539. 'timestamp'=>time(),
  540. 'appAuthToken'=>self::shop_token1['accessToken'],
  541. 'charset'=>'utf-8',
  542. 'version'=>'2',
  543. 'developerId'=>self::developerId,
  544. 'businessId'=>58,
  545. 'biz'=>json_encode([
  546. 'offset'=>$offset,
  547. 'limit'=>100,
  548. "source"=>2,
  549. ],JSON_UNESCAPED_UNICODE)
  550. ];
  551. $sign_data = self::get_sign(self::assessKey, $data);
  552. $data['sign'] = $sign_data;
  553. return http_request($url,http_build_query($data));
  554. }
  555. /**
  556. * 商家改约
  557. * @param $offset
  558. * @return string
  559. */
  560. public static function merchantmodify($data)
  561. {
  562. $url = 'https://api-open-cater.meituan.com/ddzh/yuding/lifereserve/merchantmodify';
  563. $opBizCode = !empty($data['request_msg'])?json_decode($data['request_msg'],true)['opBizCode']:'';
  564. $accessToken = $opBizCode == 'AE7MKOJAV67338LIC3UD0K5TGIO' ? self::shop_token2['accessToken'] : self::shop_token1['accessToken'];
  565. $data = [
  566. 'timestamp'=>time(),
  567. 'appAuthToken'=>$accessToken,
  568. 'charset'=>'utf-8',
  569. 'version'=>'2',
  570. 'developerId'=>self::developerId,
  571. 'businessId'=>58,
  572. 'biz'=>json_encode([
  573. 'reserveOrderId'=>$data['reserveOrderId'],
  574. 'reserveUserName'=>$data['reserveUserName'],
  575. "reservePhone"=>$data['reservePhone'],
  576. "reserveAddress"=>$data['reserveAddress'],
  577. "bookStartTime"=>$data['bookStartTime'],
  578. "bookEndTime"=>$data['bookEndTime'],
  579. ],JSON_UNESCAPED_UNICODE)
  580. ];
  581. $sign_data = self::get_sign(self::assessKey, $data);
  582. $data['sign'] = $sign_data;
  583. return http_request($url,http_build_query($data));
  584. }
  585. /**
  586. * 商家取消预定
  587. * @param $params
  588. * @return string|true
  589. */
  590. public static function merchantcancelorder($work_id)
  591. {
  592. return '';
  593. $third_order = ThirdOrders::where('work_id',$work_id)->findOrEmpty();
  594. if(!$third_order->isEmpty() && !empty($third_order['request_msg']) && $third_order['third_type']==1){
  595. Log::write('取消美团订单'.$work_id);
  596. $third_order->bookStatus = 3;
  597. $third_order->save();
  598. $url = 'https://api-open-cater.meituan.com/ddzh/yuding/merchantcancelorder';
  599. $opBizCode = !empty($third_order['request_msg'])?json_decode($third_order['request_msg'],true)['opBizCode']:'';
  600. $accessToken = $opBizCode == 'AE7MKOJAV67338LIC3UD0K5TGIO' ? self::shop_token2['accessToken'] : self::shop_token1['accessToken'];
  601. $data = [
  602. 'timestamp'=>time(),
  603. 'appAuthToken'=>$accessToken,
  604. 'charset'=>'utf-8',
  605. 'version'=>'2',
  606. 'developerId'=>self::developerId,
  607. 'businessId'=>58,
  608. 'biz'=>json_encode([
  609. 'orderId'=>$third_order['orderId'],
  610. 'cancelReason'=>'取消预定',
  611. "type"=>2,
  612. ],JSON_UNESCAPED_UNICODE)
  613. ];
  614. $sign_data = self::get_sign(self::assessKey, $data);
  615. $data['sign'] = $sign_data;
  616. return http_request($url,http_build_query($data));
  617. }
  618. return true;
  619. }
  620. /**
  621. * 更新履约状态
  622. * @param $work
  623. * @return string|void
  624. */
  625. public static function updateorderfulfillinfo($work,$orderFulfillStatus)
  626. {
  627. return '';
  628. //http_request('https://developer.kyjlkj.com/platf/Kaidianbao/performanceSecurity',http_build_query(['orderFulfillStatus'=>$orderFulfillStatus]));
  629. $third_order = ThirdOrders::where('work_id',$work['id'])->findOrEmpty();
  630. if(!$third_order->isEmpty() && !empty($third_order['request_msg'])) {
  631. // 家政/维修更新顺序:已分配(40001)→ 已到达(40002)→ 履约完成(41001)
  632. $app_sku_id = ThirdGoods::where('product_id',$third_order['productId'])->value('app_sku_id');
  633. //判断当前履约状态
  634. $pic_url = 'https://cdnweixiu.kyjlkj.com/uploads/images/20240914/2024091414471041c336653.png';
  635. switch ($orderFulfillStatus){
  636. case '40001':
  637. $describe = '已分配';
  638. break;
  639. case '40002':
  640. $describe = '已到达';
  641. break;
  642. case '41001':
  643. $describe = '履约完成';
  644. $pic_url = !empty($work['finished_images'][0])?$work['finished_images'][0]:$pic_url;
  645. break;
  646. default:
  647. $describe = '未知';
  648. break;
  649. }
  650. $url = 'https://api-open-cater.meituan.com/ddzh/yuding/updateorderfulfillinfo';
  651. $opBizCode = !empty($third_order['request_msg']) ? json_decode($third_order['request_msg'], true)['opBizCode'] : '';
  652. $accessToken = $opBizCode == 'AE7MKOJAV67338LIC3UD0K5TGIO' ? self::shop_token2['accessToken'] : self::shop_token1['accessToken'];
  653. $data = [
  654. 'timestamp' => time(),
  655. 'appAuthToken' => $accessToken,
  656. 'charset' => 'utf-8',
  657. 'version' => '2',
  658. 'developerId' => self::developerId,
  659. 'businessId' => 58,
  660. 'biz' => json_encode([
  661. 'orderId' => $third_order['orderId'],
  662. 'attrKeyValue' => [
  663. 'service_voucher' => [
  664. 'detail_list' => [
  665. [
  666. 'app_sku_id' => $app_sku_id,
  667. 'describe' => $describe,
  668. 'pic_url' => $pic_url
  669. ]
  670. ]
  671. ],
  672. 'delivery_info' => '无',
  673. 'delivery_type' => 3
  674. ],
  675. "type" => 2,
  676. "orderFulfillStatus" => $orderFulfillStatus
  677. ], JSON_UNESCAPED_UNICODE)
  678. ];
  679. $sign_data = self::get_sign(self::assessKey, $data);
  680. $data['sign'] = $sign_data;
  681. return http_request($url, http_build_query($data));
  682. }
  683. }
  684. /**
  685. * 商家改约
  686. * @param $offset
  687. * @return string
  688. */
  689. public static function changeresultcallback($reserveOrderId)
  690. {
  691. $url = 'https://api-open-cater.meituan.com/ddzh/yuding/changeresultcallback';
  692. $opBizCode = !empty($data['request_msg'])?json_decode($data['request_msg'],true)['opBizCode']:'';
  693. $accessToken = $opBizCode == 'AE7MKOJAV67338LIC3UD0K5TGIO' ? self::shop_token2['accessToken'] : self::shop_token1['accessToken'];
  694. $data = [
  695. 'timestamp'=>time(),
  696. 'appAuthToken'=>$accessToken,
  697. 'charset'=>'utf-8',
  698. 'version'=>'2',
  699. 'developerId'=>self::developerId,
  700. 'businessId'=>58,
  701. 'biz'=>json_encode([
  702. 'reserveOrderId'=>$reserveOrderId,
  703. 'changeOrderResult'=>2,
  704. "code"=>200,
  705. ],JSON_UNESCAPED_UNICODE)
  706. ];
  707. $sign_data = self::get_sign(self::assessKey, $data);
  708. $data['sign'] = $sign_data;
  709. return http_request($url,http_build_query($data));
  710. }
  711. }