OrderService.php 12 KB

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