love_php/app/Services/OrderService.php
2026-04-09 13:52:20 +08:00

700 lines
26 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Services;
use App\Contracts\OrderContract;
use App\Models\Dma\DmaServiceUserRole;
use App\Models\Dma\S2Customer;
use App\Models\Order;
use App\Models\PayOrder;
use App\Models\RankHistory;
use App\Models\User;
use App\Models\Score;
use App\Models\ScoreHistory;
use App\Models\SubRank;
use App\Jobs\SyncScore;
use App\Jobs\SendRankNotice;
use App\Models\Wechat;
use App\Models\RefundOrder;
use App\Services\PaasService;
use App\Models\PaasAccount;
use App\Models\Live\Asset;
use App\Http\Response\ResponseJson;
use App\Models\Live\AssetLog;
use Log;
use PhpParser\Node\Expr\Cast\Bool_;
class OrderService implements OrderContract
{
use ResponseJson;
//充值会员
public function officialMemberCharge($request, $rank_name, $rank_month, $discount_price, $score, $trade_type = "h5")
{
$user = auth()->user();
//购买的会员等级
$sub_rank_id = $request->input('sub_rank_id');
$goods = '购买' . $rank_month . '个月' . $rank_name . 'VIP';
//订单号
if ($trade_type == 'alipay') {
$trade_no = \CommonUtilsService::getAliTradeNo();
} else {
$trade_no = \CommonUtilsService::getTradeNO();
}
//如果购买的会员是市级会员
if ($discount_price == 0) {
$order = Order::where('user_id', $user->id)->where('type', 'rank')->where('type_id', $sub_rank_id)->first();
if (empty($order)) {
$pay_order = array(
'user_id' => $user->id,
'trade_no' => $trade_no,
'pay_status' => 'PAID',
'is_hooked' => 1,
'cash' => 0,
'score' => 0,
);
$order = array(
'user_id' => $user->id,
'type_id' => $sub_rank_id,
'goods' => $goods,
'price' => 0,
'num' => 1,
'type' => 'rank',
'trade_no' => $trade_no,
'pay_status' => 'PAID',
);
$order_pay = PayOrder::create($pay_order);
$order = Order::create($order);
} else {
$order_pay = PayOrder::where('trade_no', $order->trade_no)->first();
}
$order_pay->wx_pay = [];
$h = RankHistory::where('user_id', $user->id)->where('rank_id', 1)->first();
if (empty($h)) {
RankHistory::create([
'user_id' => $user->id,
'rank_id' => 1,
]);
}
return $order_pay;
}
if ($trade_type != 'wechat_app' && $trade_type != 'alipay_app') {
//当前积分
if ($score->remain_amount >= $discount_price) {
$cash = 0;
$score = $discount_price;
} else {
$discount_price = (int) number_format($discount_price, 2, '', '');
$remain_amount = (int) number_format($score->remain_amount, 2, '', '');
$cash = ($discount_price - $remain_amount) / 100;
$score = $score->remain_amount;
$discount_price = $discount_price / 100;
}
} else {
$cash = $discount_price;
$score = 0;
}
//使用积分
// if ($score > 0) {
// $this->changeScore($user->id, $score, 'used', $message='购买会员');
// }
//订单
$pay_order = array(
'user_id' => $user->id,
'trade_no' => $trade_no,
'pay_status' => 'UNPAID',
'cash' => $cash,
'score' => $score,
);
$order = array(
'user_id' => $user->id,
'type_id' => $sub_rank_id,
'goods' => $goods,
'price' => $discount_price,
'num' => 1,
'type' => 'rank',
'trade_no' => $trade_no,
);
//支付订单
$order_pay = PayOrder::create($pay_order);
$order = Order::create($order);
$wx_pay = [];
if ($cash > 0) {
if ($trade_type == 'h5') {//h5支付
if (strstr($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger')) {
$wx_pay = \WechatService::constructWXPay($pay_order, $user->id, $goods);
} else {
$wx_pay = \WechatService::constructWXH5Pay($pay_order, $user->id, $goods);
}
} elseif ($trade_type == 'wechat_app') {
$wx_pay = \WechatService::constructWXAppPay($pay_order, $user->id, $goods);
} elseif ($trade_type == 'alipay_app') {
$subject = 'rank';
$wx_pay = \AlipayService::purchase($subject, $trade_no, $cash);
}
} else {
$order_pay->pay_status = 'PAID';
$order_pay->is_hooked = 1;
$order->pay_status = 'PAID';
$order_pay->save();
$order->save();
$this->markRankOrder($order->id);
//赠送认证资格
// $this->sendApproveTime($order->user_id);
//赠送认证订单
$this->addApproveOrder($order->user_id);
}
$order_pay->wx_pay = $wx_pay;
//添加平台预订单联系
$paas_service = new PaasService;
$paas_service->addPaasOrder($request->input('paas'), $order->id);
return $order_pay;
}
public function markRankOrder($order_id)
{
$order = Order::find($order_id);
$pay_order = PayOrder::where('trade_no', $order->trade_no)->first();
if ($pay_order->score > 0) {
//扣除对应积分
$result = $this->changeScore($order->user_id, $pay_order->score, 'used', $message = '升级VIP');
if (!$result) {
\Log::debug($order->trade_no . '订单查询异常: 支付回调失败, 福分溢出');
// $this->sms->sentMessage('15872844805', '订单号:'.$order->trade_no.' 福分溢出');
// return $this->failure('支付失败福分溢出');
return false;
}
}
$this->changeRank($order->user_id, $order->type_id);
// //邀请人
// if (!empty($user->from_openid)) {
// $this->addInviteScore($user->from_openid, $order->price);
// }
$user = User::with('wechat')->find($order->user_id);
$sub_rank = SubRank::find($order->type_id);
$array['openid'] = $user->wechat->openid;
$array['rank_id'] = $sub_rank->rank_id;
//微信通知
SendRankNotice::dispatch($array)->onQueue('love');
return true;
}
/**
* 积分修改
* @param int $user_id 用户ID
* @param decimal $score 更改积分
* @param string $type 类型
* @param string $message 备注
* @param inte $other_user_id 其他人ID
* @return bool 是否成功
*/
public function changeScore($user_id, $score, $type, $message = '', $other_user_id = null)
{
$score_obj = Score::where('user_id', $user_id)->first();
if (empty($score_obj)) {
$score_obj = Score::create([
'user_id' => $user_id,
]);
}
if ($type == 'gained') {
//更新积分
// $score_obj->increment('remain_amount', $score);
} else {
if ($score_obj->remain_amount >= $score) {
$score_obj->decrement('remain_amount', $score);
} else {
// $score_obj->decrement('remain_amount', $score_obj->remain_amount);
$this->sms->sentMessage('15872844805', '用户id' . $user_id . ' 福分超额.' . $message);
return false;
}
$score_obj->increment('used_amount', $score);
}
//生成积分记录
ScoreHistory::create([
'user_id' => $user_id,
'other_user_id' => $other_user_id,
'type' => $type,
'amount' => $score,
'value' => $score_obj->remain_amount,
'message' => $message,
]);
// $array['message'] = $message;
// $array['user_id'] = $user_id;
// $array['other_user_id'] = $other_user_id;
// $array['type'] = $type;
// $array['score'] = $score;
// SyncScore::dispatch($array)->onQueue('love');
return true;
}
/**
* 赠送认证资格
* @param [type] $user_id [description]
*/
public function sendApproveTime($user_id)
{
$user = User::find($user_id);
if (!$user->is_approved) {
$user->approve_time = 3;
$user->save();
}
return;
}
/**
* 修改会员
* @return [type] [description]
*/
public function changeRank($user_id, $sub_rank_id)
{
//子等级
$sub_rank = SubRank::find($sub_rank_id);
//当前等级
$user = User::where('id', $user_id)->with('wechat')->first();
//当前会员记录
$rank_history = RankHistory::where('user_id', $user_id)->where('rank_id', $user->rank_id)->orderBy('id', 'desc')->first();
//购买月数
$rank_month = $sub_rank->month;
if ($user->rank_id === 0) {
//创建对应会员
RankHistory::create([
'user_id' => $user_id,
'rank_id' => $sub_rank->rank_id,
'deadline' => date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month')),
]);
$user->rank_id = $sub_rank->rank_id;
$user->save();
} elseif ($user->rank_id === 1) {//当前市级
if ($rank_history && $rank_history->deadline) {//期限内
//更新市级会员
$rank_history->deadline = date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month', strtotime($rank_history->deadline)));
$rank_history->save();
}
//创建对应会员
RankHistory::create([
'user_id' => $user_id,
'rank_id' => $sub_rank->rank_id,
'deadline' => date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month')),
]);
$user->rank_id = $sub_rank->rank_id;
$user->save();
} elseif ($user->rank_id === 2) {//当前黄金
//市级会员记录
$city_rank_history = RankHistory::where('user_id', $user_id)->where('rank_id', 1)->orderBy('id', 'desc')->first();
if (!empty($city_rank_history) && !empty($city_rank_history->deadline)) {//市级会员在期限内
//更新市级会员
$city_rank_history->deadline = date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month', strtotime($city_rank_history->deadline)));
$city_rank_history->save();
}
if ($sub_rank->rank_id === 2) {
if (!empty($rank_history)) {
//更新黄金会员
$rank_history->deadline = date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month', strtotime($rank_history->deadline)));
$rank_history->save();
} else {
RankHistory::create([
'user_id' => $user_id,
'rank_id' => $sub_rank->rank_id,
'deadline' => date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month')),
]);
}
}
if ($sub_rank->rank_id === 3) {
//创建对应会员
RankHistory::create([
'user_id' => $user_id,
'rank_id' => $sub_rank->rank_id,
'deadline' => date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month')),
]);
$user->rank_id = $sub_rank->rank_id;
$user->save();
}
} elseif ($user->rank_id === 3) {//当前钻石
//市级会员记录
$city_rank_history = RankHistory::where('user_id', $user_id)->where('rank_id', 1)->orderBy('id', 'desc')->first();
if (!empty($city_rank_history) && !empty($city_rank_history->deadline)) {//市级会员在期限内
//更新市级会员
$city_rank_history->deadline = date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month', strtotime($city_rank_history->deadline)));
$city_rank_history->save();
}
//黄金会员记录
$gold_rank_history = RankHistory::where('user_id', $user_id)->where('rank_id', 2)->orderBy('id', 'desc')->first();
if (!empty($gold_rank_history) && !empty($gold_rank_history->deadline)) {//黄金会员在期限内
//更新市级会员
$gold_rank_history->deadline = date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month', strtotime($gold_rank_history->deadline)));
$gold_rank_history->save();
}
//更新钻石会员
$rank_history->deadline = date('Y-m-d H:i:s', strtotime('+' . $rank_month . ' month', strtotime($rank_history->deadline)));
$rank_history->save();
} elseif ($user->rank_id === 9) {//当前超级会员
// $history = RankHistory::where('user_id', $user_id)->where('rank_id', $sub_rank->rank_id)->where('deadline', ">", date('Y-m-d H:i:s'))->first();
// if ($history) {
// $history->deadline = date('Y-m-d H:i:s', strtotime('+'.$rank_month.' month', strtotime($history->deadline)));
// }else{
// RankHistory::create([
// 'user_id'=>$user_id,
// 'rank_id'=>$sub_rank->rank_id,
// 'deadline'=>date('Y-m-d H:i:s', strtotime('+'.$rank_month.' month')),
// ]);
// }
}
}
/**
* 退认证费
* 推荐人需要有认证费订单
* 是否重复退费
* @return [type] [description]
*/
public function refundApprove($from_openid)
{
//推荐人
$user_id = Wechat::where('openid', $from_openid)->value('user_id');
if (empty($user_id)) {
return;
}
//是否交认证费
$approve_order = Order::where('user_id', $user_id)->where('type', 'approve')->where('pay_status', 'PAID')->first();
if (empty($approve_order)) {
return;
}
$approve_pay_order = PayOrder::where('user_id', $user_id)->where('trade_no', $approve_order->trade_no)->where('is_hooked', 1)->first();
if (empty($approve_pay_order)) {
return;
}
//是否已退
$refund_order = RefundOrder::where('user_id', $user_id)->where('type', 'approve')->first();
//生成退款记录
if (empty($refund_order)) {
$refund_order = RefundOrder::create([
'user_id' => $user_id,
'type' => 'approve',
'trade_no' => $approve_order->trade_no,
'refund_trade_no' => \CommonUtilsService::getRefundTradeNo(),
'total_fee' => $approve_pay_order->cash,
'refund_fee' => $approve_pay_order->cash,
]);
} else {
return;
}
$total = $refund_order->total_fee * 100;
$desc = '用户实名认证费退款';
//退款
$result = \WechatService::userTransfer($refund_order->refund_trade_no, $from_openid, $total, $desc);
}
/**
* 赠送认证订单
*/
public function addApproveOrder($user_id)
{
// $order = Order::where('user_id', $user_id)->where('type', 'approve')->where('pay_status','PAID')->first();
// if (empty($order)) {
// $order = Order::create([
// 'user_id'=>$user_id,
// 'type_id'=>0,
// 'type'=>"approve",
// 'goods'=>'赠送认证',
// 'pay_status'=>'PAID',
// 'price'=>10,
// 'trade_no'=>'123',
// ]);
// }
return;
}
/**
* app支付生成订单
*/
public function makeAppOrder($request, $price, $type, $type_id = 0, $goods, $linkmen = [], $detail = '')
{
try {
$user = auth()->user();
$pay_type = $request->input('pay_type', 'free');
if (empty($pay_type)) {
$pay_type = 'free';
}
if ($pay_type == 'free' && $price != 0) {
throw new \Exception("订单价格大于0", 1);
}
//是否使用福分
$use_score = $request->input('use_score', 0);
//订单号
$trade_no = \CommonUtilsService::getTradeNO();
$score = 0;
$cash = $price;
$order = array(
'user_id' => auth()->id(),
'type_id' => $type_id,
'goods' => $goods,
'price' => $price,
'num' => 1,
'type' => $type,
'trade_no' => $trade_no,
'pay_type' => $pay_type,
'linkmen' => json_encode($request->input('linkmen', [])),
);
if ($price == 0) {
$order['pay_status'] = 'PAID';
$score = 0;
$cash = 0;
} else {
//计算支付金额
if ($use_score) {
//福气
$viewer_id = $user->getViewerId();
$remain_score = 0;
if (!empty($viewer_id)) {
$asset = Asset::where('viewer_id', $viewer_id)->first();
$remain_score = $asset ? bcadd($asset->share_cash, $asset->cash, 2) : 0;
}
if (bccomp($price, $remain_score) > 0) {
$cash = bcsub($price, $remain_score, 2);
$score = $remain_score;
} else {
$cash = 0;
$score = $price;
}
}
}
$receipt = request()->input('apple_receipt');
$ios_version = $request->header('app-version', '1.0.0');
// $result = \CommonUtilsService::contrastVersion($ios_version, '1.3.16');
$result = $ios_version == '1.3.17' ? true : false;
if ($result && $pay_type == 'ios' and empty($receipt))
throw new \Exception("没有支付凭证", 1);
//生成支付订单
$pay_order = array(
'user_id' => auth()->id(),
'trade_no' => $trade_no,
'pay_status' => $price == 0 ? 'PAID' : 'UNPAID',
'cash' => $cash,
'score' => $score,
'pay_type' => $pay_type,
'receipt' => $receipt,
);
if (empty($cash)) {
$pay_order['pay_status'] = 'PAID';
$pay_order['is_hooked'] = 1;
$order['pay_status'] = 'PAID';
if ($score) {
$result = $this->changeAsset($user, $score);
if (empty($result)) {
throw new \Exception("订单生成失败,福气溢出", 1);
}
}
}
$order_pay = PayOrder::create($pay_order);
//支付订单
$order = Order::create($order);
if ($cash > 0) {
if ($pay_type == 'wechat') {
$ios_version = request()->header('app-version');
$and_version = request()->header('version-name');
$callback = config('app.url') . '/api/app/callback/orders/' . $pay_order['trade_no'] . '?ios_version=' . $ios_version . '&and_version=' . $and_version;
$pay_config = \WechatService::constructWXAppPay($pay_order, auth()->id(), $detail, $callback);
$order_pay->pay_config = $pay_config;
} elseif ($pay_type == 'alipay') {
$pay_config = \AlipayService::purchase($detail, $trade_no, $cash);
$order_pay->pay_config = $pay_config;
}
}
$order_pay->order_id = $order->id;
return $order_pay;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* 修改福气
* @param Request $request [description]
* @return [type] [description]
*/
public function changeAsset($user, $score)
{
try {
\DB::beginTransaction();
//福气
$asset = $user->userAsset();
if (!empty($asset)) {
$remain_score = $asset ? bcadd($asset->share_cash, $asset->cash, 2) : 0;
if ($remain_score < $score) {//总福气小于消耗福气
\DB::rollback();
throw new \Exception("福气溢出 用户id:" . $user->id, 1);
}
//先扣除cash
$cash = $asset->cash;
$share_cash = $asset->share_cash;
if ($cash >= $score) {
$asset->decrement('cash', $score);
} else {
$asset->decrement('cash', $cash);
//再扣除share_cash
$asset->decrement('share_cash', bcsub($score, $cash, 2));
}
//生成消费记录
$log = new AssetLog;
$log->viewer_id = $asset->viewer_id;
$log->num = $score;
$log->real_num = $score;
$log->type = 6;
$log->is_hooked = 1;
$log->score = bcadd($asset->share_cash, $asset->cash, 2);
$log->save();
} else {
\DB::rollback();
throw new \Exception("未查询到福气账号 用户id:" . $user->id, 1);
}
\DB::commit();
return true;
} catch (\Exception $e) {
\DB::rollback();
$this->getError($e);
return false;
}
}
/**订单类型转换 代码转成中文*/
public function orderTypeCodeSwitchChinese($type)
{
if ($type === 'score') {
return '福分充值';
} else if ($type === 'rank') {
return 'VIP充值';
} else if ($type === 'other_rank') {
return '替人VIP充值';
} else if ($type === 'goods') {
return '兑换商品';
} else if ($type === 'donation') {
return '奉献金';
} else if ($type === 'active') {
return '人工牵线';
} else if ($type === 'passive') {
return '托管服务';
} else if ($type === 'coin') {
return '福币充值';
} else if ($type === 'community') {
return '社群支付';
} else if ($type === 'activity') {
return '活动报名';
} else if ($type === 'approve') {
return '实名认证';
} else if ($type === 'single_service') {
return '单身服务';
} else if ($type === 'gift') {
return '赠送礼物';
} else if ($type === 'course') {
return '购买课程';
} else {
return '其他';
}
}
public function storeUftxCustomer($order): bool
{
try {
// 判断订单是否是uftx
if ($order->merchant_id != 44) {
Log::error("不是友福商户");
return false;
}
// 判断订单是否有分享人
if (!$order->from_openid) {
Log::error("没有from_openid");
return false;
}
// 判断下单人和分享人是否一致
if ($order->openid == $order->from_openid) {
Log::error("分享人和下单人一致");
return false;
}
// 查询订单用户手机号和分享人用户手机号
$wechat = Wechat::where("official_openid", $order->open_id)->first();
if (empty($wechat)) {
Log::error("没有下单人wechat");
return false;
}
$from_wechat = Wechat::where("official_openid", $order->from_openid)->first();
if (empty($from_wechat)) {
Log::error("没有分享人wechat");
return false;
}
$user = User::Where("id", $wechat->user_id)->first();
if (empty($user)) {
Log::error("没有下单人user");
return false;
}
$from_user = User::Where("id", $from_wechat->user_id)->first();
if (empty($from_user)) {
Log::error("没有分享人user");
return false;
}
$mobile = $user->mobile;
if (empty($mobile)) {
Log::error("没有下单人手机号");
return false;
}
$from_mobile = $from_user->mobile;
if (empty($from_mobile)) {
Log::error("没有分享人手机号");
return false;
}
// 判断分享人是否在友福同享有服务端账号
$serviceUser = DmaServiceUserRole::where("mobile", $from_mobile)->first();
if (empty($serviceUser)) {
Log::error("分享人不是商户端用户");
return false;
}
// 判断是否已经是客户
$customer = S2Customer::where(["user_id" => $serviceUser->user_id, "contacts_mobile" => $mobile])->first();
if ($customer) {
Log::error("已成为客户");
return false;
}
// 创建客户
S2Customer::create([
"user_id" => $serviceUser->user_id,
"customer_name" => "",
"customer_type" => 101,
"contacts_name" => $user->nickname,
"contacts_mobile" => $mobile,
"intention" => 1,
"status" => 2
]);
Log::info("创建客户成功");
return true;
} catch (\Throwable $th) {
$this->getError($th);
return false;
}
}
}