OrderService.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <?php
  2. /**
  3. * Author: luzheng.liu
  4. * Time: 2020/12/24 13:44
  5. */
  6. namespace app\common\service;
  7. use app\api\controller\Order;
  8. use app\api\exception\ApiException;
  9. use app\api\model\AllocateModel;
  10. use app\api\model\CartModel;
  11. use app\api\model\OrderModel;
  12. use app\api\model\OrderProductModel;
  13. use app\api\model\ProductModel;
  14. use app\api\model\StoreModel;
  15. use app\api\model\UserModel;
  16. use app\api\model\WriteOffModel;
  17. use app\common\until\Until;
  18. use GuzzleHttp\Client;
  19. use think\facade\Cache;
  20. use think\facade\Config;
  21. use const http\Client\Curl\Features\UNIX_SOCKETS;
  22. class OrderService {
  23. public $userName = 'heshen';
  24. public $passwd = 'heshenit@0563';
  25. public $time = [];
  26. public function payOrder($input) {
  27. $userId = empty($input['userId']) ? Until::$userId : $input['userId'];
  28. $payCode = (new StoreModel())->getPayCode($input['storeId']);
  29. $this->time[] = 'start' . time();
  30. $orderSn = Until::createSn();
  31. $productInfo = (new ProductModel())::where(['id' => $input['productId']])->find();
  32. $productInfo = Until::modelToArray($productInfo);
  33. $userInfo = (new UserModel())::where(['id' => $userId])->find();
  34. $userInfo = Until::modelToArray($userInfo);
  35. if (empty($userInfo)) {
  36. throw new ApiException('无此用户');
  37. }
  38. $model = new OrderModel();
  39. try {
  40. $orderType = 1;
  41. if (Until::$isAdmin) {
  42. $orderType = 2;
  43. }
  44. $model->startTrans();
  45. $orderMoney = $productInfo['current_price'] * (int)abs($input['num']);
  46. $orderId = $model->insertGetId([
  47. 'order_sn' => $orderSn,
  48. 'order_money' => $orderMoney,
  49. 'product_id' => $input['productId'],
  50. 'staff_id' => $input['staffId'] ?? 0,
  51. 'num' => (int)abs($input['num']),
  52. 'store_id' => $input['storeId'],
  53. 'appointment_time' => $input['appointmentTime'],
  54. 'end_time' => $input['endTime'],
  55. 'mobile' => $input['mobile'],
  56. 'status' => 1,
  57. 'order_type' => $orderType,
  58. 'user_id' => $userId,
  59. 'admin_id' => Until::$adminId
  60. ]);
  61. (new AllocateModel())->insertGetId([
  62. 'order_id' => $orderId,
  63. 'staff_id' => $input['staffId'],
  64. 'assign_admin_id' => Until::$adminId,
  65. 'server_start_time' => $input['appointmentTime'],
  66. ]);
  67. $opModel = new OrderProductModel();
  68. $opModel->insert([
  69. 'order_id' => $orderId,
  70. 'product_id' => $input['productId'],
  71. 'product_num' => (int)abs($input['num']),
  72. 'current_price' => $productInfo['current_price'],
  73. 'product_name' => $productInfo['product_name'],
  74. 'product_img' => $productInfo['product_img'],
  75. 'old_price' => $productInfo['old_price'],
  76. 'company_id' => $productInfo['company_id'],
  77. 'brand_id' => $productInfo['brand_id'],
  78. 'product_type_id' => $productInfo['product_type_id'],
  79. 'type' => $productInfo['type'],
  80. 'product_snap' => json_encode($productInfo)
  81. ]);
  82. (new WriteOffModel())->insertGetId([
  83. 'write_off_code' => '',
  84. 'order_id' => $orderId,
  85. 'write_off_status' => 1,
  86. ]);
  87. $model->commit();
  88. } catch (\Exception $e) {
  89. $model->rollback();
  90. throw new ApiException($e->getMessage());
  91. }
  92. //{attach string支付主体的标识
  93. //mark string商品信息
  94. //money integer($int32)金额,分为单位
  95. //openId string小程序的openid
  96. //orderId string订单号
  97. //payCode string支付标识
  98. //username string用户名
  99. //}
  100. if (!Until::$isAdmin) {
  101. $otherData = [
  102. 'openId' => $userInfo['open_id'],
  103. 'attach' => 'storeId:' . $input['storeId'],
  104. 'money' => $orderMoney * 100,
  105. 'mark' => '购买了' . $productInfo['product_name'],
  106. 'orderId' => $orderSn,
  107. 'username' => $userInfo['name'],
  108. 'payCode' => strtoupper($payCode),
  109. ];
  110. $this->time[] = 'leo-start' . time();
  111. $wxOrderInfo = $this->createOrderForOther($otherData);
  112. $order = [
  113. 'nonceStr' => $wxOrderInfo['nonceStr'],
  114. 'package' => $wxOrderInfo['pack'],
  115. 'paySign' => $wxOrderInfo['paySign'],
  116. 'timeStamp' => $wxOrderInfo['timeStamp'],
  117. 'signType' => $wxOrderInfo['signType'],
  118. 'orderSn' => $orderSn,
  119. 'orderId' => $orderId
  120. ];
  121. }
  122. $this->time[] = 'leo-end' . time();
  123. $order['time'] = $this->time;
  124. return $order;
  125. }
  126. public function payFoodOrder($input) {
  127. $orderSn = Until::createSn();
  128. $cartModel = new CartModel();
  129. $cartModel->setFields('c.store_id,cp.num,p.*');
  130. $cartModel->setWhere(['c.id' => $input['cartId']]);
  131. $cartInfo = $cartModel->getCartList();
  132. $orderMoney = 0;
  133. $recordData = [];
  134. $storeId = 0;
  135. foreach ($cartInfo as $info) {
  136. $storeId = $info['store_id'];
  137. $orderMoney += $info['num'] * $info['current_price'];
  138. }
  139. $payCode = (new StoreModel())->getPayCode($storeId);
  140. $userInfo = (new UserModel())::where(['id' => Until::$userId])->find();
  141. $userInfo = Until::modelToArray($userInfo);
  142. if (empty($userInfo)) {
  143. throw new ApiException('无此用户');
  144. }
  145. $model = new OrderModel();
  146. try {
  147. $userId = Until::$userId;
  148. $orderType = 3;
  149. $model->startTrans();
  150. $cartModel::where(['id' => $input['cartId']])->update(['status' => 0]);
  151. $orderId = $model->insertGetId([
  152. 'order_sn' => $orderSn,
  153. 'order_money' => $orderMoney,
  154. 'product_id' => 0,
  155. 'num' => 0,
  156. 'store_id' => $storeId,
  157. 'table_id' => $input['tableId'],
  158. 'appointment_time' => null,
  159. 'end_time' => null,
  160. 'mobile' => '',
  161. 'order_type' => $orderType,
  162. 'user_id' => $userId,
  163. ]);
  164. $opModel = new OrderProductModel();
  165. foreach ($cartInfo as $info) {
  166. $recordData[] = [
  167. 'order_id' => $orderId,
  168. 'product_id' => $info['id'],
  169. 'product_num' => $info['num'],
  170. 'current_price' => $info['current_price'],
  171. 'product_name' => $info['product_name'],
  172. 'product_img' => $info['product_img'],
  173. 'old_price' => $info['old_price'],
  174. 'company_id' => $info['company_id'],
  175. 'brand_id' => $info['brand_id'],
  176. 'product_type_id' => $info['product_type_id'],
  177. 'type' => $info['type'],
  178. 'product_snap' => json_encode($info)
  179. ];
  180. }
  181. $opModel->insertAll($recordData);
  182. $cartModel::where(['id' => $input['cartId']])->update(['status' => 0]);
  183. $model->commit();
  184. } catch (\Exception $e) {
  185. $model->rollback();
  186. throw new ApiException($e->getMessage());
  187. }
  188. //{attach string支付主体的标识
  189. //mark string商品信息
  190. //money integer($int32)金额,分为单位
  191. //openId string小程序的openid
  192. //orderId string订单号
  193. //payCode string支付标识
  194. //username string用户名
  195. //}
  196. if (!Until::$isAdmin) {
  197. $otherData = [
  198. 'openId' => $userInfo['open_id'],
  199. 'attach' => 'storeId:' . $storeId,
  200. 'money' => $orderMoney * 100,
  201. 'mark' => '购买了小食',
  202. 'orderId' => $orderSn,
  203. 'username' => $userInfo['name'],
  204. 'payCode' => strtoupper($payCode),
  205. ];
  206. $this->time[] = 'leo-start' . time();
  207. $wxOrderInfo = $this->createOrderForOther($otherData);
  208. $order = [
  209. 'nonceStr' => $wxOrderInfo['nonceStr'],
  210. 'package' => $wxOrderInfo['pack'],
  211. 'paySign' => $wxOrderInfo['paySign'],
  212. 'timeStamp' => $wxOrderInfo['timeStamp'],
  213. 'signType' => $wxOrderInfo['signType'],
  214. 'orderSn' => $orderSn,
  215. 'orderId' => $orderId
  216. ];
  217. }
  218. $this->time[] = 'leo-end' . time();
  219. $order['time'] = $this->time;
  220. return $order;
  221. }
  222. public function payAgain(int $orderId) {
  223. $model = new OrderModel();
  224. $info = $model::where(['id' => $orderId])->find();
  225. $payCode = (new StoreModel())->getPayCode($info['store_id']);
  226. // $productInfo = (new ProductModel())::where(['id' => $info['product_id']])->find();
  227. if ($info['status'] === OrderModel::IS_PAY) {
  228. throw new ApiException('订单已支付');
  229. }
  230. $userInfo = (new UserModel())::where(['id' => Until::$userId])->find();
  231. if (empty($userInfo)) {
  232. throw new ApiException('无此用户');
  233. }
  234. $paySn = Until::createSn();
  235. $model::where(['id' => $orderId])->update(['pay_sn' => $paySn]);
  236. $otherData = [
  237. 'openId' => $userInfo['open_id'],
  238. 'attach' => 'storeId:' . $info['store_id'],
  239. 'money' => $info['order_money'] * 100,
  240. 'mark' => '购买了商品',
  241. 'orderId' => $paySn,
  242. 'username' => $userInfo['name'],
  243. 'payCode' => strtoupper($payCode),
  244. ];
  245. $wxOrderInfo = $this->createOrderForOther($otherData);
  246. $order = [
  247. 'nonceStr' => $wxOrderInfo['nonceStr'],
  248. 'package' => $wxOrderInfo['pack'],
  249. 'paySign' => $wxOrderInfo['paySign'],
  250. 'timeStamp' => $wxOrderInfo['timeStamp'],
  251. 'signType' => $wxOrderInfo['signType'],
  252. 'orderSn' => $info['order_sn'],
  253. 'orderId' => $orderId
  254. ];
  255. return $order;
  256. }
  257. public function getPayToken() {
  258. // var_dump('获取token'.time());
  259. $this->time[] = 'payToken-start-' . time();
  260. $key = 'payToken' . $this->userName;
  261. $token = Cache::get($key);
  262. if (empty($token)) {
  263. $token = $this->getAuthPay();
  264. Cache::set($key, $token, '7100');
  265. // var_dump('接口获取token结束'.time());
  266. return $token;
  267. }
  268. $this->time[] = 'payToken-end-' . time();
  269. // var_dump('缓存获取token结束'.time());
  270. return $token;
  271. }
  272. public function getAuthPay() {
  273. $client = new Client();
  274. $time = Until::msectime();
  275. $res = $client->request('Post',
  276. Config::get('domain') . "api/auth/create", [
  277. 'json' => [
  278. 'username' => $this->userName,
  279. "password" => $this->passwd,
  280. 'timestamp' => $time,
  281. 'sign' => md5($this->userName . $time . $this->passwd)
  282. ]
  283. ]);
  284. $info = json_decode((string)$res->getBody(), true);
  285. if ($info['code'] != 200) {
  286. throw new ApiException($info['msg']);
  287. }
  288. return $info['data']['token'];
  289. }
  290. public function createOrderForOther(array $data) {
  291. // var_dump('start'.time());
  292. $this->time[] = 'createOrder-start-' . time();
  293. $client = new Client();
  294. $res = $client->request('Post',
  295. Config::get('domain') . "api/supers/wx-pay/gateway-no-order", [
  296. 'json' => $data,
  297. 'headers' => [
  298. 'API-TOKEN-V1' => $this->getPayToken()
  299. ]
  300. ]);
  301. $info = json_decode((string)$res->getBody(), true);
  302. if ($info['code'] != 200) {
  303. throw new ApiException($info['msg']);
  304. }
  305. $this->time[] = 'createOrder-end-' . time();
  306. // var_dump('end'.time());
  307. return $info['data'];
  308. }
  309. public function notify(string $orderSn) {
  310. $model = new OrderModel();
  311. $rs = $model::where(['order_sn' => $orderSn])->whereOr(['pay_sn' => $orderSn])->find();
  312. if (empty($rs) || $rs['status'] === 2) {
  313. return;
  314. }
  315. // var_dump($rs);
  316. $model::where(['order_sn' => $orderSn])->update(['status' => 2, 'pay_time' => date('Y-m-d H:i:s')]);
  317. $model::where(['pay_sn' => $orderSn])->update(['status' => 2, 'pay_time' => date('Y-m-d H:i:s')]);
  318. $wModel = new WriteOffModel();
  319. $code = $this->changeCode();
  320. $wModel::where(['order_id' => $rs['id']])->update([
  321. 'write_off_code' => $code,
  322. 'over_time' => date('Y-m-d H:i:s', time() + 2 * 60),
  323. ]);
  324. }
  325. public function changeCode() {
  326. $wModel = new WriteOffModel();
  327. $codeList = $wModel::where(['write_off_status' => WriteOffModel::NO_WRITE_OFF])->field('write_off_code')->select();
  328. $codeList = Until::modelToArray($codeList);
  329. $codeArr = [];
  330. foreach ($codeList as $v) {
  331. $codeArr[] = $v['write_off_code'];
  332. }
  333. $code = $this->makeUniqCode($codeArr);
  334. return $code;
  335. }
  336. public function makeUniqCode(array $codeList) {
  337. $code = random_int(10000, 99999);
  338. if (in_array($code, $codeList)) {
  339. $this->makeUniqCode($codeList);
  340. }
  341. return $code;
  342. }
  343. }