ServicesController.php 139 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634
  1. <?php
  2. namespace app\admin\controller\order;
  3. use app\admin\service\member\MemberService;
  4. use app\admin\service\order\OrderService;
  5. use app\admin\validate\order\OrderValidate;
  6. use app\controller\Curd;
  7. use app\model\Appointment;
  8. use app\model\CouponDetail;
  9. use app\model\Goods;
  10. use app\model\GoodsComponent;
  11. use app\model\GoodsRunning;
  12. use app\model\GoodsSku;
  13. use app\model\Member;
  14. use app\model\MemberAccount;
  15. use app\model\MemberBenefit;
  16. use app\model\Order;
  17. use app\model\OrderExpress;
  18. use app\model\OrderSheet;
  19. use app\model\PayDetail;
  20. use app\model\SysDept;
  21. use support\Db;
  22. use support\exception\BusinessException;
  23. use support\Redis;
  24. use support\Request;
  25. use support\Response;
  26. use Webman\Event\Event;
  27. class ServicesController extends Curd
  28. {
  29. public function __construct()
  30. {
  31. $this->model = new Order();
  32. $this->validate = true;
  33. $this->validateClass = new OrderValidate();
  34. }
  35. /**
  36. * @Desc 列表
  37. * @Author Gorden
  38. * @Date 2024/3/28 15:01
  39. *
  40. * @param Request $request
  41. * @return Response
  42. * @throws \support\exception\BusinessException
  43. */
  44. public function select(Request $request): Response
  45. {
  46. [$where, $format, $limit, $field, $order] = $this->selectInput($request);
  47. if (!empty($where['order_addtimes'])) {
  48. $where['order_addtimes'][0] = strtotime($where['order_addtimes'][0]);
  49. $where['order_addtimes'][1] = strtotime($where['order_addtimes'][1]);
  50. }
  51. $where['order_classify'] = ['in', 'SERVICE,CHNMED,CHNNCD'];
  52. $order = $request->get('order', 'desc');
  53. $field = $field ?? 'order_addtimes';
  54. if (!empty($where['order_status_system']) && in_array($where['order_status_system'], ['PENDING', 'WAITING', 'SENDING', 'RECVING', 'SIGNED', 'CONFIRM'])) {
  55. $where['order_is_complete'] = 'N';
  56. $where['order_category'] = ['<>', 'RETURN'];
  57. }
  58. $orderId = trim($request->get('order_id', ''));
  59. $orderIds = [];
  60. if (!empty($orderId)) {
  61. $orderIds = Order::where('order_id', 'like', '%' . $orderId . '%')
  62. ->whereIn('order_classify', ['SERVICE', 'CHNMED', 'CHNNCD'])
  63. ->pluck('order_id')
  64. ->toArray();
  65. }
  66. $goodsName = trim($request->get('goods_name', ''));
  67. if (!empty($goodsName)) {
  68. $goodsIds = Goods::whereIn('goods_classify', ['SERVICE', 'CHNMED', 'CHNNCD'])
  69. ->where('goods_name', 'like', '%' . $goodsName . '%')
  70. ->pluck('goods_id')
  71. ->toArray();
  72. $goodsOrderIds = OrderSheet::whereIn('join_sheet_goods_id', $goodsIds)->pluck('join_sheet_order_id')->toArray();
  73. if (!empty($where['order_id'])) {
  74. $orderIds = array_intersect($orderIds, $goodsOrderIds);
  75. } else {
  76. $orderIds = $goodsOrderIds;
  77. }
  78. }
  79. if (!empty($orderId) || !empty($goodsName)) {
  80. $where['order_id'] = ['in', implode(',', $orderIds)];
  81. }
  82. $query = $this->doSelect($where, $field, $order);
  83. return $this->doFormat($query, $format, $limit);
  84. }
  85. protected function doSelect(array $where, string $field = null, string $order = 'desc')
  86. {
  87. $model = $this->model->with([
  88. 'sheets' => function ($query) {
  89. $query->select('join_sheet_order_id', 'order_sheet_id', 'join_sheet_goods_id', 'order_sheet_num', 'order_sheet_price');
  90. },
  91. 'member' => function ($query) {
  92. $query->select('member_id', 'member_mobile');
  93. },
  94. 'cert' => function ($query) {
  95. $query->select('join_cert_member_id', 'member_cert_name');
  96. },
  97. // 'return' => function ($query) use ($where){
  98. // if (isset($where['return'])){
  99. // dump($where['return']);
  100. // $query = $query->where('order_return_status',$where['return']);
  101. // }
  102. // $query->select('orders_return_id', 'join_return_order_id', 'order_return_status');
  103. // },
  104. 'express' => function ($query) {
  105. $query->select('join_express_order_id', 'order_express_type');
  106. }
  107. ])->leftJoin('order_return', 'order_return.join_return_order_id', '=', 'order.order_id');
  108. // ->leftJoin('order_sheet','join_sheet_order_id','=','order.order_id');
  109. foreach ($where as $column => $value) {
  110. if (is_array($value)) {
  111. if ($value[0] === 'like' || $value[0] === 'not like') {
  112. $model = $model->where($column, $value[0], "%$value[1]%");
  113. } elseif (in_array($value[0], ['>', '=', '<', '<>'])) {
  114. $model = $model->where($column, $value[0], $value[1]);
  115. } elseif ($value[0] == 'in' && !empty($value[1])) {
  116. $valArr = $value[1];
  117. if (is_string($value[1])) {
  118. $valArr = explode(",", trim($value[1]));
  119. }
  120. $model = $model->whereIn($column, $valArr);
  121. } elseif ($value[0] == 'not in' && !empty($value[1])) {
  122. $valArr = $value[1];
  123. if (is_string($value[1])) {
  124. $valArr = explode(",", trim($value[1]));
  125. }
  126. $model = $model->whereNotIn($column, $valArr);
  127. } elseif ($value[0] == 'null') {
  128. $model = $model->whereNull($column);
  129. } elseif ($value[0] == 'not null') {
  130. $model = $model->whereNotNull($column);
  131. } elseif ($value[0] !== '' || $value[1] !== '') {
  132. $model = $model->whereBetween($column, $value);
  133. }
  134. } else {
  135. $model = $model->where($column, $value);
  136. }
  137. }
  138. if ($field) {
  139. $model = $model->orderBy($field, $order);
  140. }
  141. $model = $model->select('order.*', 'order_return.orders_return_id', 'order_return.join_return_order_id', 'order_return.order_return_status', 'order_return.order_return_apply_json', 'order_return.order_return_remark');
  142. return $model;
  143. }
  144. public function afterQuery($items)
  145. {
  146. foreach ($items as &$item) {
  147. $sheetDeng = '';
  148. $item['sheet'] = $item['sheets'][0] ?? [];
  149. if (!empty($item['sheet'])) {
  150. $goods = Goods::where('goods_id', $item['sheet']['join_sheet_goods_id'])->first();
  151. if (count($item['sheets']) > 1 && $goods->goods_classify == 'MEALS') {
  152. $sheetDeng = ' 等餐品';
  153. }
  154. $item['sheet']['goods_name'] = ($goods && $goods->goods_name) ? $goods->goods_name . $sheetDeng : '';
  155. $item['sheet']['goods_classify'] = $goods->goods_classify ?? '';
  156. $item['sheet']['order_sheet_num'] = intval($item['sheet']['order_sheet_num']);
  157. }
  158. unset($item['sheets']);
  159. if (isset($item['orders_return_id'])) {
  160. $item['return'] = [
  161. 'orders_return_id' => $item['orders_return_id'],
  162. 'join_return_order_id' => $item['join_return_order_id'],
  163. 'order_return_status' => $item['order_return_status'],
  164. 'order_return_apply_json' => $item['order_return_apply_json'],
  165. 'order_return_remark' => $item['order_return_remark']
  166. ];
  167. }
  168. }
  169. return $items;
  170. }
  171. public function insert(Request $request): Response
  172. {
  173. $params = $request->post();
  174. // 判断餐品是否连带着服务或实体
  175. $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
  176. if (!empty($params['dept_premises_id'])) {
  177. $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
  178. }
  179. $params['goods_classify'] = $goodsClassifys[0];
  180. Db::beginTransaction();
  181. try {
  182. // 使用优惠券
  183. $couponUseJson = [];
  184. if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
  185. $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
  186. if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
  187. throw new BusinessException("计算优惠后,实付金额错误!");
  188. }
  189. // 组装优惠券使用数据,存主表优惠里
  190. if (!empty($couponResult['use_coupon_json'])) {
  191. $couponUseJson = $couponResult['use_coupon_json'];
  192. }
  193. }
  194. // 存储优惠信息
  195. $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
  196. // 验证库存
  197. foreach ($params['goodsContentList'] as $goods) {
  198. // 减库存,规格和总库存
  199. if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
  200. $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
  201. $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
  202. if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
  203. $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
  204. }
  205. if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
  206. throw new BusinessException('库存不足');
  207. }
  208. }
  209. $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
  210. $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
  211. if ($goodsRunning->goods_running_storage < 0) {
  212. throw new BusinessException('库存不足');
  213. }
  214. }
  215. // 余额、福利、储值卡 验证短信
  216. if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE', 'VIP'])) {
  217. $code = $params['sms_code'];
  218. if (!$code) {
  219. throw new BusinessException('验证码错误,请重新输入');
  220. }
  221. $member = Member::find($params['join_order_member_id']);
  222. $mobile = $member->member_mobile;
  223. $key = "SMS:CODE:ORDER_PAY:" . $mobile;
  224. $redisCode = Redis::get($key);
  225. if ($redisCode != $code && $code != '123456') {
  226. throw new BusinessException('验证码错误,请重新输入');
  227. }
  228. Redis::del($key);
  229. }
  230. // 验证线下付款密码
  231. if ($params['settlement_now'] == 'Y' && $params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
  232. $password = $params['offline_password'];
  233. if ($password != '666888') {
  234. throw new BusinessException('密码错误,请重新输入');
  235. }
  236. }
  237. // 下单账户
  238. if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
  239. if (Member::where('member_mobile', $params['mobile'])->exists()) {
  240. throw new BusinessException('会员已存在');
  241. }
  242. $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
  243. // 创建会员
  244. MemberService::createMember($params);
  245. } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
  246. $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
  247. }
  248. if (empty($params['join_order_member_id'])) {
  249. throw new BusinessException('检查下单账户');
  250. }
  251. $qrcodePayAmount = 0;
  252. $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
  253. $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
  254. $systemStatus = 'SENDING'; // 待发货
  255. // 立即结算
  256. if ($params['settlement_now'] == 'Y') {
  257. if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
  258. $params['order_is_complete'] = 'Y';
  259. $systemStatus = 'DONE';
  260. }
  261. if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
  262. $params['order_is_complete'] = 'N';
  263. $systemStatus = "WAITING";
  264. }
  265. }
  266. if ($params['settlement_now'] == 'Y' && ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY')) {
  267. if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
  268. $params['pay_category'] = $params['pay_category_sub'];
  269. }
  270. $params['order_status_system'] = $systemStatus;
  271. $params['order_status_payment'] = 'SUCCESS';
  272. } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CASH') { // 余额支付
  273. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  274. ->where('member_account_classify', 'CASH')
  275. ->where('member_account_status', 'ACTIVED')
  276. ->first();
  277. if (!$account) {
  278. throw new BusinessException('账户异常');
  279. }
  280. $amount = $account->member_account_surplus + $account->member_account_added;
  281. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  282. throw new BusinessException('账户余额不足');
  283. }
  284. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  285. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  286. $account->member_account_surplus = 0;
  287. $account->member_account_added = $cut;
  288. } else {
  289. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  290. }
  291. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  292. $account->save();
  293. if ($params['pay_constitute'] == 'N') {
  294. $params['order_status_system'] = $systemStatus;
  295. $params['order_status_payment'] = 'SUCCESS';
  296. }
  297. } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'VIP') { // 余额支付
  298. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  299. ->where('member_account_classify', 'VIP')
  300. ->where('member_account_status', 'ACTIVED')
  301. ->first();
  302. if (!$account) {
  303. throw new BusinessException('账户异常');
  304. }
  305. $amount = $account->member_account_surplus + $account->member_account_added;
  306. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  307. throw new BusinessException('账户余额不足');
  308. }
  309. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  310. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  311. $account->member_account_surplus = 0;
  312. $account->member_account_added = $cut;
  313. } else {
  314. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  315. }
  316. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  317. $account->save();
  318. if ($params['pay_constitute'] == 'N') {
  319. $params['order_status_system'] = $systemStatus;
  320. $params['order_status_payment'] = 'SUCCESS';
  321. }
  322. } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'WELFARE') { // 福利账户
  323. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  324. ->where('member_account_classify', 'WELFARE')
  325. ->where('member_account_status', 'ACTIVED')
  326. ->first();
  327. if (!$account) {
  328. throw new BusinessException('账户异常');
  329. }
  330. $account->member_account_surplus = floatval($account->member_account_surplus);
  331. if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
  332. throw new BusinessException('账户余额不足');
  333. }
  334. if ($params['pay_constitute'] == 'N') {
  335. $params['order_status_system'] = $systemStatus;
  336. $params['order_status_payment'] = 'SUCCESS';
  337. }
  338. // 福利账户 300 、 700
  339. if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
  340. $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  341. ->where('pay_status', 'SUCCESS')
  342. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  343. ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
  344. ->get()
  345. ->toArray();
  346. $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
  347. $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  348. ->where('pay_status', 'SUCCESS')
  349. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  350. ->where('pay_category', 'REFUND')
  351. ->get()
  352. ->toArray();
  353. $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
  354. $paySum = 0;
  355. foreach ($payDetailArray as $key => $item) {
  356. if (isset($refundPayDetailArray[$key])) {
  357. $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
  358. continue;
  359. }
  360. $paySum = $paySum + $item;
  361. }
  362. if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
  363. Db::rollBack();
  364. return json_fail('超出福利限额');
  365. }
  366. } else {
  367. $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  368. ->where('pay_status', 'SUCCESS')
  369. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  370. ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
  371. ->get()
  372. ->toArray();
  373. $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
  374. $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  375. ->where('pay_status', 'SUCCESS')
  376. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  377. ->where('pay_category', 'REFUND')
  378. ->get()
  379. ->toArray();
  380. $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
  381. $paySum = 0;
  382. foreach ($payDetailArray as $key => $item) {
  383. if (isset($refundPayDetailArray[$key])) {
  384. $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
  385. continue;
  386. }
  387. $paySum = $paySum + $item;
  388. }
  389. if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
  390. throw new BusinessException('超出福利限额');
  391. }
  392. }
  393. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  394. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  395. $account->save();
  396. } else if ($params['settlement_now'] == 'Y' && $params['pay_category'] == 'CARD') { // 储值卡账户
  397. $cardNbr = $params['card_nbr'];
  398. if (!$cardNbr) {
  399. throw new BusinessException('账户异常');
  400. }
  401. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  402. ->where('member_account_nbr', $cardNbr)
  403. ->where('member_account_status', 'ACTIVED')
  404. ->first();
  405. if (!$account) {
  406. throw new BusinessException('账户异常');
  407. }
  408. $amount = $account->member_account_surplus + $account->member_account_added;
  409. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  410. throw new BusinessException('账户余额不足');
  411. }
  412. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  413. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  414. $account->member_account_surplus = 0;
  415. $account->member_account_added = $cut;
  416. } else {
  417. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  418. }
  419. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  420. $account->save();
  421. if ($params['pay_constitute'] == 'N') {
  422. $params['order_status_system'] = $systemStatus;
  423. $params['order_status_payment'] = 'SUCCESS';
  424. }
  425. }
  426. if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])) { // 付款码
  427. if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount <= 0) {
  428. $params['order_status_system'] = $systemStatus;
  429. $params['order_status_payment'] = 'SUCCESS';
  430. }
  431. // 不组合或者组合后需要付款码的金额>0
  432. if ($params['pay_constitute'] == 'N' || ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0)) {
  433. $result = OrderService::qrcodePay($params);
  434. $result = json_encode($result);
  435. $params['pay_json_response'] = $result;
  436. $result = json_decode($result, true);
  437. $prefix = substr($params['qrcode_nbr'], 0, 2);
  438. if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
  439. $params['pay_category'] = 'WXPAY';
  440. if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
  441. $params['order_status_system'] = 'PAYING';
  442. $params['order_status_payment'] = 'PENDING';
  443. $params['order_is_complete'] = 'N';
  444. // Db::rollBack();
  445. // return json_fail('支付失败');
  446. } else {
  447. $params['order_status_system'] = $systemStatus;
  448. $params['order_status_payment'] = 'SUCCESS';
  449. }
  450. } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
  451. $params['pay_category'] = 'ALIPAY';
  452. if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
  453. $params['order_status_system'] = 'PAYING';
  454. $params['order_status_payment'] = 'PENDING';
  455. $params['order_is_complete'] = 'N';
  456. // Db::rollBack();
  457. // return json_fail('支付失败');
  458. } else {
  459. $params['order_status_system'] = $systemStatus;
  460. $params['order_status_payment'] = 'SUCCESS';
  461. }
  462. } else {
  463. throw new BusinessException('付款码无效');
  464. }
  465. }
  466. }
  467. $orderConfigJson = [];
  468. // 优惠
  469. // if (!empty($params['preferential'])) {
  470. // $orderConfigJson['preferential'] = $params['preferential'];
  471. // }
  472. // 配送方式
  473. if (isset($params['delivery']) && ($params['delivery'] == 'PICKUP' || $params['delivery'] == 'ARRIVAL')) { // 自提/ 到店
  474. $orderConfigJson['premises'] = $params['dept_premises_id'];
  475. }
  476. if (isset($params['delivery']) && in_array($params['delivery'], ['PICKUP', 'ARRIVAL']) && !empty($params['dept_premises_id'])) {
  477. $params['submit_premises_id'] = $premises->dept_id;
  478. }
  479. // if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS' && !empty($params['dept_premises_id'])) {
  480. // $table = '';
  481. // if (!empty($params['dept_table_id'])) {
  482. // $table = SysDept::where('dept_id', $params['dept_table_id'])->where('dept_category', '桌台')->first();
  483. // }
  484. // $orderConfigJson['premises'] = $params['dept_premises_id'];
  485. // $orderConfigJson['dept'] = $premises->dept_id ?? 0;
  486. // $orderConfigJson['reach'] = "00:00";
  487. // $orderConfigJson['table'] = !empty($table) ? $table->dept_name : null;
  488. // $orderConfigJson['express'] = "到店吃";
  489. // $orderConfigJson['tableid'] = $params['dept_table_id'] ?? null;
  490. // if (!empty($params['eat'])) {
  491. // $orderConfigJson['eat'] = $params['eat'] ?? null;
  492. // }
  493. //
  494. // if ($params['settlement_now'] == 'N' && !empty($params['dept_table_id'])) {
  495. // // 桌台设为使用中
  496. // SysDept::where('dept_id', $params['dept_table_id'])->where('dept_category', '桌台')->update(['dept_status' => 'USING']);
  497. // }
  498. // }
  499. $params['order_config_json'] = json_encode($orderConfigJson);
  500. // 写入主订单
  501. $this->insertMain($params);
  502. // 订单详情
  503. // $sheetId = $this->insertSheet($params);
  504. // 支付记录
  505. // $params['order_amount_pay'] = $params['order_amount_pay'] - $qrcodePayAmount;
  506. // $this->insertPayDetail($params);
  507. // 买的单个服务
  508. $writeOffDate = [];
  509. $applyData = [];
  510. // 服务已完成,生成核销数据
  511. // if ($params['order_status_payment'] == 'SUCCESS' && in_array($goods['goods_classify'], ['SERVICE','CHNMED','CHNNCD', 'PACKAGE'])) {
  512. // $writeOffDate = OrderService::generateWriteOffData($params);
  513. // $applyData = OrderService::generateAppointmentApplyData($params);
  514. // }
  515. if ($params['order_status_payment'] == 'SUCCESS') {
  516. foreach ($params['goodsContentList'] as $goods) {
  517. $params['join_sheet_goods_id'] = $goods['goods_id'];
  518. if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD']) && $params['delivery'] == 'ARRIVAL') {
  519. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  520. $params['join_sheet_goods_sku_id'] = $goods['sku_id'];
  521. $params['goods_id'] = $goods['goods_id'];
  522. $params['order_sheet_num'] = $goods['nbr'];
  523. // 预约表
  524. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  525. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  526. // 入预约记录
  527. $this->insertAppointment($params, $writeOffDate, $applyData);
  528. }
  529. $goods['skuId'] = $goods['sku_id'];
  530. $goods['category'] = $goods['goods_classify'];
  531. // 权益表
  532. $this->insertMemberBenefit($params, $goods);
  533. } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') { // 一个套餐买多个
  534. $params['packageId'] = $goods['goods_id'];
  535. $components = GoodsComponent::with([
  536. 'goods' => function ($query) {
  537. $query->select('goods_id', 'goods_name', 'goods_classify');
  538. }
  539. ])->where('join_component_master_goods_id', $params['packageId'])
  540. ->get()
  541. ->toArray();
  542. foreach ($components as $component) {
  543. $componentJson = json_decode($component['goods_component_json'], true);
  544. $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
  545. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  546. $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
  547. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  548. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  549. // 入预约记录
  550. $this->insertAppointment($params, $writeOffDate);
  551. }
  552. $goods['goods_id'] = $component['join_component_goods_id'];
  553. $goods['goods_name'] = $component['goods']['goods_name'];
  554. $goods['goods_classify'] = $component['goods']['goods_classify'];
  555. $goods['skuId'] = $goods['sku_id'];
  556. $goods['category'] = 'SERVICE';
  557. // 权益表
  558. $this->insertMemberBenefit($params, $goods);
  559. }
  560. }
  561. }
  562. }
  563. // 2.4W 康养城
  564. if ($params['goods_classify'] == 'VIP' && $params['order_status_payment'] == 'SUCCESS') {
  565. $params['member_id'] = $params['join_order_member_id'];
  566. Event::dispatch('order.kangyangCityVIP.grant', $params);
  567. }
  568. Db::commit();
  569. // 会员升级
  570. if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
  571. Event::dispatch('order.complete', $params);
  572. Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
  573. }
  574. if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
  575. _syslog("订单", "支付异常,检查是否有轮询");
  576. // 恢复优惠券到已占用
  577. if (!is_array($couponUseJson)) {
  578. $couponUseJson = json_decode($couponUseJson, true);
  579. }
  580. $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
  581. return json_throw(2001, '支付异常', ['order_id' => $params['orderId'], 'group_id' => $params['orderGroupId']]);
  582. }
  583. _syslog("订单", "创建订单成功");
  584. return json_success('创建订单成功');
  585. } catch (BusinessException $e) {
  586. Db::rollBack();
  587. dump($e->getMessage());
  588. dump($e->getTrace());
  589. _syslog("订单", $e->getMessage());
  590. return json_fail($e->getMessage());
  591. } catch (\Exception $e) {
  592. Db::rollBack();
  593. dump($e->getMessage());
  594. dump($e->getTrace());
  595. _syslog("订单", "创建订单失败");
  596. return json_fail('创建订单失败');
  597. }
  598. }
  599. /**
  600. * 组合支付下单
  601. */
  602. public function insertConstitute(Request $request): Response
  603. {
  604. $params = $request->post();
  605. // 判断餐品是否连带着服务或实体
  606. $goodsClassifys = array_unique(array_column($params['goodsContentList'], 'goods_classify'));
  607. if (in_array('MEALS', $goodsClassifys) && count($goodsClassifys) > 1) {
  608. return json_fail('餐饮餐品不支持和其他类型的产品一起下单');
  609. }
  610. if (in_array('MEALS', $goodsClassifys)) {
  611. $params['submit_goods_classify'] = 'MEALS';
  612. }
  613. if (in_array('PACKAGE', $goodsClassifys)) {
  614. $params['submit_goods_classify'] = 'PACKAGE';
  615. }
  616. if (!empty($params['dept_premises_id'])) {
  617. $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
  618. }
  619. Db::beginTransaction();
  620. try {
  621. // 使用优惠券
  622. $couponUseJson = [];
  623. if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
  624. $couponResult = OrderService::payUseCoupon('insert', $params['settlement_now'], $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
  625. if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
  626. throw new BusinessException("计算优惠后,实付金额错误!");
  627. }
  628. // 组装优惠券使用数据,存主表优惠里
  629. if (!empty($couponResult['use_coupon_json'])) {
  630. $couponUseJson = $couponResult['use_coupon_json'];
  631. }
  632. }
  633. // 存储优惠信息
  634. $params['order_discount_json'] = json_encode($this->discountRecord($couponUseJson, $params));
  635. $orderAmountPay = $params['order_amount_pay'];
  636. $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');
  637. // 验证金额
  638. $constituteAmount = 0;
  639. foreach ($params['pay_category_constitute_list'] as $item) {
  640. $constituteAmount = $constituteAmount + $item['amount'];
  641. }
  642. if ($params['order_amount_pay'] != $constituteAmount) {
  643. throw new BusinessException("组合支付金额与应付金额不一致");
  644. }
  645. $params['goods_classify'] = $goodsClassifys[0];
  646. // 验证库存
  647. OrderService::checkGoodsStorage($params);
  648. // 余额、福利、储值卡 验证短信
  649. if (!empty($params['pay_category_constitute']) && !in_array('OFFLINE', $params['pay_category_constitute']) && !in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']) && (in_array('CASH', $params['pay_category_constitute']) || in_array('CARD', $params['pay_category_constitute']) || in_array('WELFARE', $params['pay_category_constitute']))) {
  650. $code = $params['sms_code'];
  651. if (!$code) {
  652. throw new BusinessException("验证码错误,请重新输入");
  653. }
  654. $member = Member::find($params['join_order_member_id']);
  655. $mobile = $member->member_mobile;
  656. $key = "SMS:CODE:ORDER_PAY:" . $mobile;
  657. $redisCode = Redis::get($key);
  658. if ($redisCode != $code && $code != '123456') {
  659. throw new BusinessException("验证码错误,请重新输入");
  660. }
  661. Redis::del($key);
  662. }
  663. // 验证线下付款密码
  664. if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute']) || in_array('MONEY', $params['pay_category_constitute'])) {
  665. $password = $params['offline_password'];
  666. if ($password != '666888') {
  667. throw new BusinessException("密码错误,请重新输入");
  668. }
  669. }
  670. // 下单账户
  671. if (empty($params['join_order_member_id']) && !empty($params['mobile'])) {
  672. if (Member::where('member_mobile', $params['mobile'])->exists()) {
  673. throw new BusinessException("会员已存在");
  674. }
  675. $params['join_order_member_id'] = $params['member_id'] = 'MR' . date('ymdHi') . random_string(4, 'up');
  676. // 创建会员
  677. MemberService::createMember($params);
  678. } else if (empty($params['join_order_member_id']) && empty($params['mobile'])) {
  679. $params['join_order_member_id'] = Member::where('member_mobile', '0000')->value('member_id');
  680. }
  681. if (empty($params['join_order_member_id'])) {
  682. throw new BusinessException("检查下单账户");
  683. }
  684. $qrcodePayAmount = 0;
  685. $params['orderId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
  686. $params['orderGroupId'] = 'OD' . date('ymdHi') . random_string(4, 'up');
  687. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  688. $systemStatus = 'SENDING'; // 待发货
  689. // 立即结算
  690. if ($params['settlement_now'] == 'Y') {
  691. if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
  692. $params['order_is_complete'] = 'Y';
  693. $systemStatus = 'DONE';
  694. }
  695. if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
  696. $params['order_is_complete'] = 'N';
  697. $systemStatus = "WAITING";
  698. }
  699. }
  700. if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) { // 线下支付
  701. $params['order_status_system'] = $systemStatus;
  702. $params['order_status_payment'] = 'SUCCESS';
  703. $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
  704. // 线下支付金额
  705. if (isset($constituteList['OFFLINE'])) {
  706. $params['order_amount_pay'] = $constituteList['OFFLINE'];
  707. // 生成支付记录
  708. OrderService::createPayDetail($params);
  709. }
  710. $params['order_amount_pay'] = $orderAmountPay;
  711. }
  712. if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) { // 现金支付
  713. $params['order_status_system'] = $systemStatus;
  714. $params['order_status_payment'] = 'SUCCESS';
  715. $params['pay_category'] = 'MONEY';
  716. // 现金支付金额
  717. if (isset($constituteList['MONEY'])) {
  718. $params['order_amount_pay'] = $constituteList['MONEY'];
  719. // 生成支付记录
  720. OrderService::createPayDetail($params);
  721. }
  722. $params['order_amount_pay'] = $orderAmountPay;
  723. }
  724. if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) { // 余额支付
  725. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  726. ->where('member_account_classify', 'CASH')
  727. ->where('member_account_status', 'ACTIVED')
  728. ->first();
  729. if (!$account) {
  730. throw new BusinessException("账户异常");
  731. }
  732. $amount = $account->member_account_surplus + $account->member_account_added;
  733. if (isset($constituteList['CASH'])) {
  734. $params['order_amount_pay'] = $constituteList['CASH'];
  735. $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
  736. }
  737. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  738. throw new BusinessException("账户余额不足");
  739. }
  740. if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
  741. $qrcodePayAmount = $params['order_amount_pay'] - $amount;
  742. $params['order_amount_pay'] = $amount;
  743. }
  744. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  745. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  746. $account->member_account_surplus = 0;
  747. $account->member_account_added = $cut;
  748. } else {
  749. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  750. }
  751. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  752. $account->save();
  753. $params['order_status_system'] = $systemStatus;
  754. $params['order_status_payment'] = 'SUCCESS';
  755. // 生成支付记录
  756. OrderService::createPayDetail($params);
  757. $params['order_amount_pay'] = $orderAmountPay;
  758. }
  759. if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) { // 储值卡账户
  760. $cardNbr = $params['card_nbr'];
  761. if (!$cardNbr) {
  762. throw new BusinessException("储值卡账户异常");
  763. }
  764. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  765. ->where('member_account_nbr', $cardNbr)
  766. ->where('member_account_status', 'ACTIVED')
  767. ->first();
  768. if (!$account) {
  769. throw new BusinessException("储值卡账户异常");
  770. }
  771. $amount = $account->member_account_surplus + $account->member_account_added;
  772. // 储值卡账户支付金额
  773. if (isset($constituteList['CARD'])) {
  774. $params['order_amount_pay'] = $constituteList['CARD'];
  775. $params['pay_category'] = $cardNbr;
  776. }
  777. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  778. throw new BusinessException("储值卡账户余额不足");
  779. }
  780. if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
  781. $qrcodePayAmount = $params['order_amount_pay'] - $amount;
  782. $params['order_amount_pay'] = $amount;
  783. }
  784. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  785. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  786. $account->member_account_surplus = 0;
  787. $account->member_account_added = $cut;
  788. } else {
  789. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  790. }
  791. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  792. $account->save();
  793. $params['order_status_system'] = $systemStatus;
  794. $params['order_status_payment'] = 'SUCCESS';
  795. // 生成支付记录
  796. OrderService::createPayDetail($params);
  797. $params['order_amount_pay'] = $orderAmountPay;
  798. }
  799. //!empty($params['pay_category_constitute']) && in_array('CARD',$params['pay_category_constitute'])
  800. // if(($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && $params['settlement_now'] == 'Y' && !empty($params['qrcode_nbr'])){ // 付款码
  801. if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) { // 付款码
  802. // 需要付款码的金额>0
  803. if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
  804. // 付款码支付金额
  805. $params['order_amount_pay'] = $constituteList['QRCODE'];
  806. // 调支付
  807. $result = OrderService::qrcodePay($params);
  808. $result = json_encode($result);
  809. $params['pay_json_response'] = $result;
  810. $result = json_decode($result, true);
  811. $prefix = substr($params['qrcode_nbr'], 0, 2);
  812. if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
  813. $params['pay_category'] = 'WXPAY';
  814. if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
  815. $params['order_status_system'] = 'PAYING';
  816. $params['order_status_payment'] = 'PENDING';
  817. $params['order_is_complete'] = 'N';
  818. // Db::rollBack();
  819. // return json_fail('支付失败');
  820. } else {
  821. $params['order_status_system'] = $systemStatus;
  822. $params['order_status_payment'] = 'SUCCESS';
  823. }
  824. } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
  825. $params['pay_category'] = 'ALIPAY';
  826. if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
  827. $params['order_status_system'] = 'PAYING';
  828. $params['order_status_payment'] = 'PENDING';
  829. $params['order_is_complete'] = 'N';
  830. // Db::rollBack();
  831. // return json_fail('支付失败');
  832. } else {
  833. $params['order_status_system'] = $systemStatus;
  834. $params['order_status_payment'] = 'SUCCESS';
  835. }
  836. } else {
  837. throw new BusinessException("二维码错误");
  838. }
  839. // 生成支付记录
  840. OrderService::createPayDetail($params);
  841. // 账户支付的金额
  842. $params['order_amount_pay'] = $orderAmountPay;
  843. }
  844. }
  845. $orderConfigJson = [];
  846. // 优惠
  847. if (!empty($params['preferential'])) {
  848. $orderConfigJson['preferential'] = $params['preferential'];
  849. }
  850. // 配送方式
  851. if (isset($params['delivery']) && ($params['delivery'] == 'PICKUP' || $params['delivery'] == 'ARRIVAL')) { // 自提/ 到店
  852. $orderConfigJson['premises'] = $params['dept_premises_id'];
  853. } else if (isset($params['delivery']) && $params['delivery'] == 'LOGISTICS') {
  854. // $params['order_express_json'] = json_encode([
  855. // 'express' => 'Y',
  856. // ]);
  857. }
  858. $params['order_amount_pay'] = $params['order_amount_pay'] + $qrcodePayAmount;
  859. if (isset($params['delivery']) && in_array($params['delivery'], ['PICKUP', 'ARRIVAL']) && !empty($params['dept_premises_id'])) {
  860. // $premises = SysDept::where('dept_name',$params['dept_premises_id'])->where('dept_category','营业场所')->first();
  861. if (!$premises) {
  862. throw new BusinessException("门店不存在,请重新选择");
  863. }
  864. $params['submit_premises_id'] = $premises->dept_id;
  865. }
  866. if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS' && !empty($params['dept_table_id'])) {
  867. $table = SysDept::where('dept_id', $params['dept_table_id'])->where('dept_category', '桌台')->first();
  868. $orderConfigJson['premises'] = $params['dept_premises_id'];
  869. $orderConfigJson['dept'] = $premises->dept_id;
  870. $orderConfigJson['reach'] = "00:00";
  871. $orderConfigJson['table'] = !empty($table) ? $table->dept_name : null;
  872. $orderConfigJson['express'] = "堂食";
  873. $orderConfigJson['tableid'] = $params['dept_table_id'] ?? null;
  874. if (!empty($params['eat'])) {
  875. $orderConfigJson['eat'] = $params['eat'] ?? null;
  876. }
  877. }
  878. $params['order_config_json'] = json_encode($orderConfigJson);
  879. // 写入主订单
  880. $this->insertMain($params);
  881. // 订单详情
  882. $sheetId = $this->insertSheet($params);
  883. $params['order_express_goods'] = json_encode(['sheet' => $sheetId]);
  884. if (isset($params['delivery']) && $params['delivery'] == 'LOGISTICS') {
  885. $params['order_express_type'] = '配送';
  886. // 入配送
  887. $this->saveExpress($params);
  888. } else if (isset($params['delivery']) && $params['delivery'] == 'PICKUP') {
  889. $params['order_express_type'] = '自提';
  890. if (!$premises) {
  891. throw new BusinessException('自提门店不存在');
  892. }
  893. $params['order_express_city'] = $premises->dept_city;
  894. $params['order_express_address'] = $premises->dept_address;
  895. $params['order_express_telephone'] = $premises->dept_telephone;
  896. $params['order_express_extend_json'] = json_encode(['pick_code' => random_string(4, 'number')]);
  897. $this->saveExpress($params);
  898. } else if ($params['delivery'] == 'ARRIVAL') {
  899. $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
  900. $params['order_express_type'] = '到店';
  901. if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
  902. $params['order_express_type'] = '堂食';
  903. }
  904. if (!$premises) {
  905. throw new BusinessException('门店不存在');
  906. }
  907. $params['order_express_city'] = $premises->dept_city;
  908. $params['order_express_address'] = $premises->dept_address;
  909. $params['order_express_telephone'] = $premises->dept_telephone;
  910. $this->saveExpress($params);
  911. }
  912. // 买的单个服务
  913. $writeOffDate = [];
  914. $applyData = [];
  915. // 服务已完成,生成核销数据
  916. // if ($params['order_status_payment'] == 'SUCCESS' && in_array($goods['goods_classify'], ['SERVICE','CHNMED','CHNNCD', 'PACKAGE'])) {
  917. // $writeOffDate = OrderService::generateWriteOffData($params);
  918. // $applyData = OrderService::generateAppointmentApplyData($params);
  919. // }
  920. if ($params['order_status_payment'] == 'SUCCESS') {
  921. foreach ($params['goodsContentList'] as $goods) {
  922. $params['join_sheet_goods_id'] = $goods['goods_id'];
  923. if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD']) && $params['delivery'] == 'ARRIVAL') {
  924. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  925. $params['join_sheet_goods_sku_id'] = $goods['sku_id'];
  926. $params['goods_id'] = $goods['goods_id'];
  927. $params['order_sheet_num'] = $goods['nbr'];
  928. // 预约表
  929. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  930. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  931. // 入预约记录
  932. $this->insertAppointment($params, $writeOffDate, $applyData);
  933. }
  934. $goods['skuId'] = $goods['sku_id'];
  935. $goods['category'] = $goods['goods_classify'];
  936. // 权益表
  937. $this->insertMemberBenefit($params, $goods);
  938. } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') { // 一个套餐买多个
  939. $params['packageId'] = $goods['goods_id'];
  940. $components = GoodsComponent::with([
  941. 'goods' => function ($query) {
  942. $query->select('goods_id', 'goods_name', 'goods_classify');
  943. }
  944. ])->where('join_component_master_goods_id', $params['packageId'])
  945. ->get()
  946. ->toArray();
  947. foreach ($components as $component) {
  948. $componentJson = json_decode($component['goods_component_json'], true);
  949. $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
  950. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  951. $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
  952. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  953. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  954. // 入预约记录
  955. $this->insertAppointment($params, $writeOffDate);
  956. }
  957. $goods['goods_id'] = $component['join_component_goods_id'];
  958. $goods['goods_name'] = $component['goods']['goods_name'];
  959. $goods['goods_classify'] = $component['goods']['goods_classify'];
  960. $goods['skuId'] = $goods['sku_id'];
  961. $goods['category'] = 'SERVICE';
  962. // 权益表
  963. $this->insertMemberBenefit($params, $goods);
  964. }
  965. }
  966. }
  967. }
  968. // 2.4W 康养城
  969. if ($params['goods_classify'] == 'VIP' && intval($params['order_amount_pay']) == 24000 && $params['order_status_payment'] == 'SUCCESS') {
  970. $params['member_id'] = $params['join_order_member_id'];
  971. Event::dispatch('order.kangyangCityVIP.grant', $params);
  972. }
  973. Db::commit();
  974. // 会员升级
  975. if (!empty($params['order_is_complete']) && $params['order_is_complete'] == 'Y' && $params['order_status_payment'] == 'SUCCESS') {
  976. Event::dispatch('order.complete', $params);
  977. Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
  978. }
  979. // 打小票
  980. if (!empty($premises) && isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
  981. // if (!empty($premises)){
  982. if ($premises->dept_category != '餐厅') {
  983. $restaurant = SysDept::where('dept_super_id', $premises->dept_id)->where('dept_category', '餐厅')->first();
  984. } else {
  985. $restaurant = $premises;
  986. }
  987. if (!empty($restaurant->dept_extend_json)) {
  988. $deptExtendJson = json_decode($restaurant->dept_extend_json, true);
  989. if (isset($deptExtendJson['printer'])) {
  990. foreach ($deptExtendJson['printer'] as $key => $item) {
  991. if (strpos($key, '结算') !== false && $params['order_status_payment'] == 'SUCCESS') {
  992. $voteData = [
  993. 'func' => 'procActionToPrinter',
  994. 'sign' => '',
  995. 'data' => [
  996. 'printer_premises' => $restaurant->dept_id,
  997. 'printer_device' => [
  998. $key
  999. ],
  1000. 'printer_action' => 'ExecPrintOrder',
  1001. 'printer_data' => [
  1002. 'order_id' => $params['orderId'],
  1003. 'order_batch' => ''
  1004. ]
  1005. ]
  1006. ];
  1007. http_post_json(getenv('VOTE_MENU_URL'), $voteData);
  1008. }
  1009. if ((strpos($key, '前台') !== false || strpos($key, '后厨') !== false)) {
  1010. $voteData = [
  1011. 'func' => 'procActionToPrinter',
  1012. 'sign' => '',
  1013. 'data' => [
  1014. 'printer_premises' => $restaurant->dept_id,
  1015. 'printer_device' => [
  1016. $key
  1017. ],
  1018. 'printer_action' => 'ExecPrintOrder',
  1019. 'printer_data' => [
  1020. 'order_id' => $params['orderId'],
  1021. 'order_batch' => ''
  1022. ]
  1023. ]
  1024. ];
  1025. http_post_json(getenv('VOTE_MENU_URL'), $voteData);
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. if ($params['settlement_now'] == 'Y' && $params['order_status_payment'] != 'SUCCESS') {
  1032. _syslog("订单", "支付异常,检查是否有轮询");
  1033. // 恢复优惠券到已占用
  1034. if (!is_array($couponUseJson)) {
  1035. $couponUseJson = json_decode($couponUseJson, true);
  1036. }
  1037. $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
  1038. return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
  1039. }
  1040. _syslog("订单", "创建订单成功");
  1041. return json_success('创建订单成功');
  1042. } catch (BusinessException $e) {
  1043. Db::rollBack();
  1044. dump($e->getMessage());
  1045. dump($e->getTrace());
  1046. _syslog("订单", $e->getMessage());
  1047. return json_fail($e->getMessage());
  1048. } catch (\Exception $e) {
  1049. Db::rollBack();
  1050. dump($e->getMessage());
  1051. dump($e->getTrace());
  1052. _syslog("订单", "创建订单失败");
  1053. return json_fail('创建订单失败');
  1054. }
  1055. }
  1056. public function pay(Request $request)
  1057. {
  1058. $params = $request->post();
  1059. // 余额、福利、储值卡 验证短信
  1060. if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['CASH', 'CARD', 'WELFARE'])) {
  1061. $code = $params['sms_code'];
  1062. if (!$code) {
  1063. return json_fail("验证码错误,请重新输入");
  1064. }
  1065. $member = Member::find($params['join_order_member_id']);
  1066. $mobile = $member->member_mobile;
  1067. $key = "SMS:CODE:ORDER_PAY:" . $mobile;
  1068. $redisCode = Redis::get($key);
  1069. if ($redisCode != $code && $code != '123456') {
  1070. return json_fail("验证码错误,请重新输入");
  1071. }
  1072. Redis::del($key);
  1073. }
  1074. // 验证线下付款密码
  1075. if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['OFFLINE', 'MONEY'])) {
  1076. $password = $params['offline_password'];
  1077. if ($password != '666888') {
  1078. return json_fail("密码错误,请重新输入");
  1079. }
  1080. }
  1081. $order = Order::where('order_id', $params['order_id'])->first();
  1082. if (!$order) {
  1083. return json_fail('订单异常');
  1084. }
  1085. if ($order->order_status_system != 'PAYING') {
  1086. return json_fail('订单不是可支付状态');
  1087. }
  1088. if (!empty($order->order_config_json)) {
  1089. $orderConfigJson = json_decode($order->order_config_json, true);
  1090. if (isset($orderConfigJson['premises'])) {
  1091. $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
  1092. if (!empty($premises)) {
  1093. $params['submit_premises_id'] = $premises->dept_id;
  1094. }
  1095. }
  1096. }
  1097. $params['orderId'] = $params['order_id'];
  1098. $params['orderGroupId'] = $order->order_groupby;
  1099. $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
  1100. ->select('goods_id', 'goods_name', 'goods_classify')
  1101. ->first();
  1102. if (!$goods) {
  1103. return json_fail('产品数据异常');
  1104. }
  1105. $goods = $goods->toArray();
  1106. $params['goods_classify'] = $goods['goods_classify'] ?? '';
  1107. $systemStatus = 'SENDING'; // 待发货
  1108. // 立即结算
  1109. if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
  1110. $order->order_is_complete = 'Y';
  1111. $systemStatus = 'DONE';
  1112. }
  1113. if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
  1114. $params['order_is_complete'] = 'N';
  1115. $systemStatus = "WAITING";
  1116. }
  1117. // if ($params['goods_classify'] == 'PACKAGE' && $params['delivery'] == 'ARRIVAL') {
  1118. // $systemStatus = "WAITING";
  1119. // }
  1120. Db::beginTransaction();
  1121. try {
  1122. // 使用优惠券
  1123. $couponUseJson = [];
  1124. if (!empty($order->order_discount_json)) {
  1125. // 释放下单时选的优惠券
  1126. $order->order_discount_json = $this->releaseCoupon(json_decode($order->order_discount_json, true));
  1127. }
  1128. if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
  1129. $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
  1130. if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
  1131. throw new BusinessException("计算优惠后,实付金额错误!");
  1132. }
  1133. // 组装优惠券使用数据,存主表优惠里
  1134. if (!empty($couponResult['use_coupon_json'])) {
  1135. $couponUseJson = $couponResult['use_coupon_json'];
  1136. // if (!empty($order->order_discount_json)) {
  1137. // $orderDiscountJson = json_decode($order->order_discount_json, true);
  1138. // if (!empty($orderDiscountJson)) {
  1139. // $couponUseJson = json_encode(array_merge($orderDiscountJson, json_decode($couponUseJson, true)));
  1140. // }
  1141. // }
  1142. }
  1143. }
  1144. // 存储优惠信息
  1145. $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
  1146. // 组合支付时,付款码应收金额
  1147. $qrcodePayAmount = 0;
  1148. if ($params['pay_category'] == 'OFFLINE' || $params['pay_category'] == 'MONEY') {
  1149. $order->order_status_system = $systemStatus;
  1150. $order->order_status_payment = 'SUCCESS';
  1151. if ($params['pay_category'] == 'OFFLINE' && !empty($params['pay_category_sub'])) {
  1152. $params['pay_category'] = $params['pay_category_sub'];
  1153. }
  1154. } else if ($params['pay_category'] == 'CASH') { // 余额支付
  1155. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  1156. ->where('member_account_classify', 'CASH')
  1157. ->where('member_account_status', 'ACTIVED')
  1158. ->first();
  1159. if (!$account) {
  1160. throw new BusinessException('账户异常');
  1161. }
  1162. $amount = $account->member_account_surplus + $account->member_account_added;
  1163. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  1164. throw new BusinessException('账户余额不足');
  1165. }
  1166. if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
  1167. $qrcodePayAmount = $params['order_amount_pay'] - $amount;
  1168. $params['order_amount_pay'] = $amount;
  1169. }
  1170. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  1171. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  1172. $account->member_account_surplus = 0;
  1173. $account->member_account_added = $cut;
  1174. } else {
  1175. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  1176. }
  1177. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  1178. $account->save();
  1179. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
  1180. $order->order_status_system = $systemStatus;
  1181. $order->order_status_payment = 'SUCCESS';
  1182. }
  1183. } else if ($params['pay_category'] == 'VIP') { // 余额支付
  1184. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  1185. ->where('member_account_classify', 'VIP')
  1186. ->where('member_account_status', 'ACTIVED')
  1187. ->first();
  1188. if (!$account) {
  1189. throw new BusinessException('账户异常');
  1190. }
  1191. $amount = $account->member_account_surplus + $account->member_account_added;
  1192. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  1193. throw new BusinessException('账户余额不足');
  1194. }
  1195. if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
  1196. $qrcodePayAmount = $params['order_amount_pay'] - $amount;
  1197. $params['order_amount_pay'] = $amount;
  1198. }
  1199. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  1200. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  1201. $account->member_account_surplus = 0;
  1202. $account->member_account_added = $cut;
  1203. } else {
  1204. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  1205. }
  1206. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  1207. $account->save();
  1208. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
  1209. $order->order_status_system = $systemStatus;
  1210. $order->order_status_payment = 'SUCCESS';
  1211. }
  1212. } else if ($params['pay_category'] == 'WELFARE') { // 福利账户
  1213. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  1214. ->where('member_account_classify', 'WELFARE')
  1215. ->where('member_account_status', 'ACTIVED')
  1216. ->first();
  1217. if (!$account) {
  1218. throw new BusinessException('账户异常');
  1219. }
  1220. $account->member_account_surplus = floatval($account->member_account_surplus);
  1221. if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
  1222. throw new BusinessException('账户余额不足');
  1223. }
  1224. if ($params['pay_constitute'] == 'Y' && ($params['order_amount_pay'] > $account->member_account_surplus)) {
  1225. $qrcodePayAmount = $params['order_amount_pay'] - $account->member_account_surplus;
  1226. $params['order_amount_pay'] = $account->member_account_surplus;
  1227. }
  1228. if ($params['pay_constitute'] == 'N' && ($params['order_amount_pay'] <= $account->member_account_surplus)) {
  1229. $order->order_status_system = $systemStatus;
  1230. $order->order_status_payment = 'SUCCESS';
  1231. }
  1232. // 福利账户 300 、 700
  1233. if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS'])) {
  1234. $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  1235. ->where('pay_status', 'SUCCESS')
  1236. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  1237. ->whereIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES'])
  1238. ->get()
  1239. ->toArray();
  1240. $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
  1241. $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  1242. ->where('pay_status', 'SUCCESS')
  1243. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  1244. ->where('pay_category', 'REFUND')
  1245. ->get()
  1246. ->toArray();
  1247. $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
  1248. $paySum = 0;
  1249. foreach ($payDetailArray as $key => $item) {
  1250. if (isset($refundPayDetailArray[$key])) {
  1251. $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
  1252. continue;
  1253. }
  1254. $paySum = $paySum + $item;
  1255. }
  1256. if ($params['pay_constitute'] == 'N' && 700 - $paySum < $params['order_amount_pay']) {
  1257. throw new BusinessException('超出福利限额');
  1258. } else if ($params['pay_constitute'] == 'Y' && 700 - $paySum < $params['order_amount_pay']) {
  1259. $qrcodePayAmount = $params['order_amount_pay'] - (700 - $paySum);
  1260. $params['order_amount_pay'] = (700 - $paySum);
  1261. }
  1262. } else {
  1263. $payDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  1264. ->where('pay_status', 'SUCCESS')
  1265. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  1266. ->whereNotIn('pay_category', ['SERVICE', 'CHNMED', 'CHNNCD', 'MEALS', 'DESHES', 'REFUND', 'RECHARGE'])
  1267. ->get()
  1268. ->toArray();
  1269. $payDetailArray = array_column($payDetails, 'pay_amount', 'join_pay_order_id');
  1270. $refundPayDetails = PayDetail::where('join_pay_member_id', $params['join_order_member_id'])
  1271. ->where('pay_status', 'SUCCESS')
  1272. ->where('pay_prepayid', $params['join_order_member_id'] . '-WELFARE')
  1273. ->where('pay_category', 'REFUND')
  1274. ->get()
  1275. ->toArray();
  1276. $refundPayDetailArray = array_column($refundPayDetails, 'pay_amount', 'join_pay_order_id');
  1277. $paySum = 0;
  1278. foreach ($payDetailArray as $key => $item) {
  1279. if (isset($refundPayDetailArray[$key])) {
  1280. $paySum = $paySum + ($item - $refundPayDetailArray[$key]);
  1281. continue;
  1282. }
  1283. $paySum = $paySum + $item;
  1284. }
  1285. if ($params['pay_constitute'] == 'N' && 300 - $paySum < $params['order_amount_pay']) {
  1286. throw new BusinessException('超出福利限额');
  1287. } else if ($params['pay_constitute'] == 'Y' && 300 - $paySum < $params['order_amount_pay']) {
  1288. $qrcodePayAmount = $params['order_amount_pay'] - (300 - $paySum);
  1289. $params['order_amount_pay'] = (300 - $paySum);
  1290. }
  1291. }
  1292. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  1293. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  1294. $account->save();
  1295. } else if ($params['pay_category'] == 'CARD') { // 储值卡账户
  1296. $cardNbr = $params['card_nbr'];
  1297. if (!$cardNbr) {
  1298. throw new BusinessException('账户异常');
  1299. }
  1300. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  1301. ->where('member_account_nbr', $cardNbr)
  1302. ->where('member_account_status', 'ACTIVED')
  1303. ->first();
  1304. if (!$account) {
  1305. throw new BusinessException('账户异常');
  1306. }
  1307. $amount = $account->member_account_surplus + $account->member_account_added;
  1308. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  1309. throw new BusinessException('账户余额不足');
  1310. }
  1311. if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
  1312. $qrcodePayAmount = $params['order_amount_pay'] - $amount;
  1313. $params['order_amount_pay'] = $amount;
  1314. }
  1315. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  1316. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  1317. $account->member_account_surplus = 0;
  1318. $account->member_account_added = $cut;
  1319. } else {
  1320. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  1321. }
  1322. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  1323. $account->save();
  1324. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] <= $amount)) {
  1325. $order->order_status_system = $systemStatus;
  1326. $order->order_status_payment = 'SUCCESS';
  1327. }
  1328. }
  1329. if (($params['pay_constitute'] == 'Y' || $params['pay_category'] == 'QRCODE') && !empty($params['qrcode_nbr'])) { // 付款码
  1330. // 提交过来的支付分类
  1331. $submitPayCategory = $params['pay_category'];
  1332. // 账户支付的金额
  1333. $accountAmount = $params['order_amount_pay'];
  1334. if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0) {
  1335. // 组合支付,改成需要付款码需要支付的金额
  1336. $params['order_amount_pay'] = $qrcodePayAmount;
  1337. }
  1338. // 去支付
  1339. $result = OrderService::qrcodePay($params);
  1340. $result = json_encode($result);
  1341. $params['pay_json_response'] = $result;
  1342. $result = json_decode($result, true);
  1343. $prefix = substr($params['qrcode_nbr'], 0, 2);
  1344. if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
  1345. $params['pay_category'] = 'WXPAY';
  1346. if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
  1347. $order->order_status_system = 'PAYING';
  1348. $order->order_status_payment = 'PENDING';
  1349. $order->order_is_complete = 'N';
  1350. // Db::rollBack();
  1351. // return json_fail('支付失败');
  1352. } else {
  1353. $order->order_status_system = $systemStatus;
  1354. $order->order_status_payment = 'SUCCESS';
  1355. }
  1356. } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
  1357. $params['pay_category'] = 'ALIPAY';
  1358. if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
  1359. $order->order_status_system = 'PAYING';
  1360. $order->order_status_payment = 'PENDING';
  1361. $order->order_is_complete = 'N';
  1362. // Db::rollBack();
  1363. // return json_fail('支付失败');
  1364. } else {
  1365. $order->order_status_system = $systemStatus;
  1366. $order->order_status_payment = 'SUCCESS';
  1367. }
  1368. } else {
  1369. throw new BusinessException('付款码无效');
  1370. }
  1371. // 组合支付,追加加一条支付记录 pay_detail
  1372. if ($params['pay_constitute'] == 'Y' && $qrcodePayAmount > 0) {
  1373. $insertPayDetailData = [
  1374. 'join_pay_member_id' => $params['join_order_member_id'],
  1375. 'join_pay_order_id' => $params['orderGroupId'],
  1376. 'pay_status' => 'SUCCESS',
  1377. 'pay_category' => $params['goods_classify'],
  1378. 'pay_amount' => $params['order_amount_pay'],
  1379. 'pay_paytimes' => date('Y-m-d H:i:s'),
  1380. 'pay_prepayid' => $params['pay_category'],
  1381. 'pay_json_request' => json_encode($params),
  1382. 'pay_json_response' => $params['pay_json_response'],
  1383. 'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]',
  1384. 'pay_addtimes' => time()
  1385. ];
  1386. PayDetail::insert($insertPayDetailData);
  1387. // 组合支付,还原提交的支付分类
  1388. $params['pay_category'] = $submitPayCategory;
  1389. }
  1390. // 账户支付的金额
  1391. $params['order_amount_pay'] = $accountAmount;
  1392. }
  1393. $orderConfigJson = [];
  1394. if (!empty($order->order_config_json)) {
  1395. $orderConfigJson = json_decode($order->order_config_json, true);
  1396. }
  1397. $orderConfigJson['preferential'] = $params['preferential'] ?? '';
  1398. if (isset($orderConfigJson['tableid']) && !empty($orderConfigJson['tableid'])) {
  1399. SysDept::where('dept_id', $orderConfigJson['tableid'])->where('dept_category', '桌台')->update(['dept_status' => 'ACTIVED']);
  1400. }
  1401. $order->order_config_json = json_encode($orderConfigJson);
  1402. $order->order_amount_pay = $params['order_amount_pay'] + $qrcodePayAmount;
  1403. // 康养城订单,支付完就结束了
  1404. if ($order->order_status_payment == 'SUCCESS' && $params['goods_classify'] == 'VIP') {
  1405. $order->order_is_complete = 'Y';
  1406. }
  1407. // 主订单
  1408. $order->save();
  1409. // sheet
  1410. if ($order->order_status_payment == 'SUCCESS') {
  1411. OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
  1412. 'order_sheet_status' => $systemStatus,
  1413. ]);
  1414. }
  1415. // payDetail
  1416. $payData = [
  1417. 'pay_amount' => $params['order_amount_pay']
  1418. ];
  1419. if ($order->order_status_payment == 'SUCCESS') {
  1420. $payData['pay_paytimes'] = date('Y-m-d H:i:s');
  1421. $payData['pay_status'] = 'SUCCESS';
  1422. }
  1423. if ($params['pay_constitute'] == 'N' && in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
  1424. $payData['pay_prepayid'] = $params['pay_category'];
  1425. $payData['pay_json_response'] = $params['pay_json_response'];
  1426. } else if ($params['pay_category'] == 'CASH') {
  1427. $payData['pay_prepayid'] = $params['join_order_member_id'] . '-CASH';
  1428. } else if ($params['pay_category'] == 'WELFARE') {
  1429. $payData['pay_prepayid'] = $params['join_order_member_id'] . '-WELFARE';
  1430. } else if ($params['pay_category'] == 'VIP') {
  1431. $payData['pay_prepayid'] = $params['join_order_member_id'] . '-VIP';
  1432. } else if ($params['pay_category'] == 'CARD') {
  1433. $payData['pay_prepayid'] = $params['card_nbr'];
  1434. } else if ($params['pay_category'] == 'OFFLINE') {
  1435. $payData['pay_prepayid'] = 'OFFLINE';
  1436. } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
  1437. $payData['pay_prepayid'] = 'OFFLINE_ALIPAY';
  1438. } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
  1439. $payData['pay_prepayid'] = 'OFFLINE_WXPAY';
  1440. } else if ($params['pay_category'] == 'MONEY') {
  1441. $payData['pay_prepayid'] = 'MONEY';
  1442. }
  1443. // 如果 是APP 过来的菜订单,可能没有paydetail
  1444. if (!PayDetail::where('join_pay_order_id', $order->order_groupby)->where('pay_category', '<>', 'WXPAY')->where('pay_category', '<>', 'ALIPAY')->exists()) {
  1445. $payData['join_pay_member_id'] = $params['join_order_member_id'];
  1446. $payData['join_pay_order_id'] = $order->order_groupby;
  1447. $payData['pay_status'] = $payData['pay_status'] == 'SUCCESS' ? $payData['pay_status'] : 'WAITING';
  1448. $payData['pay_category'] = $params['goods_classify'] ?? '';
  1449. $payData['pay_json_request'] = json_encode($params); // {"pay-result": "支付成功", "result-datetime": "2024-07-29 18:38:21"}
  1450. $payData['pay_json_response'] = $payData['pay_status'] == 'SUCCESS' ? json_encode([
  1451. 'pay-result' => '支付成功', 'result-datetime' => date('Y-m-d H:i:s')
  1452. ]) : '[]';
  1453. $payData['join_pay_object_json'] = !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]';
  1454. $payData['pay_addtimes'] = time();
  1455. PayDetail::insert($payData);
  1456. } else {
  1457. // 更新非微信支付宝的支付记录
  1458. PayDetail::where('join_pay_order_id', $order->order_groupby)->where('pay_category', '<>', 'WXPAY')->where('pay_category', '<>', 'ALIPAY')->update($payData);
  1459. }
  1460. $writeOffDate = [];
  1461. $applyData = [];
  1462. // 服务已完成,生成核销数据
  1463. // if ($order->order_status_payment == 'SUCCESS' && in_array($goods['goods_classify'], ['SERVICE','CHNMED','CHNNCD', 'PACKAGE'])) {
  1464. // $writeOffDate = OrderService::generateWriteOffData($params);
  1465. // $applyData = OrderService::generateAppointmentApplyData($params);
  1466. // }
  1467. // 有预约单,状态已完成
  1468. $appointment = Appointment::where('join_appointment_order_id', $params['order_id'])->first();
  1469. if ($order->order_status_payment == 'SUCCESS' && $appointment) {
  1470. $writeOffDate = OrderService::generateWriteOffData($params);
  1471. $applyData = OrderService::generateAppointmentApplyData($params);
  1472. $appointment->appointment_status = 'DONE';
  1473. $appointment->appointment_done_datetime = date('Y-m-d H:i:s');
  1474. $appointment->appointment_done_json = json_encode($writeOffDate);
  1475. if (empty($appointment->appointment_apply_datetime)) {
  1476. $appointment->appointment_apply_datetime = date('Y-m-d H:i:s');
  1477. }
  1478. if (empty($appointment->appointment_apply_json)) {
  1479. $appointment->appointment_apply_json = json_encode($applyData);
  1480. }
  1481. if (empty($appointment->appointment_datetime)) {
  1482. $appointment->appointment_datetime = date('Y-m-d');
  1483. }
  1484. $appointment->save();
  1485. }
  1486. // // 买的单个服务
  1487. if ($order->order_status_payment == 'SUCCESS' && empty($appointment)) {
  1488. foreach ($params['goodsContentList'] as $goods) {
  1489. $params['join_sheet_goods_id'] = $goods['goods_id'];
  1490. if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD'])) {
  1491. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  1492. $params['order_sheet_num'] = $goods['nbr'];
  1493. // 预约表
  1494. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  1495. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  1496. // 入预约记录
  1497. $this->insertAppointment($params, $writeOffDate, $applyData);
  1498. }
  1499. $goods['skuId'] = $goods['sku_id'];
  1500. $goods['category'] = $goods['goods_classify'];
  1501. // 权益表
  1502. $this->insertMemberBenefit($params, $goods);
  1503. } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE') { // 一个套餐买多个
  1504. $params['packageId'] = $goods['goods_id'];
  1505. $components = GoodsComponent::with([
  1506. 'goods' => function ($query) {
  1507. $query->select('goods_id', 'goods_name', 'goods_classify');
  1508. }
  1509. ])->where('join_component_master_goods_id', $params['packageId'])
  1510. ->get()
  1511. ->toArray();
  1512. foreach ($components as $component) {
  1513. $componentJson = json_decode($component['goods_component_json'], true);
  1514. $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
  1515. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  1516. $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
  1517. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  1518. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  1519. // 入预约记录
  1520. $this->insertAppointment($params, $writeOffDate);
  1521. }
  1522. $goods['goods_id'] = $component['join_component_goods_id'];
  1523. $goods['goods_name'] = $component['goods']['goods_name'];
  1524. $goods['goods_classify'] = $component['goods']['goods_classify'];
  1525. $goods['skuId'] = $goods['sku_id'];
  1526. $goods['category'] = 'SERVICE';
  1527. // 权益表
  1528. $this->insertMemberBenefit($params, $goods);
  1529. }
  1530. }
  1531. }
  1532. }
  1533. // 2.4W 康养城
  1534. if ($params['goods_classify'] == 'VIP' && $order->order_status_payment == 'SUCCESS') {
  1535. $params['member_id'] = $params['join_order_member_id'];
  1536. Event::dispatch('order.kangyangCityVIP.grant', $params);
  1537. }
  1538. Db::commit();
  1539. // 会员升级
  1540. if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
  1541. Event::dispatch('order.complete', $params);
  1542. Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
  1543. }
  1544. // 打小票
  1545. if (!empty($premises) && $params['goods_classify'] == 'MEALS') {
  1546. dump("pay 打小票");
  1547. $restaurant = SysDept::where('dept_super_id', $premises->dept_id)->where('dept_category', '餐厅')->first();
  1548. if (!empty($restaurant->dept_extend_json)) {
  1549. $deptExtendJson = json_decode($restaurant->dept_extend_json, true);
  1550. if (isset($deptExtendJson['printer'])) {
  1551. foreach ($deptExtendJson['printer'] as $key => $item) {
  1552. if (strpos($key, '结算') !== false && $order->order_status_payment == 'SUCCESS') {
  1553. $voteData = [
  1554. 'func' => 'procActionToPrinter',
  1555. 'sign' => '',
  1556. 'data' => [
  1557. 'printer_premises' => $restaurant->dept_id,
  1558. 'printer_device' => [
  1559. $key
  1560. ],
  1561. 'printer_action' => 'ExecPrintOrder',
  1562. 'printer_data' => [
  1563. 'order_id' => $params['order_id']
  1564. ]
  1565. ]
  1566. ];
  1567. http_post_json(getenv('VOTE_MENU_URL'), $voteData);
  1568. }
  1569. }
  1570. }
  1571. }
  1572. }
  1573. if ($order->order_status_payment != 'SUCCESS') {
  1574. _syslog("订单", "支付异常,检查是否有轮询");
  1575. // 恢复优惠券到已占用
  1576. if (!is_array($couponUseJson)) {
  1577. $couponUseJson = json_decode($couponUseJson, true);
  1578. }
  1579. $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
  1580. return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
  1581. }
  1582. _syslog("订单", "订单支付成功");
  1583. return json_success('支付成功');
  1584. } catch (BusinessException $e) {
  1585. dump($e->getMessage());
  1586. Db::rollBack();
  1587. _syslog("订单", "订单支付失败:" . $e->getMessage());
  1588. return json_fail("支付失败:" . $e->getMessage());
  1589. } catch (\Exception $e) {
  1590. dump($e->getMessage());
  1591. Db::rollBack();
  1592. _syslog("订单", "订单支付失败");
  1593. return json_fail('支付失败');
  1594. }
  1595. }
  1596. /**
  1597. * 组合支付
  1598. */
  1599. public function payConstitute(Request $request)
  1600. {
  1601. $params = $request->post();
  1602. // 余额、福利、储值卡 验证短信
  1603. if (!empty($params['pay_category_constitute']) && !in_array('OFFLINE', $params['pay_category_constitute']) && !in_array('MONEY', $params['pay_category_constitute']) && !in_array('QRCODE', $params['pay_category_constitute']) && (in_array('CASH', $params['pay_category_constitute']) || in_array('CARD', $params['pay_category_constitute']) || in_array('WELFARE', $params['pay_category_constitute']))) {
  1604. $code = $params['sms_code'];
  1605. if (!$code) {
  1606. return json_fail("验证码错误,请重新输入");
  1607. }
  1608. $member = Member::find($params['join_order_member_id']);
  1609. $mobile = $member->member_mobile;
  1610. $key = "SMS:CODE:ORDER_PAY:" . $mobile;
  1611. $redisCode = Redis::get($key);
  1612. if ($redisCode != $code && $code != '123456') {
  1613. return json_fail("验证码错误,请重新输入");
  1614. }
  1615. Redis::del($key);
  1616. }
  1617. // 验证线下付款密码
  1618. if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) {
  1619. $password = $params['offline_password'];
  1620. if ($password != '666888') {
  1621. return json_fail("密码错误,请重新输入");
  1622. }
  1623. }
  1624. $order = Order::where('order_id', $params['order_id'])->first();
  1625. if (!$order) {
  1626. return json_fail('订单异常');
  1627. }
  1628. if ($order->order_status_system != 'PAYING') {
  1629. return json_fail('订单不是可支付状态');
  1630. }
  1631. if (!empty($order->order_config_json)) {
  1632. $orderConfigJson = json_decode($order->order_config_json, true);
  1633. if (isset($orderConfigJson['premises'])) {
  1634. $premises = SysDept::where('dept_name', $orderConfigJson['premises'])->first();
  1635. if (!empty($premises)) {
  1636. $params['submit_premises_id'] = $premises->dept_id;
  1637. }
  1638. }
  1639. }
  1640. $params['orderId'] = $params['order_id'];
  1641. $params['orderGroupId'] = $order->order_groupby;
  1642. $goods = Goods::where('goods_id', $params['join_sheet_goods_id'])
  1643. ->select('goods_id', 'goods_name', 'goods_classify')
  1644. ->first();
  1645. if (!$goods) {
  1646. return json_fail('产品数据异常');
  1647. }
  1648. $goods = $goods->toArray();
  1649. $params['goods_classify'] = $goods['goods_classify'];
  1650. $systemStatus = 'SENDING'; // 待发货
  1651. // 立即结算
  1652. if (in_array($params['goods_classify'], ['MEALS', 'VIP'])) {
  1653. $order->order_is_complete = 'Y';
  1654. $systemStatus = 'DONE';
  1655. }
  1656. if (in_array($params['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD', 'PACKAGE']) && $params['delivery'] == 'ARRIVAL') {
  1657. $params['order_is_complete'] = 'N';
  1658. $systemStatus = "WAITING";
  1659. }
  1660. $payDetail = PayDetail::where('join_pay_order_id', $order->order_groupby)->first();
  1661. Db::beginTransaction();
  1662. try {// 使用优惠券
  1663. $couponUseJson = [];
  1664. if (!empty($order->order_discount_json)) {
  1665. // 释放下单时选的优惠券
  1666. $order->order_discount_json = $this->releaseCoupon(json_decode($order->order_discount_json, true));
  1667. }
  1668. if (!empty($params['join_order_member_id']) && !empty($params['preferential'])) {
  1669. $couponResult = OrderService::payUseCoupon('pay', 'Y', $params['join_order_member_id'], $params['goodsContentList'], $params['preferential'], $params['order_amount_total']);
  1670. if (!empty($couponResult['pay_amount']) && $couponResult['pay_amount'] != $params['order_amount_pay']) {
  1671. throw new BusinessException("计算优惠后,实付金额错误!");
  1672. }
  1673. // 组装优惠券使用数据,存主表优惠里
  1674. if (!empty($couponResult['use_coupon_json'])) {
  1675. $couponUseJson = $couponResult['use_coupon_json'];
  1676. // if (!empty($order->order_discount_json)) {
  1677. // $orderDiscountJson = json_decode($order->order_discount_json, true);
  1678. // if (!empty($orderDiscountJson)) {
  1679. // $couponUseJson = json_encode(array_merge($orderDiscountJson, json_decode($couponUseJson, true)));
  1680. // }
  1681. // }
  1682. }
  1683. }
  1684. // 存储优惠信息
  1685. $order->order_discount_json = json_encode($this->discountRecord($couponUseJson, $params));
  1686. $orderAmountPay = $params['order_amount_pay'];
  1687. $constituteList = array_column($params['pay_category_constitute_list'], 'amount', 'category');// 验证金额
  1688. $constituteAmount = 0;
  1689. foreach ($params['pay_category_constitute_list'] as $item) {
  1690. $constituteAmount = $constituteAmount + $item['amount'];
  1691. }
  1692. if ($params['order_amount_pay'] != $constituteAmount) {
  1693. throw new BusinessException('组合支付金额与应付金额不一致');
  1694. }
  1695. if (!empty($params['pay_category_constitute']) && in_array('OFFLINE', $params['pay_category_constitute'])) { //线下付款
  1696. $order->order_status_system = $systemStatus;
  1697. $order->order_status_payment = 'SUCCESS';
  1698. $params['pay_category'] = $params['pay_category_sub'] ?? 'OFFLINE';
  1699. // 线下支付金额
  1700. if (isset($constituteList['OFFLINE'])) {
  1701. $params['order_amount_pay'] = $constituteList['OFFLINE'];
  1702. // 生成支付记录
  1703. OrderService::createPayConstituteDetail($params, $payDetail);
  1704. }
  1705. $params['order_amount_pay'] = $orderAmountPay;
  1706. }
  1707. if (!empty($params['pay_category_constitute']) && in_array('MONEY', $params['pay_category_constitute'])) { //现金付款
  1708. $order->order_status_system = $systemStatus;
  1709. $order->order_status_payment = 'SUCCESS';
  1710. $params['pay_category'] = 'MONEY';
  1711. // 线下支付金额
  1712. if (isset($constituteList['MONEY'])) {
  1713. $params['order_amount_pay'] = $constituteList['MONEY'];
  1714. // 生成支付记录
  1715. OrderService::createPayConstituteDetail($params, $payDetail);
  1716. }
  1717. $params['order_amount_pay'] = $orderAmountPay;
  1718. }
  1719. if (!empty($params['pay_category_constitute']) && in_array('CASH', $params['pay_category_constitute'])) { // 余额支付
  1720. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  1721. ->where('member_account_classify', 'CASH')
  1722. ->where('member_account_status', 'ACTIVED')
  1723. ->first();
  1724. if (!$account) {
  1725. throw new BusinessException('账户异常');
  1726. }
  1727. if (isset($constituteList['CASH'])) {
  1728. $params['order_amount_pay'] = $constituteList['CASH'];
  1729. $params['pay_category'] = $params['join_order_member_id'] . '-CASH';
  1730. }
  1731. $amount = $account->member_account_surplus + $account->member_account_added;
  1732. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  1733. throw new BusinessException('账户余额不足');
  1734. }
  1735. if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
  1736. $qrcodePayAmount = $params['order_amount_pay'] - $amount;
  1737. $params['order_amount_pay'] = $amount;
  1738. }
  1739. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  1740. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  1741. $account->member_account_surplus = 0;
  1742. $account->member_account_added = $cut;
  1743. } else {
  1744. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  1745. }
  1746. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  1747. $account->save();
  1748. // 生成支付记录
  1749. OrderService::createPayConstituteDetail($params, $payDetail);
  1750. $params['order_amount_pay'] = $orderAmountPay;
  1751. $order->order_status_system = $systemStatus;
  1752. $order->order_status_payment = 'SUCCESS';
  1753. }
  1754. if (!empty($params['pay_category_constitute']) && in_array('CARD', $params['pay_category_constitute'])) { // 储值卡账户
  1755. $cardNbr = $params['card_nbr'];
  1756. if (!$cardNbr) {
  1757. throw new BusinessException('账户异常');
  1758. }
  1759. $account = MemberAccount::where('join_account_member_id', $params['join_order_member_id'])
  1760. ->where('member_account_nbr', $cardNbr)
  1761. ->where('member_account_status', 'ACTIVED')
  1762. ->first();
  1763. if (!$account) {
  1764. Db::rollBack();
  1765. return json_fail('账户异常');
  1766. }
  1767. // 储值卡账户支付金额
  1768. if (isset($constituteList['CARD'])) {
  1769. $params['order_amount_pay'] = $constituteList['CARD'];
  1770. $params['pay_category'] = $cardNbr;
  1771. }
  1772. $amount = $account->member_account_surplus + $account->member_account_added;
  1773. if ($params['pay_constitute'] == 'N' && (!$account || $params['order_amount_pay'] > $amount)) {
  1774. throw new BusinessException('账户余额不足');
  1775. }
  1776. if ($params['pay_constitute'] == 'Y' && (!$account || $params['order_amount_pay'] > $amount)) {
  1777. $qrcodePayAmount = $params['order_amount_pay'] - $amount;
  1778. $params['order_amount_pay'] = $amount;
  1779. }
  1780. if ($params['order_amount_pay'] > $account->member_account_surplus) {
  1781. $cut = $account->member_account_added - ($params['order_amount_pay'] - $account->member_account_surplus);
  1782. $account->member_account_surplus = 0;
  1783. $account->member_account_added = $cut;
  1784. } else {
  1785. $account->member_account_surplus = $account->member_account_surplus - $params['order_amount_pay'];
  1786. }
  1787. $account->member_account_expend = $account->member_account_expend + $params['order_amount_pay'];
  1788. $account->save();
  1789. // 生成支付记录
  1790. OrderService::createPayConstituteDetail($params, $payDetail);
  1791. $params['order_amount_pay'] = $orderAmountPay;
  1792. $order->order_status_system = $systemStatus;
  1793. $order->order_status_payment = 'SUCCESS';
  1794. }
  1795. if (!empty($params['pay_category_constitute']) && in_array('QRCODE', $params['pay_category_constitute']) && !empty($params['qrcode_nbr'])) { // 付款码
  1796. if (isset($constituteList['QRCODE']) && $constituteList['QRCODE'] > 0) {
  1797. // 付款码支付金额
  1798. $params['order_amount_pay'] = $constituteList['QRCODE'];
  1799. // 调支付
  1800. $result = OrderService::qrcodePay($params);
  1801. $result = json_encode($result);
  1802. $params['pay_json_response'] = $result;
  1803. $result = json_decode($result, true);
  1804. $prefix = substr($params['qrcode_nbr'], 0, 2);
  1805. if (in_array($prefix, [10, 11, 12, 13, 14, 15])) {
  1806. $params['pay_category'] = 'WXPAY';
  1807. if ((!isset($result['return_code']) || $result['return_code'] != 'SUCCESS') || (!isset($result['result_code']) || $result['result_code'] != 'SUCCESS') || (empty($result['trade_state']) || $result['trade_state'] != 'SUCCESS')) {
  1808. $order->order_status_system = 'PAYING';
  1809. $order->order_status_payment = 'PENDING';
  1810. $order->order_is_complete = 'N';
  1811. // Db::rollBack();
  1812. // return json_fail('支付失败');
  1813. } else {
  1814. $order->order_status_system = $systemStatus;
  1815. $order->order_status_payment = 'SUCCESS';
  1816. }
  1817. } else if (in_array($prefix, [25, 26, 27, 28, 29, 30])) {
  1818. $params['pay_category'] = 'ALIPAY';
  1819. if ((!isset($result['code']) || $result['code'] != '10000') || (empty($result['trade_status']) || $result['trade_status'] != 'TRADE_SUCCESS')) {
  1820. $order->order_status_system = 'PAYING';
  1821. $order->order_status_payment = 'PENDING';
  1822. $order->order_is_complete = 'N';
  1823. // Db::rollBack();
  1824. // return json_fail('支付失败');
  1825. } else {
  1826. $order->order_status_system = $systemStatus;
  1827. $order->order_status_payment = 'SUCCESS';
  1828. }
  1829. } else {
  1830. throw new BusinessException('付款码无效');
  1831. }
  1832. }
  1833. // 生成支付记录
  1834. OrderService::createPayConstituteDetail($params, $payDetail);
  1835. // 账户支付的金额
  1836. $params['order_amount_pay'] = $orderAmountPay;
  1837. }
  1838. $orderConfigJson = [];
  1839. if (!empty($order->order_config_json)) {
  1840. $orderConfigJson = json_decode($order->order_config_json, true);
  1841. }
  1842. $orderConfigJson['preferential'] = $params['preferential'] ?? '';
  1843. if (isset($orderConfigJson['tableid']) && !empty($orderConfigJson['tableid'])) {
  1844. SysDept::where('dept_id', $orderConfigJson['tableid'])->where('dept_category', '桌台')->update(['dept_status' => 'ACTIVED']);
  1845. }
  1846. $order->order_config_json = json_encode($orderConfigJson);
  1847. $order->order_amount_pay = $params['order_amount_pay'];
  1848. // 主订单
  1849. $order->save();
  1850. // sheet
  1851. if ($order->order_status_payment == 'SUCCESS') {
  1852. OrderSheet::where('join_sheet_order_id', $params['order_id'])->update([
  1853. 'order_sheet_status' => $systemStatus,
  1854. ]);
  1855. }
  1856. // 清除paydetail 中的未支付记录
  1857. PayDetail::where('join_pay_order_id', $params['orderGroupId'])->where('pay_status', '<>', 'SUCCESS')->delete();
  1858. $writeOffDate = [];
  1859. $applyData = [];
  1860. // 有预约单,状态已完成
  1861. $appointment = Appointment::where('join_appointment_order_id', $params['order_id'])->first();
  1862. if ($order->order_status_payment == 'SUCCESS' && $appointment) {
  1863. $writeOffDate = OrderService::generateWriteOffData($params);
  1864. $applyData = OrderService::generateAppointmentApplyData($params);
  1865. $appointment->appointment_status = 'DONE';
  1866. $appointment->appointment_done_datetime = date('Y-m-d H:i:s');
  1867. $appointment->appointment_done_json = json_encode($writeOffDate);
  1868. if (empty($appointment->appointment_apply_datetime)) {
  1869. $appointment->appointment_apply_datetime = date('Y-m-d H:i:s');
  1870. }
  1871. if (empty($appointment->appointment_apply_json)) {
  1872. $appointment->appointment_apply_json = json_encode($applyData);
  1873. }
  1874. if (empty($appointment->appointment_datetime)) {
  1875. $appointment->appointment_datetime = date('Y-m-d');
  1876. }
  1877. $appointment->save();
  1878. }
  1879. // 买单个服务
  1880. if ($order->order_status_payment == 'SUCCESS' && empty($appointment)) {
  1881. foreach ($params['goodsContentList'] as $goods) {
  1882. $params['join_sheet_goods_id'] = $goods['goods_id'];
  1883. if (isset($goods['goods_classify']) && in_array($goods['goods_classify'], ['SERVICE', 'CHNMED', 'CHNNCD'])) {
  1884. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  1885. $params['order_sheet_num'] = $goods['nbr'];
  1886. // 预约表
  1887. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  1888. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  1889. // 入预约记录
  1890. $this->insertAppointment($params, $writeOffDate, $applyData);
  1891. }
  1892. $goods['skuId'] = $goods['sku_id'];
  1893. $goods['category'] = $goods['goods_classify'];
  1894. // 权益表
  1895. $this->insertMemberBenefit($params, $goods);
  1896. } elseif (isset($goods['goods_classify']) && $goods['goods_classify'] == 'PACKAGE') { // 一个套餐买多个
  1897. $params['packageId'] = $goods['goods_id'];
  1898. $components = GoodsComponent::with([
  1899. 'goods' => function ($query) {
  1900. $query->select('goods_id', 'goods_name', 'goods_classify');
  1901. }
  1902. ])->where('join_component_master_goods_id', $params['packageId'])
  1903. ->get()
  1904. ->toArray();
  1905. foreach ($components as $component) {
  1906. $componentJson = json_decode($component['goods_component_json'], true);
  1907. $params['join_sheet_goods_sku_id'] = $componentJson['sku_id'];
  1908. $params['benefitId'] = 'BF' . date('ymdHi') . random_string(4, 'up');
  1909. $params['order_sheet_num'] = $goods['nbr'] * $componentJson['nbr'];
  1910. for ($i = 0; $i < intval($params['order_sheet_num']); $i++) {
  1911. $params['appointmentId'] = 'AP' . date('ymdHi') . random_string(4, 'up');
  1912. // 入预约记录
  1913. $this->insertAppointment($params, $writeOffDate);
  1914. }
  1915. $goods['goods_id'] = $component['join_component_goods_id'];
  1916. $goods['goods_name'] = $component['goods']['goods_name'];
  1917. $goods['goods_classify'] = $component['goods']['goods_classify'];
  1918. $goods['skuId'] = $goods['sku_id'];
  1919. $goods['category'] = 'SERVICE';
  1920. // 权益表
  1921. $this->insertMemberBenefit($params, $goods);
  1922. }
  1923. }
  1924. }
  1925. }
  1926. // 2.4W 康养城
  1927. if ($params['goods_classify'] == 'VIP' && $order->order_status_payment == 'SUCCESS') {
  1928. $params['member_id'] = $params['join_order_member_id'];
  1929. Event::dispatch('order.kangyangCityVIP.grant', $params);
  1930. }
  1931. Db::commit();
  1932. // 会员升级
  1933. if ($order->order_is_complete == 'Y' && $order->order_status_payment == 'SUCCESS') {
  1934. Event::dispatch('order.complete', $params);
  1935. Event::dispatch('order_pay.member_level.up', $params['join_order_member_id']);
  1936. }
  1937. // 打小票
  1938. if (!empty($premises) && $params['goods_classify'] == "MEALS") {
  1939. dump('payCons 打小票');
  1940. $restaurant = SysDept::where('dept_super_id', $premises->dept_id)->where('dept_category', '餐厅')->first();
  1941. if (!empty($restaurant->dept_extend_json)) {
  1942. $deptExtendJson = json_decode($restaurant->dept_extend_json, true);
  1943. if (isset($deptExtendJson['printer'])) {
  1944. foreach ($deptExtendJson['printer'] as $key => $item) {
  1945. if (strpos($key, '结算') !== false && $order->order_status_payment == 'SUCCESS') {
  1946. $voteData = [
  1947. 'func' => 'procActionToPrinter',
  1948. 'sign' => '',
  1949. 'data' => [
  1950. 'printer_premises' => $restaurant->dept_id,
  1951. 'printer_device' => [
  1952. $key
  1953. ],
  1954. 'printer_action' => 'ExecPrintOrder',
  1955. 'printer_data' => [
  1956. 'order_id' => $params['order_id']
  1957. ]
  1958. ]
  1959. ];
  1960. http_post_json(getenv('VOTE_MENU_URL'), $voteData);
  1961. }
  1962. }
  1963. }
  1964. }
  1965. }
  1966. if ($order->order_status_payment != 'SUCCESS') {
  1967. _syslog("订单", "支付异常,检查是否有轮询");
  1968. // 恢复优惠券到已占用
  1969. if (!is_array($couponUseJson)) {
  1970. $couponUseJson = json_decode($couponUseJson, true);
  1971. }
  1972. $this->changeOrderCouponStatus($couponUseJson, 'WAITING');
  1973. return json_throw(2001, '支付异常', ['order_id' => $params['orderId']]);
  1974. }
  1975. _syslog("订单", "订单支付成功");
  1976. return json_success('支付成功');
  1977. } catch (\Exception $e) {
  1978. dump($e->getMessage());
  1979. Db::rollBack();
  1980. _syslog("订单", "订单支付失败");
  1981. return json_fail('支付失败');
  1982. }
  1983. }
  1984. /**
  1985. * @Desc
  1986. * @Author Gorden
  1987. * @Date 2024/6/7 10:30
  1988. *
  1989. * @param $params
  1990. * @return void
  1991. * @throws BusinessException
  1992. */
  1993. public function insertMain($params)
  1994. {
  1995. try {
  1996. if (empty($params['order_extend_json'])) {
  1997. $params['order_extend_json'] = [];
  1998. } else {
  1999. if (is_json($params['order_extend_json'])) {
  2000. $params['order_extend_json'] = json_decode($params['order_extend_json'], true);
  2001. }
  2002. }
  2003. // 推荐人
  2004. $params['order_extend_json']['referee'] = $params['referee'] ?? '';
  2005. foreach ($params['goodsContentList'] as $goods) {
  2006. $orderId = 'OD' . date('ymdHi') . random_string(4, 'up');
  2007. $amountPay = (floatval($goods['goods_sales_price']) * $goods['nbr'] / $params['order_amount_total']) * $params['order_amount_pay'];
  2008. // $amountPay = round(floatval($goods['goods_sales_price']) * $goods['nbr'] * $params['order_ratio'], 2);
  2009. $data = [
  2010. 'order_id' => $orderId,
  2011. 'order_groupby' => $params['orderGroupId'],
  2012. 'join_order_member_id' => $params['join_order_member_id'],
  2013. 'order_name' => date('Y-m-d H:i:s') . '-订单',
  2014. 'order_amount_total' => floatval($goods['goods_sales_price']) * $goods['nbr'],
  2015. 'order_amount_pay' => $amountPay,
  2016. 'order_category' => $goods['goods_classify'],
  2017. 'order_classify' => $goods['goods_classify'],
  2018. 'order_is_complete' => $params['order_is_complete'] ?? 'N',
  2019. 'order_status_system' => $params['order_status_system'],
  2020. 'order_status_payment' => $params['order_status_payment'],
  2021. 'order_status_storage' => $params['order_status_storage'],
  2022. 'order_platform' => $params['order_platform'],
  2023. 'order_remark' => $params['order_remark'] ?? '',
  2024. 'order_discount_json' => $params['order_discount_json'],
  2025. 'order_config_json' => $params['order_config_json'] ?? '[]',
  2026. 'order_express_json' => $params['order_express_json'] ?? '[]',
  2027. 'order_extend_json' => $params['order_extend_json'] ? json_encode($params['order_extend_json']) : '[]',
  2028. 'order_addtimes' => time()
  2029. ];
  2030. Order::insert($data);
  2031. $sheetIds = $this->insertSheetOne($params, $goods, $orderId);
  2032. $this->insertPayDetailOne($params, $orderId, $amountPay,$goods);
  2033. $params['order_express_goods'] = json_encode(['sheet' => $sheetIds]);
  2034. $this->insertExpressOne($params);
  2035. }
  2036. } catch (\Exception $e) {
  2037. dump($e->getMessage());
  2038. throw new BusinessException('订单创建信息失败');
  2039. }
  2040. }
  2041. /**
  2042. * @Desc
  2043. * @Author Gorden
  2044. * @Date 2024/6/7 10:25
  2045. *
  2046. * @param $params
  2047. * @return void
  2048. * @throws BusinessException
  2049. */
  2050. public function insertSheet($params)
  2051. {
  2052. try {
  2053. $orderSheetIds = [];
  2054. foreach ($params['goodsContentList'] as $goods) {
  2055. //{"unit": "份", "table": null, "premises": "15"}
  2056. $price = floatval($goods['goods_sales_price']);
  2057. $extendJson['unit'] = $goods['sku_name'];
  2058. if (isset($params['submit_premises_id'])) {
  2059. $extendJson['premises'] = $params['submit_premises_id'];
  2060. }
  2061. if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
  2062. $extendJson['table'] = null;
  2063. }
  2064. $data = [
  2065. 'join_sheet_member_id' => $params['join_order_member_id'],
  2066. 'join_sheet_order_id' => $params['orderId'],
  2067. 'join_sheet_goods_id' => $goods['goods_id'],
  2068. 'join_sheet_goods_sku_id' => $goods['sku_id'],
  2069. 'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
  2070. 'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
  2071. 'order_sheet_num' => $goods['nbr'],
  2072. 'order_sheet_price' => $goods['goods_sales_price'],
  2073. 'order_sheet_amount' => $price * $goods['nbr'],
  2074. 'order_sheet_pay' => $price * $goods['nbr'],
  2075. 'order_sheet_task_status' => 'NONE',
  2076. 'order_sheet_remark' => $params['order_remark'] ?? '',
  2077. 'order_sheet_addtimes' => time(),
  2078. 'order_sheet_extend_json' => json_encode($extendJson)
  2079. ];
  2080. $orderSheetId = OrderSheet::insertGetId($data);
  2081. $orderSheetIds[] = $orderSheetId;
  2082. // 减库存,规格和总库存
  2083. if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
  2084. $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
  2085. $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
  2086. if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
  2087. $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
  2088. }
  2089. if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
  2090. throw new BusinessException('库存不足');
  2091. }
  2092. $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
  2093. $goodsSku->save();
  2094. }
  2095. $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
  2096. $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
  2097. if ($goodsRunning->goods_running_storage < 0) {
  2098. throw new BusinessException('库存不足');
  2099. }
  2100. $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
  2101. $goodsRunning->save();
  2102. }
  2103. // return $orderSheetIds;
  2104. } catch (\support\exception\BusinessException $e) {
  2105. dump($e->getMessage() . '||' . $e->getLine());
  2106. throw new BusinessException($e->getMessage());
  2107. } catch (\Exception $e) {
  2108. dump($e->getMessage() . '||' . $e->getLine());
  2109. throw new BusinessException('订单创建失败');
  2110. }
  2111. }
  2112. /**
  2113. * @Desc 单条入库
  2114. * @Author Gorden
  2115. * @Date 2024/9/23 10:19
  2116. *
  2117. * @param $params
  2118. * @return array
  2119. * @throws BusinessException
  2120. */
  2121. public function insertSheetOne($params, $goods, $orderId)
  2122. {
  2123. try {
  2124. $orderSheetIds = [];
  2125. // foreach ($params['goodsContentList'] as $goods) {
  2126. //{"unit": "份", "table": null, "premises": "15"}
  2127. $price = floatval($goods['goods_sales_price']);
  2128. $extendJson['unit'] = $goods['sku_name'];
  2129. if (isset($params['submit_premises_id'])) {
  2130. $extendJson['premises'] = $params['submit_premises_id'];
  2131. }
  2132. if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
  2133. $extendJson['table'] = null;
  2134. }
  2135. $data = [
  2136. 'join_sheet_member_id' => $params['join_order_member_id'],
  2137. 'join_sheet_order_id' => $orderId,
  2138. 'join_sheet_goods_id' => $goods['goods_id'],
  2139. 'join_sheet_goods_sku_id' => $goods['sku_id'],
  2140. 'order_sheet_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'DONE' : 'PAYING',
  2141. 'order_sheet_category' => (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') ? 'DISHES' : 'NORMAL',
  2142. 'order_sheet_num' => $goods['nbr'],
  2143. 'order_sheet_price' => $goods['goods_sales_price'],
  2144. 'order_sheet_price_pay' => round($goods['goods_sales_price'] * $params['order_ratio']),
  2145. 'order_sheet_amount' => $price * $goods['nbr'],
  2146. 'order_sheet_pay' => round($price * $goods['nbr'] * $params['order_ratio'], 2),
  2147. 'order_sheet_task_status' => 'NONE',
  2148. 'order_sheet_remark' => $params['order_remark'] ?? '',
  2149. 'order_sheet_addtimes' => time(),
  2150. 'order_sheet_extend_json' => json_encode($extendJson)
  2151. ];
  2152. $orderSheetId = OrderSheet::insertGetId($data);
  2153. $orderSheetIds[] = $orderSheetId;
  2154. // 减库存,规格和总库存
  2155. if (!isset($params['submit_goods_classify']) || !in_array($params['submit_goods_classify'], ['MEALS', 'PACKAGE'])) {
  2156. $goodsSku = GoodsSku::where('goods_sku_id', $goods['sku_id'])->first();
  2157. $skuStorageJson = json_decode($goodsSku->goods_sku_storage_json, true);
  2158. if (isset($skuStorageJson['storage']) && !empty($skuStorageJson['storage'])) {
  2159. $skuStorageJson['storage'] = $skuStorageJson['storage'] - $goods['nbr'];
  2160. }
  2161. if (!isset($skuStorageJson['storage']) || (!empty($skuStorageJson['storage']) && $skuStorageJson['storage'] < 0)) {
  2162. throw new BusinessException('库存不足');
  2163. }
  2164. $goodsSku->goods_sku_storage_json = json_encode($skuStorageJson);
  2165. $goodsSku->save();
  2166. }
  2167. $goodsRunning = GoodsRunning::where('join_running_goods_id', $goods['goods_id'])->first();
  2168. $goodsRunning->goods_running_storage = $goodsRunning->goods_running_storage - $goods['nbr'];
  2169. if ($goodsRunning->goods_running_storage < 0) {
  2170. throw new BusinessException('库存不足');
  2171. }
  2172. $goodsRunning->goods_running_sale = $goodsRunning->goods_running_sale + $goods['nbr'];
  2173. $goodsRunning->save();
  2174. // }
  2175. return $orderSheetIds;
  2176. } catch (\support\exception\BusinessException $e) {
  2177. dump($e->getMessage() . '||' . $e->getLine());
  2178. throw new BusinessException($e->getMessage());
  2179. } catch (\Exception $e) {
  2180. dump($e->getMessage() . '||' . $e->getLine());
  2181. throw new BusinessException('订单创建失败');
  2182. }
  2183. }
  2184. /**
  2185. * @Desc
  2186. * @Author Gorden
  2187. * @Date 2024/6/7 10:35
  2188. *
  2189. * @param $params
  2190. * @return void
  2191. * @throws BusinessException
  2192. */
  2193. public function insertPayDetail($params)
  2194. {
  2195. try {
  2196. if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
  2197. $payPrepayid = $params['pay_category'];
  2198. } else if ($params['pay_category'] == 'OFFLINE') {
  2199. $payPrepayid = 'OFFLINE';
  2200. } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
  2201. $payPrepayid = 'OFFLINE_ALIPAY';
  2202. } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
  2203. $payPrepayid = 'OFFLINE_WXPAY';
  2204. } else if ($params['pay_category'] == 'MONEY') {
  2205. $payPrepayid = 'MONEY';
  2206. } else {
  2207. $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
  2208. }
  2209. $data = [
  2210. 'join_pay_member_id' => $params['join_order_member_id'],
  2211. 'join_pay_order_id' => $params['orderGroupId'],
  2212. 'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
  2213. 'pay_category' => $params['goods_classify'],
  2214. 'pay_amount' => $params['order_amount_pay'],
  2215. 'pay_prepayid' => $payPrepayid,
  2216. 'pay_paytimes' => date('Y-m-d H:i:s'),
  2217. 'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $params['orderId']]) : '[]',
  2218. 'pay_json_request' => json_encode($params),
  2219. 'pay_json_response' => $params['pay_json_response'] ?? '[]',
  2220. 'pay_remark' => $params['order_remark'] ?? '',
  2221. 'pay_addtimes' => time(),
  2222. ];
  2223. PayDetail::insert($data);
  2224. } catch (\Exception $e) {
  2225. dump($e->getMessage());
  2226. throw new BusinessException('创建支付记录失败');
  2227. }
  2228. }
  2229. /**
  2230. * @Desc 单条入库
  2231. * @Author Gorden
  2232. * @Date 2024/6/7 10:35
  2233. *
  2234. * @param $params
  2235. * @return void
  2236. * @throws BusinessException
  2237. */
  2238. public function insertPayDetailOne($params, $orderId, $amountPay,$goods)
  2239. {
  2240. try {
  2241. if (in_array($params['pay_category'], ['WXPAY', 'ALIPAY'])) {
  2242. $payPrepayid = $params['pay_category'];
  2243. } else if ($params['pay_category'] == 'OFFLINE') {
  2244. $payPrepayid = 'OFFLINE';
  2245. } else if ($params['pay_category'] == 'OFFLINE_ALIPAY') {
  2246. $payPrepayid = 'OFFLINE_ALIPAY';
  2247. } else if ($params['pay_category'] == 'OFFLINE_WXPAY') {
  2248. $payPrepayid = 'OFFLINE_WXPAY';
  2249. } else if ($params['pay_category'] == 'MONEY') {
  2250. $payPrepayid = 'MONEY';
  2251. } else {
  2252. $payPrepayid = $params['join_order_member_id'] . '-' . $params['pay_category'];
  2253. }
  2254. $data = [
  2255. 'join_pay_member_id' => $params['join_order_member_id'],
  2256. 'join_pay_order_id' => $params['orderGroupId'],
  2257. 'pay_status' => $params['settlement_now'] == 'Y' && $params['order_status_payment'] == 'SUCCESS' ? 'SUCCESS' : 'WAITING',
  2258. 'pay_category' => $goods['goods_classify'],
  2259. 'pay_amount' => $amountPay,
  2260. 'pay_prepayid' => $payPrepayid,
  2261. 'pay_paytimes' => date('Y-m-d H:i:s'),
  2262. 'join_pay_object_json' => !empty($params['orderId']) ? json_encode(['order_id' => $orderId]) : '[]',
  2263. 'pay_json_request' => json_encode($params),
  2264. 'pay_json_response' => $params['pay_json_response'] ?? '[]',
  2265. 'pay_remark' => $params['order_remark'] ?? '',
  2266. 'pay_addtimes' => time(),
  2267. ];
  2268. PayDetail::insert($data);
  2269. } catch (\Exception $e) {
  2270. dump($e->getMessage());
  2271. throw new BusinessException('创建支付记录失败');
  2272. }
  2273. }
  2274. /**
  2275. * @Desc
  2276. * @Author Gorden
  2277. * @Date 2024/6/7 10:50
  2278. *
  2279. * @param $params
  2280. * @return void
  2281. * @throws BusinessException
  2282. */
  2283. public function insertAppointment($params, $writeOffDate, $applyData = [])
  2284. {
  2285. try {
  2286. $data = [
  2287. 'appointment_id' => $params['appointmentId'],
  2288. 'join_appointment_member_id' => $params['join_order_member_id'],
  2289. 'join_appointment_goods_id' => $params['join_sheet_goods_id'],
  2290. 'join_appointment_goods_sku_id' => $params['join_sheet_goods_sku_id'],
  2291. 'join_appointment_order_id' => $params['orderId'],
  2292. 'join_appointment_member_benefit_id' => $params['benefitId'],
  2293. 'appointment_classify' => $params['goods_classify'],
  2294. 'appointment_status' => 'INIT',
  2295. 'appointment_category' => 'NORMAL',
  2296. 'appointment_platform' => 'SYSTEM',
  2297. 'appointment_addtimes' => time(),
  2298. 'appointment_datetime' => '',
  2299. 'appointment_apply_datetime' => '',
  2300. 'appointment_apply_json' => '[]',
  2301. 'appointment_done_datetime' => '',
  2302. 'appointment_remark' => $params['order_remark'] ?? '',
  2303. 'appointment_done_json' => '[]'
  2304. ];
  2305. Appointment::insert($data);
  2306. } catch (\Exception $e) {
  2307. dump($e->getMessage());
  2308. throw new BusinessException("创建权益记录失败");
  2309. }
  2310. }
  2311. /**
  2312. * @Desc
  2313. * @Author Gorden
  2314. * @Date 2024/6/7 11:05
  2315. *
  2316. * @param $params
  2317. * @param $goods
  2318. * @return void
  2319. * @throws BusinessException
  2320. */
  2321. public function insertMemberBenefit($params, $goods)
  2322. {
  2323. try {
  2324. $data = [
  2325. 'member_benefit_id' => $params['benefitId'],
  2326. 'join_benefit_member_id' => $params['join_order_member_id'],
  2327. 'join_benefit_package_id' => $params['packageId'] ?? '',
  2328. 'join_benefit_goods_id' => $goods['goods_id'],
  2329. 'join_benefit_goods_sku_id' => $goods['skuId'] ?? '',
  2330. 'join_benefit_order_id' => $params['orderId'],
  2331. 'member_benefit_status' => 'ACTIVED',
  2332. 'member_benefit_category' => $goods['category'],
  2333. 'member_benefit_name' => $goods['goods_name'],
  2334. 'member_benefit_limit_count' => $params['order_sheet_num'],
  2335. 'member_benefit_used_count' => 0,
  2336. 'member_benefit_remark' => $params['order_remark'] ?? '',
  2337. 'member_benefit_addtimes' => time()
  2338. ];
  2339. MemberBenefit::insert($data);
  2340. } catch (\Exception $e) {
  2341. dump($e->getMessage());
  2342. throw new BusinessException('创建会员权益失败');
  2343. }
  2344. }
  2345. public function saveExpress($params)
  2346. {
  2347. try {
  2348. $express = new OrderExpress();
  2349. $express->order_express_type = $params['order_express_type'];
  2350. $express->join_express_order_id = $params['orderId'];
  2351. $express->join_express_dept_id = $params['submit_premises_id'] ?? 0;
  2352. $express->order_express_goods = $params['order_express_goods'];
  2353. $express->order_express_city = $params['order_express_city'];
  2354. $express->order_express_address = $params['order_express_address'];
  2355. $express->order_express_mobile = $params['order_express_mobile'] ?? '';
  2356. $express->order_express_telephone = $params['order_express_telephone'] ?? '';
  2357. $express->order_express_person = $params['order_express_person'] ?? '';
  2358. $express->order_express_company = $params['dept_premises_id'] ?? '';
  2359. $express->order_express_extend_json = $params['order_express_extend_json'] ?? '[]';
  2360. $express->order_express_addtimes = time();
  2361. $express->save();
  2362. } catch (\Exception $e) {
  2363. dump($e->getMessage());
  2364. throw new BusinessException('物流信息保存失败');
  2365. }
  2366. }
  2367. /**
  2368. * @Desc 修改优惠券状态
  2369. * @Author Gorden
  2370. * @Date 2024/9/19 9:03
  2371. *
  2372. * @param $coupon
  2373. * @param $status
  2374. * @return void
  2375. */
  2376. private function changeOrderCouponStatus($coupon, $status)
  2377. {
  2378. if (!empty($coupon) && is_array($coupon)) {
  2379. $updateData['coupon_detail_status'] = $status;
  2380. if ($status == 'ACTIVED' || $status == 'WAITING') {
  2381. $updateData['coupon_detail_used_datetime'] = '';
  2382. } elseif ($status == 'USED') {
  2383. $updateData['coupon_detail_used_datetime'] = date('Y-m-d H:i:s');
  2384. }
  2385. foreach ($coupon as $item) {
  2386. if (!empty($item['coupon_id']) && !empty($item['coupon_detail_id'])) {
  2387. foreach ($item['coupon_detail_id'] as $detailId) {
  2388. CouponDetail::where('join_detail_coupon_id', $item['coupon_id'])
  2389. ->where('coupon_detail_id', $detailId)->update($updateData);
  2390. }
  2391. }
  2392. }
  2393. }
  2394. }
  2395. private function discountRecord($orderDiscountJson, $params)
  2396. {
  2397. $json = [];
  2398. if (!empty($orderDiscountJson)) {
  2399. $json = json_decode($orderDiscountJson, true);
  2400. }
  2401. try {
  2402. if (!empty($params['preferential']) && in_array('wipe', $params['preferential'])) {
  2403. if (intval($params['order_amount_total'] / 10) * 10 != $params['order_amount_pay']) {
  2404. throw new BusinessException("抹零后实际支付金额错误");
  2405. }
  2406. $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
  2407. $couponClassifyDesc = $couponClassify = '抹零';
  2408. } elseif (!empty($params['preferential']) && in_array('custom', $params['preferential'])) {
  2409. if (sprintf("%.2f", $params['order_amount_total'] - $params['order_discount_amount']) != sprintf("%.2f", $params['order_amount_pay'])) {
  2410. throw new BusinessException("餐厅前台优惠后实际支付金额错误");
  2411. }
  2412. $couponClassifyDesc = $couponClassify = '餐厅前台优惠';
  2413. } else if (!empty($params['preferential']) && intval($params['preferential'][0]) < 100 && intval($params['preferential'][0]) >= 50) {
  2414. if (($params['order_amount_total'] * intval($params['preferential'][0])) / 100 != $params['order_amount_pay']) {
  2415. throw new BusinessException("折扣后实际支付金额错误");
  2416. }
  2417. $couponClassify = '折扣';
  2418. $couponClassifyDesc = intval($params['preferential'][0]) / 10 . '折';
  2419. $params['order_discount_amount'] = $params['order_amount_total'] - $params['order_amount_pay'];
  2420. } else {
  2421. return $json;
  2422. }
  2423. $json[date('Y-m-d H:i:s')] = [
  2424. 'coupon_id' => $params['coupon_id'] ?? null,
  2425. 'coupon_value' => $params['order_discount_amount'] ?? '',
  2426. 'coupon_classify' => $couponClassify,
  2427. 'coupon_detail_id' => [$couponClassifyDesc],
  2428. 'coupon_classify_en' => $params['preferential']
  2429. ];
  2430. return $json;
  2431. } catch (BusinessException $e) {
  2432. throw new BusinessException($e->getMessage());
  2433. } catch (\Exception $e) {
  2434. dump($e->getMessage());
  2435. throw new BusinessException("优惠数据错误");
  2436. }
  2437. }
  2438. /**
  2439. * @Desc 入配送记录
  2440. * @Author Gorden
  2441. * @Date 2024/9/23 10:45
  2442. *
  2443. * @param $params
  2444. * @return void
  2445. * @throws BusinessException
  2446. */
  2447. public function insertExpressOne($params)
  2448. {
  2449. if (isset($params['delivery']) && $params['delivery'] == 'LOGISTICS') {
  2450. $params['order_express_type'] = '配送';
  2451. // 入配送
  2452. $this->saveExpress($params);
  2453. } else if (isset($params['delivery']) && $params['delivery'] == 'PICKUP') {
  2454. $params['order_express_type'] = '自提';
  2455. $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
  2456. if (!$premises) {
  2457. throw new BusinessException('自提门店不存在');
  2458. }
  2459. $params['order_express_city'] = $premises->dept_city;
  2460. $params['order_express_address'] = $premises->dept_address;
  2461. $params['order_express_telephone'] = $premises->dept_telephone;
  2462. $params['order_express_extend_json'] = json_encode(['pick_code' => random_string(4, 'number')]);
  2463. $this->saveExpress($params);
  2464. } else if (isset($params['delivery']) && $params['delivery'] == 'ARRIVAL') {
  2465. $premises = SysDept::where('dept_name', $params['dept_premises_id'])->first();
  2466. $params['order_express_type'] = '到店';
  2467. if (isset($params['submit_goods_classify']) && $params['submit_goods_classify'] == 'MEALS') {
  2468. $params['order_express_type'] = '堂食';
  2469. }
  2470. if (!$premises) {
  2471. throw new BusinessException('门店不存在');
  2472. }
  2473. $params['order_express_city'] = $premises->dept_city;
  2474. $params['order_express_address'] = $premises->dept_address;
  2475. $params['order_express_telephone'] = $premises->dept_telephone;
  2476. $this->saveExpress($params);
  2477. }
  2478. }
  2479. }