Level.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. <?php
  2. namespace app\models\order;
  3. use app\models\system\SystemStoreMember;
  4. use app\models\system\SystemUserLevel;
  5. use app\models\user\User;
  6. use app\models\user\UserLevel;
  7. use app\models\user\WechatUser;
  8. use crmeb\basic\BaseModel;
  9. use crmeb\services\AlipayService;
  10. use crmeb\services\MiniProgramService;
  11. use crmeb\services\SystemConfigService;
  12. use crmeb\services\WechatService;
  13. use crmeb\repositories\PaymentRepositories;
  14. use crmeb\traits\ModelTrait;
  15. use app\models\user\UserBill;
  16. use think\facade\Log;
  17. class Level extends BaseModel
  18. {
  19. use ModelTrait;
  20. /**
  21. * 数据表主键
  22. * @var string
  23. */
  24. protected $pk = 'id';
  25. /**
  26. * 模型名称
  27. * @var string
  28. */
  29. protected $name = 'order_level';
  30. protected $insert = ['addtime'];
  31. protected static $payType = ['weixin' => '微信支付', 'yue' => '余额支付', 'ali' => '支付宝支付'];
  32. /**
  33. * 生成订单唯一id
  34. * @param $uid 用户uid
  35. * @return string
  36. */
  37. public static function getNewOrderId()
  38. {
  39. list($msec, $sec) = explode(' ', microtime());
  40. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  41. $orderId = 'lv' . $msectime . mt_rand(10000, 99999);
  42. while (self::be(['order_id' => $orderId])) $orderId = 'lv' . $msectime . mt_rand(10000, 99999);
  43. return $orderId;
  44. }
  45. /**
  46. * 创建订单
  47. * @param $uid
  48. * @param $level_id
  49. * @param $payType
  50. * @param $mark
  51. * @return Level|bool|\think\Model
  52. */
  53. public static function createLevelOrder($uid, $level_id, $payType,$spread_uid=0,$store_id=0)
  54. {
  55. Level::where('uid',$uid)->where('paid',0)->delete();
  56. self::beginTrans();
  57. try {
  58. if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!', true);
  59. $userInfo = User::getUserInfo($uid);
  60. if (!$userInfo) return self::setErrorInfo('用户不存在!', true);
  61. $levelInfo = SystemUserLevel::get(['id' => $level_id, 'is_del' => 0]);
  62. if (!$levelInfo) return self::setErrorInfo('等级不存在', true);
  63. list($where['uid'],$where['level_id'],$where['pay_type'],$where['paid']) = [$uid,$level_id,$payType,0];
  64. $info = self::where($where)->find();
  65. if($info)
  66. {
  67. $order_id = self::getNewOrderId();
  68. self::edit(['pay_price'=>$levelInfo->money,'order_id'=>$order_id],$info['id']);
  69. $info['pay_price'] = $levelInfo->money;
  70. $info['order_id'] = $order_id;
  71. return $info;
  72. }
  73. $orderInfo = [
  74. 'uid' => $uid,
  75. 'order_id' => self::getNewOrderId(),
  76. 'level_id' => $level_id,
  77. 'paid' => 0,
  78. 'is_del' => 0,
  79. 'pay_price' => $levelInfo->money,
  80. 'pay_type' => $payType,
  81. 'body' => '开通会员-'.$levelInfo->name,
  82. 'addtime' => time(),
  83. 'spread_uid'=>$spread_uid,
  84. 'store_id'=>$store_id,
  85. ];
  86. $order = self::create($orderInfo);
  87. if (!$order) return self::setErrorInfo('订单生成失败!');
  88. self::commitTrans();
  89. return $order;
  90. } catch (\PDOException $e) {
  91. self::rollbackTrans();
  92. return self::setErrorInfo('生成订单时SQL执行错误错误原因:' . $e->getMessage());
  93. } catch (\Exception $e) {
  94. self::rollbackTrans();
  95. return self::setErrorInfo('生成订单时系统错误错误原因:' . $e->getMessage());
  96. }
  97. }
  98. public static function paySuccess($orderId, $paytype = 'weixin')
  99. {
  100. $order = self::where('order_id', $orderId)->find()->toArray();
  101. $user = User::where('uid', $order['uid'])->find();
  102. if (!$user) return false;
  103. $res1 = self::where('order_id', $orderId)->update(['paid' => 1, 'pay_type' => $paytype, 'paytime' => time()]);//订单改为支付
  104. self::backBrokerage($order);
  105. $res2 = UserLevel::setUserLevel($order['uid'], $order['level_id'],1);
  106. Log::write($res2?'1':'0'.'-2', 'error');
  107. $res = $res1 && $res2 ;
  108. if($order['level_id']==1) {
  109. SystemStoreMember::setstorecardno($order['uid'], $order['store_id']);
  110. }
  111. $info = SystemUserLevel::find($order['level_id']);
  112. $user = User::where('uid',$order['uid'])->find();
  113. User::where('uid',$order['uid'])->inc('consumer',$order['pay_price'])->update();
  114. UserBill::income('开通'.$info['name'].'赠送消费券',$order['uid'],'consumer','system_add_consumer',$order['pay_price'],$info['id'],bcadd($user['consumer'],$order['pay_price'],2),"开通".$info['name']."赠送消费券".$order['pay_price']);
  115. if($user['spread_uid']>0 && $order['level_id']==1)
  116. {
  117. $sp_user = User::where('uid',$user['spread_uid'])->find();
  118. $spread_consumer = sys_config('spread_consumer');
  119. User::where('uid',$user['spread_uid'])->inc('consumer',$spread_consumer)->update();
  120. UserBill::income('推荐会员赠送消费券',$user['spread_uid'],'consumer','spread_add_consumer',$spread_consumer,$info['id'],bcadd($sp_user['consumer'],$spread_consumer,2),"推荐会员赠送消费券".$spread_consumer);
  121. }
  122. //User::setSpreadLevel($order['spread_uid'],$order['uid']);
  123. return false !== $res;
  124. }
  125. /**
  126. * TODO 小程序JS支付
  127. * @param $orderId
  128. * @param string $field
  129. * @return array|string
  130. * @throws \think\db\exception\DataNotFoundException
  131. * @throws \think\db\exception\ModelNotFoundException
  132. * @throws \think\exception\DbException
  133. */
  134. public static function jsPay($orderId, $field = 'order_id')
  135. {
  136. if (is_string($orderId))
  137. $orderInfo = self::where($field, $orderId)->find();
  138. else
  139. $orderInfo = $orderId;
  140. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  141. if ($orderInfo['paid']) exception('支付已支付!');
  142. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  143. $openid = WechatUser::getOpenId($orderInfo['uid']);
  144. return MiniProgramService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级');
  145. }
  146. /**
  147. * 微信app支付
  148. * @param $orderId
  149. * @param string $field
  150. * @return array|string
  151. * @throws \think\db\exception\DataNotFoundException
  152. * @throws \think\db\exception\ModelNotFoundException
  153. * @throws \think\exception\DbException
  154. */
  155. public static function appPay($order,$field = 'order_id')
  156. {
  157. if(is_string($order))
  158. $orderInfo = self::where($field,$order)->find();
  159. else
  160. $orderInfo = $order;
  161. if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  162. if($orderInfo['paid']) exception('支付已支付!');
  163. //if($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  164. if($orderInfo['pay_price']==0) self::jsPayPrice($order,$orderInfo['uid']);
  165. $openid = WechatUser::uidToOpenid($orderInfo['uid'],'openid');
  166. $wechat = SystemConfigService::more(['weixin_open_appid', 'weixin_open_appsecret']);
  167. $payment = SystemConfigService::more(['pay_weixin_mchid', 'pay_weixin_client_cert', 'pay_weixin_client_key', 'pay_weixin_key', 'pay_weixin_open']);
  168. $config = array(
  169. 'appid' => $wechat['weixin_open_appid'], //填写高级调用功能的app id
  170. 'appsecret' => $wechat['weixin_open_appsecret'], //填写高级调用功能的app secret
  171. 'mchid' => $payment['pay_weixin_mchid'], //商户id
  172. 'key' => $payment['pay_weixin_key'], //填写你设定的key
  173. 'sslcert_path' => $payment['pay_weixin_client_cert'],
  174. 'sslkey_path' => $payment['pay_weixin_client_key'],
  175. 'transfer_rsa_public_path' => '', //企业转账到银行卡rsa公钥证书文件路径
  176. );
  177. $wechatpay = new \JiaLeo\Payment\Wechatpay\AppPay($config);
  178. $pay_data = [
  179. 'body' =>self::getSubstrUTf8('充值VIP',30), //内容
  180. 'attach' =>'user_level', //商家数据包
  181. 'out_trade_no' => $orderInfo['order_id'], //商户订单号
  182. 'total_fee' =>bcmul($orderInfo['pay_price'],100,0), //支付价格(单位:分)
  183. 'notify_url' => sysConfig('site_url') . '/api/wechat/notify', //后台回调地址
  184. ];
  185. $url = $wechatpay->handle($pay_data);
  186. return $url;
  187. }
  188. public static function alipay($orderId, $field = 'order_id')
  189. {
  190. if (is_string($orderId))
  191. $orderInfo = self::where($field, $orderId)->find();
  192. else
  193. $orderInfo = $orderId;
  194. if ($orderInfo['paid']) exception('支付已支付!');
  195. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  196. $alipay = SystemConfigService::more(['alipay_app_id', 'alipay_pub_key','alipay_private_key','alipay_key']);
  197. $notifyUrl = sys_config('site_url') . '/api/alipay/notify';
  198. $aliPay = new AlipayService();
  199. $aliPay->setAppid($alipay['alipay_app_id']);
  200. $aliPay->setNotifyUrl($notifyUrl);
  201. $aliPay->setRsaPrivateKey($alipay['alipay_private_key']);
  202. $aliPay->setTotalFee($orderInfo['pay_price']);
  203. $aliPay->setOutTradeNo($orderInfo['order_id']);
  204. $aliPay->setOrderName('支付会员');
  205. $aliPay->setPassbackParams(['attach' =>'user_level']);
  206. $orderStr = $aliPay->getOrderStr();
  207. return $orderStr;
  208. }
  209. /**
  210. * 微信公众号JS支付
  211. * @param $orderId
  212. * @param string $field
  213. * @return array|string
  214. * @throws \think\db\exception\DataNotFoundException
  215. * @throws \think\db\exception\ModelNotFoundException
  216. * @throws \think\exception\DbException
  217. */
  218. public static function wxPay($orderId, $field = 'order_id')
  219. {
  220. if (is_string($orderId))
  221. $orderInfo = self::where($field, $orderId)->find();
  222. else
  223. $orderInfo = $orderId;
  224. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  225. if ($orderInfo['paid']) exception('支付已支付!');
  226. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  227. $openid = WechatUser::uidToOpenid($orderInfo['uid'], 'openid');
  228. return WechatService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级');
  229. }
  230. /**
  231. * 微信h5支付
  232. * @param $orderId
  233. * @param string $field
  234. * @return array|string
  235. * @throws \think\db\exception\DataNotFoundException
  236. * @throws \think\db\exception\ModelNotFoundException
  237. * @throws \think\exception\DbException
  238. */
  239. public static function h5Pay($orderId, $field = 'order_id')
  240. {
  241. if (is_string($orderId))
  242. $orderInfo = self::where($field, $orderId)->find();
  243. else
  244. $orderInfo = $orderId;
  245. if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
  246. if ($orderInfo['paid']) exception('支付已支付!');
  247. if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
  248. return WechatService::paymentPrepare(null, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级' , '', 'MWEB');
  249. }
  250. /**
  251. * 余额支付
  252. * @param $order_id
  253. * @param $uid
  254. * @param string $formId
  255. * @return bool
  256. * @throws \think\Exception
  257. * @throws \think\db\exception\DataNotFoundException
  258. * @throws \think\db\exception\ModelNotFoundException
  259. * @throws \think\exception\DbException
  260. */
  261. public static function yuePay($order_id, $uid, $formId = '')
  262. {
  263. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->find();
  264. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  265. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  266. $userInfo = User::getUserInfo($uid);
  267. if ($userInfo['now_money'] < $orderInfo['pay_price'])
  268. return self::setErrorInfo(['status' => 'pay_deficiency', 'msg' => '余额不足' . floatval($orderInfo['pay_price'])]);
  269. self::beginTrans();
  270. $res1 = false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid');
  271. $res2 = UserBill::expend('会员升级', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '余额支付' . floatval($orderInfo['pay_price']) . '元升级' . SystemUserLevel::where(['id' => $orderInfo['level_id']])->value('name'));
  272. $res3 = self::paySuccess($order_id, 'yue');//余额支付成功
  273. try {
  274. PaymentRepositories::yuePayProduct($userInfo, $orderInfo);
  275. } catch (\Exception $e) {
  276. self::rollbackTrans();
  277. return self::setErrorInfo($e->getMessage());
  278. }
  279. $res = $res1 && $res2 && $res3;
  280. self::checkTrans($res);
  281. return $res;
  282. }
  283. public static function jsPayPrice($order_id, $uid, $formId = '')
  284. {
  285. $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
  286. if (!$orderInfo) return self::setErrorInfo('订单不存在!');
  287. if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
  288. $userInfo = User::getUserInfo($uid);
  289. self::beginTrans();
  290. $res1 = UserBill::expend('会员升级', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '微信支付' . floatval($orderInfo['pay_price']) . '元升级' . SystemUserLevel::where(['id' => $orderInfo['level_id']])->value('name'));
  291. $res2 = self::paySuccess($order_id, 'weixin', $formId);//微信支付为0时
  292. $res = $res1 && $res2;
  293. self::checkTrans($res);
  294. return $res;
  295. }
  296. /**
  297. * TODO 一级返佣
  298. * @param $orderInfo
  299. * @return bool
  300. * @throws \think\Exception
  301. * @throws \think\db\exception\DataNotFoundException
  302. * @throws \think\db\exception\ModelNotFoundException
  303. * @throws \think\exception\DbException
  304. */
  305. public static function backBrokerage($levelInfo, bool $open = true)
  306. {
  307. $userInfo = User::getUserInfo($levelInfo['uid']);
  308. //TODO 当前用户不存在 没有上级 或者 当用用户上级时自己 直接返回
  309. if (!$userInfo || !$userInfo['spread_uid'] || $userInfo['spread_uid'] == $levelInfo['uid']) return true;
  310. $sp_user = User::where('uid',$levelInfo['spread_uid'])->find();
  311. $spread_consumer = sys_config('spread_consumer');
  312. User::where('uid',$levelInfo['spread_uid'])->inc('consumer',$spread_consumer)->update();
  313. UserBill::income('推荐会员赠送消费券',$levelInfo['spread_uid'],'consumer','spread_add_consumer',$spread_consumer,$levelInfo['id'],bcadd($sp_user['consumer'],$spread_consumer,2),"推荐会员赠送消费券".$spread_consumer);
  314. return true;
  315. }
  316. /**
  317. * TODO 二级推广
  318. * @param $orderInfo
  319. * @return bool
  320. * @throws \think\Exception
  321. * @throws \think\db\exception\DataNotFoundException
  322. * @throws \think\db\exception\ModelNotFoundException
  323. * @throws \think\exception\DbException
  324. */
  325. public static function backBrokerageTwo($levelInfo, bool $open = true)
  326. {
  327. //TODO 获取购买商品的用户
  328. $userInfo = User::getUserInfo($levelInfo['uid']);
  329. //TODO 获取上推广人
  330. $userInfoTwo = User::getUserInfo($userInfo['spread_uid']);
  331. //TODO 上推广人不存在 或者 上推广人没有上级 或者 当用用户上上级时自己 直接返回
  332. if (!$userInfoTwo || !$userInfoTwo['spread_uid'] || $userInfoTwo['spread_uid'] == $levelInfo['uid']) return true;
  333. //TODO 获取后台分销类型 1 指定分销 2 人人分销
  334. if (!User::be(['uid' => $userInfoTwo['spread_uid']])) return true;
  335. $brokeragePrice = bcmul($levelInfo['pay_price'],sys_config('vip_two_brokerage')/100,2);
  336. //TODO 返佣金额小于等于0 直接返回不返佣金
  337. if ($brokeragePrice <= 0) return true;
  338. //TODO 获取上上级推广员信息
  339. $spreadUserInfoTwo = User::getUserInfo($userInfoTwo['spread_uid']);
  340. //TODO 获取上上级推广员返佣之后余额
  341. $balance = bcadd($spreadUserInfoTwo['brokerage_price'], $brokeragePrice, 2);
  342. $mark = '二级推广人' . $userInfo['nickname'] . '开通会员' . floatval($levelInfo['pay_price']) . '元,奖励推广佣金' . floatval($brokeragePrice)."元";
  343. $open && self::beginTrans();
  344. //TODO 添加返佣记录
  345. $res1 = UserBill::income('获得推广佣金', $userInfoTwo['spread_uid'], 'now_money', 'brokerage', $brokeragePrice, $levelInfo['id'], $balance, $mark);
  346. //TODO 添加用户余额
  347. $res2 = self::bcInc($userInfoTwo['spread_uid'], 'brokerage_price', $brokeragePrice, 'uid');
  348. $res = $res1 && $res2;
  349. $open && self::checkTrans($res);
  350. return $res;
  351. }
  352. /**
  353. * 获取会员升级订单
  354. */
  355. public static function orderlist($where)
  356. {
  357. $model = new self;
  358. if(isset($where['data']) && $where['data'] !='') $model = $model->getModelTime($where,$model,"addtime");
  359. if(isset($where['paid']) && $where['paid'] >-1) $model = $model->where('paid',$where['paid']);
  360. if(isset($where['key']) && $where['key'] !='') $model = $model->where('order_id','like',"%".$where['key']."%");
  361. $model = $model->order('id desc');
  362. return self::page($model, function ($v) {
  363. $info = User::where('uid',$v['uid'])->find();
  364. $v['nickname'] = $info['nickname'];
  365. $v['avatar'] = $info['avatar'];
  366. }, $where);
  367. }
  368. }