提交其他文件

This commit is contained in:
2026-03-14 16:20:49 +08:00
parent a227deaecd
commit 0a19b334f8
1385 changed files with 73568 additions and 0 deletions

541
app/api/logic/PayLogic.php Normal file
View File

@ -0,0 +1,541 @@
<?php
namespace app\api\logic;
use app\common\logic\BaseLogic;
use app\common\logic\RefundLogic;
use app\common\model\order\Order;
use app\common\model\order\OrderAll;
use app\common\model\order\OrderGroup;
use app\common\model\order\OrderStore;
use app\common\model\order\OrderStoreRenew;
use app\common\model\pay\Pay;
use app\common\model\refund\RefundRecord;
use app\common\model\store\Store;
use app\common\model\store\StoreUserAccountLog;
use app\common\model\teastore\TeaStore;
use app\common\model\teastore\TeaStoreGroup;
use app\common\model\teastore\TeaStoreRoom;
use app\common\model\user\User;
use app\common\model\user\UserAccountLog;
use app\common\model\user\UserCoupon;
use app\common\model\user\UserGroup;
use app\common\model\user\UserStoreMoney;
use app\common\service\FileService;
use app\common\service\pay\WeChatPayService;
use think\facade\{Db, Config};
class PayLogic extends BaseLogic
{
// public static function yuePay($data,$user_id){
// $result = Pay::where("id",$data['id'])->find();
// $user = User::where("id",$user_id)->find();
// if($user['user_money'] < $result['order_amount']){
// throw new \Exception('余额不足');
// }
// $user->dec('user_money', $result['order_amount']);
// $user->save();
// $order_data['order_status'] = 1;
// $order_data['pay_status'] = 1;
// $order_data['update_dtime'] = date("Y-m-d H:i:s");
// Order::where("id",$result['order_id'])->update($order_data);
// $d['order_sn'] = createSn('pay','order_sn');
// $d['create_time'] = date("Y-m-d H:i:s");
// $d['pay_time'] = date("Y-m-d H:i:s");
// $result = Pay::where("id",$data['id'])->update($d);
// return $result;
// }
public static function yuePay($data, $user_id)
{
Db::startTrans();
try {
$payId = $data['id'];
$currentTime = date("Y-m-d H:i:s");
// 1. 查询支付记录(悲观锁)
$pay = Pay::where("id", $payId)->lock(true)->find();
if (!$pay) {
throw new \Exception('支付记录不存在');
}
// 支付记录状态检查
if ($pay['pay_status'] == 1) {
throw new \Exception('该支付记录已完成支付');
}
// 2. 查询关联订单
if($pay['order_type'] == 1){
$order = OrderStore::where("id", $pay['order_id'])->find();
}elseif($pay['order_type'] == 2){
$order = OrderGroup::where("id", $pay['order_id'])->find();
}elseif($pay['order_type'] == 7){
$order = OrderStoreRenew::where("id", $pay['order_id'])->find();
}
if (!$order) {
throw new \Exception('关联订单不存在');
}
// 3. 查询用户并检查余额(悲观锁)
$user = User::where("id", $user_id)->lock(true)->find();
if (!$user) {
throw new \Exception('用户不存在');
}
// 金额处理:保持数值类型用于计算,字符串类型用于显示
$amount = (float)$pay['order_amount'];
// 区分门店余额支付还是平台余额
if($data['pay_way'] == 3){
$user_store_money = UserStoreMoney::where("user_id",$user_id)->where("store_id",$data['store_id'])->find();
$userMoney = (float)$user_store_money['money'];
}else{
$userMoney = (float)$user['user_money'];
}
// 用于显示的格式化金额
$displayAmount = number_format($amount, 2);
$displayUserMoney = number_format($userMoney, 2);
if ($userMoney < $amount) {
throw new \Exception("余额不足,当前余额: {$displayUserMoney},需支付: {$displayAmount}");
}
// 4. 扣减用户余额(使用数值类型的 $amount
// $userSave = User::where("id", $user_id)->setDec('user_money', $amount);
$newBalance = round($userMoney - $amount, 2);
if($data['pay_way'] == 3){
$userSave = UserStoreMoney::where("user_id", $user_id)->where("store_id",$data['store_id'])->update(['money' => $newBalance,"update_dtime"=>date("Y-m-d H:i:s")]);
}else{
$userSave = User::where("id", $user_id)->update(['user_money' => $newBalance,"update_time"=>time()]);
}
if (!$userSave) {
throw new \Exception('用户余额扣减失败');
}
$change_type = 0;
$sub_sn = 0;
// 5. 更新订单状态
if($pay['order_type'] == 1) {
$change_type = 1;
$type = 3;
// 修改优惠券使用状态
if($order['group_coupon_id']>=0){
UserGroup::where("id", $order['group_coupon_id'])->update(["status"=>1]);
}
if($order['user_coupon_id']>=0){
UserCoupon::where('id',$order['user_coupon_id'])->update(["status"=>1]);
}
$amount = $order['order_amount'];
$orderUpdate = OrderStore::where("id", $pay['order_id'])->update([
'order_status' => 1,
'pay_status' => 1,
'update_dtime' => $currentTime
]);
if(isset($order['room_id'])){
if($order['room_id']!=0&&$order['room_id']!=""&&$order['room_id']!=null){
TeaStoreRoom::where('id', $order['room_id'])->inc('sold', 1)->update();
}
}
if (!$orderUpdate) {
throw new \Exception('订单状态更新失败');
}
}elseif($pay['order_type'] == 2){
$change_type = 4;
$type = 6;
$orderUpdate = OrderGroup::where("id", $pay['order_id'])->update([
'order_status' => 1,
'pay_status' => 1,
'update_dtime' => $currentTime
]);
if (!$orderUpdate) {
throw new \Exception('订单状态更新失败');
}
$qr_sn = createSn("user_group","qr_sn");
$qr_url = CommonLogic::qrcode($qr_sn);
$group = TeaStoreGroup::where('id', $order['group_id'])->find();
UserGroup::create([
"user_id"=>$user_id,
"group_id"=>$order['group_id'],
"qr_sn"=>$qr_sn,
"qr_url"=>$qr_url['file_url'],
"type"=>$group['type'],
"order_id"=>$order['id'],
"store_id"=>$order['store_id'],
"dtime"=>date("Y-m-d H:i:s")
]);
if(isset($order['group_id'])){
if($order['group_id']!=0&&$order['group_id']!=""&&$order['group_id']!=null){
TeaStoreGroup::where('id', $order['group_id'])->inc('sold', 1)->update();
}
}
}elseif($pay['order_type'] == 7){
$renew_order = OrderStoreRenew::where('id',$pay['order_id'])->find();
if(!$renew_order){
throw new \Exception('付款失败,订单不存在');
}
$source_id = $renew_order->source_id;
$store_order = OrderStore::where('id',$source_id)->find();
if(!$store_order){
throw new \Exception('包间订单错误,订单不存在');
}
$renew_timeslot = explode(',', $renew_order->timeslot);
$store_timeslot = explode(',', $store_order->timeslot);
$timeList = array_merge($store_timeslot, $renew_timeslot);
$end = end($timeList);
$renew_price = $renew_order->price;
$renew_order->pay_status = 1;
$renew_order->pay_dtime = 1;
$renew_order->save();
$transfer_order = OrderStore::where('transfer_order_id',$store_order['id'])->select();
$ids = explode(',',$store_order->id);
if($transfer_order->count() > 0){
$orderIds = $transfer_order->column('id');
$ids = array_merge($ids,$orderIds);
}
OrderStore::whereIn("id",$ids)->update([
"end_time"=>$end,
'timeslot'=>implode(',', $timeList),
'renew_dtime'=>implode(',', $timeList),
'is_renewal'=>1,
'renew_price'=>$renew_order->price+$store_order->renew_price,
'renew_hour'=>$renew_order->hour + $store_order->renew_hour,
'store_income_price'=>$store_order->store_income_price+$renew_price
]);
$change_type = 2;
$type = 7;
$sub_sn =$renew_order->order_sn;
$order['order_sn'] =$store_order->order_sn;
$order['store_id'] =$store_order->store_id;
$order['room_id'] =$store_order->room_id;
$amount = $renew_order->price;
}
OrderAll::where("source_sn", $order['order_sn'])->where("type", $type)->update([
'order_status' => 1,
'pay_status' => 1,
'pay_way'=>$order['pay_way'],
'update_time' => time()
]);
// 6. 更新支付记录
$payUpdate = Pay::where("id", $payId)->update([
'order_sn' => createSn('pay', 'order_sn'),
'pay_status' => 1,
'pay_time' => $currentTime
]);
if (!$payUpdate) {
throw new \Exception('支付记录更新失败');
}
// 7. 记录资金流水(使用数值类型的金额)
$moneyLog = self::addUserAccountLog(
$user_id,
$change_type,
$amount,
$userMoney,
$newBalance,
$order
);
$change_object = 1;
if($data['pay_way'] == 3){
$amount = 0;
$change_object = 3;
}
if($pay['order_type'] != 2){
// 记录店家资金流水(使用数值类型的金额)
self::addStoreUserAccountLog(
$data['pay_way'],
$pay['order_type'],
$user_id,
$change_object,
$change_type,
$amount,
$order,
$sub_sn
);
}
// 8. 记录支付日志
self::addPayLog($payId, $user_id, $amount, 'success');
Db::commit();
// 9. 支付成功后的后续操作(可异步处理)
self::afterPaySuccess($pay['order_id'], $user_id);
return [
'success' => true,
'pay_id' => $payId,
'order_id' => $pay['order_id'],
'order_sn' => $order['order_sn'],
'amount' => $displayAmount, // 返回格式化后的金额用于显示
'balance' => number_format($userMoney - $amount, 2) // 格式化余额
];
} catch (\Exception $e) {
Db::rollback();
// 记录支付失败日志
if (isset($payId)) {
self::addPayLog($payId, $user_id, $amount ?? 0, 'fail', $e->getMessage());
}
self::$error = $e->getMessage();
return false;
}
}
private static function addUserAccountLog($user_id,$change_type, $amount,$userMoney, $newBalance,$order)
{
return Db::name('user_account_log')->insert([
'sn'=>createSn("user_account_log","sn"),
'user_id' => $user_id,
'change_object'=>1,
'change_type'=>$change_type,
'action'=>2,
'amount' => $amount,
'before_amount'=>$userMoney,
'after_amount' => $newBalance,
'source_sn' => $order['order_sn'],
'store_id'=>$order['store_id'],
'create_time' => time()
]);
}
private static function addStoreUserAccountLog($pay_way,$order_type,$user_id,$change_object,$change_type, $amount,$order,$sub_sn)
{
$tea_store = TeaStore::where("id",$order['store_id'])->find();
// if($amount != 0){
StoreUserAccountLog::create([
'sn'=>createSn("store_user_account_log","sn"),
'change_object'=>$change_object,
'change_type'=>$change_type,
'user_id'=>$user_id,
'action'=>1,
'amount' => $amount,
'before_amount'=>$tea_store['balance'],
'after_amount' => round($amount+$tea_store['balance'],2),
'source_sn' => $order['order_sn'],
'store_id'=>$order['store_id'],
'sub_sn'=>$sub_sn,
'room_id'=>$order['room_id'],
'create_time' => time()
]);
// if($order_type == 7 ){
// TeaStore::where('id', $order['store_id'])->inc('total_amount', $amount)->update();
// TeaStore::where('id', $order['store_id'])->inc('balance', $amount)->update();
// }
if($pay_way != 3){
TeaStore::where('id', $order['store_id'])->inc('total_amount',$amount)->update();
TeaStore::where('id', $order['store_id'])->inc('balance', $amount)->update();
}
// }
if($order['group_coupon_id'] != 0&&$order_type == 1){
$group = UserGroup::where("id",$order['group_coupon_id'])->find();
$store_group = TeaStoreGroup::where("id",$group['group_id'])->find();
$change_object = 4;
if($group['type'] == 2){
$store_group['discount_price'] = 0;
$change_object = 5;
$amount = 0;
}
StoreUserAccountLog::create([
'sn'=>createSn("store_user_account_log","sn"),
'change_object'=>$change_object,
'change_type'=>1,
'user_id'=>$user_id,
'action'=>1,
'amount' => $store_group['discount_price'],
'before_amount'=>round($tea_store['balance']+$amount,2),
'after_amount' => round($tea_store['balance']+$amount+$store_group['discount_price'],2),
'source_sn' => $order['order_sn'],
'store_id'=>$order['store_id'],
'room_id'=>$order['room_id'],
'remark'=>"团购套餐",
'create_time' => time()
]);
TeaStore::where('id', $order['store_id'])->inc('total_amount', $store_group['discount_price'])->update();
TeaStore::where('id', $order['store_id'])->inc('balance', $store_group['discount_price'])->update();
}
return true;
}
/**
* 记录支付日志
*/
private static function addPayLog($pay_id, $user_id, $amount, $status, $message = '')
{
return Db::name('pay_log')->insert([
'pay_id' => $pay_id,
'user_id' => $user_id,
'amount' => $amount,
'status' => $status,
'message' => $message,
'create_time' => time()
]);
}
// 退款
public static function refund($data, $user_id){
$refund_msg = RefundRecord::where("id",$data['id'])->find();
$remark = "";
$change_type = 0;
// 判断是否为微信支付
// 0为茶艺师 1为茶室支付 2购买套餐 3购买会员 4充值 5团购退款 6茶室退款
if($refund_msg['order_type'] == 5){
$order = OrderGroup::where("order_sn",$refund_msg['source_sn'])->find();
$remark = "团购套餐退款";
$order_amount = $order['order_amount'];
}elseif($refund_msg['order_type'] == 1){
$order = OrderStore::where("order_sn",$refund_msg['source_sn'])->find();
$remark = "包间预定退款";
$order_amount = $order['store_income_price'];
$change_type = 1;
}
if(isset($order)){
// 微信支付
if($order['pay_way'] == 2){
if($order['order_amount'] <= 0){
//查询是否使用优惠券
if($order['user_coupon_id'] != 0){
$r = UserCoupon::where("id",$order['user_coupon_id'])->update(['status'=>0]);
}
//查询是否使用团购券
if($order['group_coupon_id'] != 0){
$r = UserGroup::where("id",$order['user_coupon_id'])->update(['status'=>0]);
}
if(!isset($r)){
throw new \Exception('退款失败100001');
}
}else{
if($refund_msg['order_type'] == 5){
UserGroup::where('order_id',$order['id'])->update(['status'=>4]);
}
$refundData = [
'transaction_id'=>$order->transaction_id,
'refund_sn'=>$refund_msg->order_sn,
'total_amount'=>$order->order_amount,
'notify_url'=>FileService::getFileUrl('api/pay/notifyMnp'),
];
$payService = (new WeChatPayService(1, $user_id ?? null));
$result = $payService->refund($refundData);
if($result['status'] !=='PROCESSING'){
throw new \Exception('押金退款失败请联系客服');
}
return true;
}
}else{
// 余额退款
RefundRecord::where("id",$data['id'])->update(['refund_way'=>3,'refund_status'=>1]);
// 更新总表状态
OrderAll::where("source_sn",$refund_msg['order_sn'])->where("type",$refund_msg['order_type'])->update([
"pay_way"=>$order['pay_way'],
"order_status"=>5,
"pay_status"=>1,
"pay_time"=>time(),
"update_time"=>time()
]);
$user = User::where("id",$user_id)->find();
$money = 0;
$user_money = 0;
if($order['pay_way'] == 1){
// 平台余额
$money = $user['user_money'];
$user_money = round($user['user_money']+$refund_msg['refund_amount'],2);
User::where("id",$user_id)->update(['user_money'=>$user_money]);
}else{
// 门店余额
$user_store_money = UserStoreMoney::where("user_id",$user_id)->where("store_id",$order['store_id'])->find();
$money = $user_store_money['money'];
$user_money = round($user_store_money['money']+$refund_msg['refund_amount'],2);
UserStoreMoney::where("user_id",$user_id)->where("store_id",$order['store_id'])->update(['money'=>$user_money]);
}
// 更新用户流水
UserAccountLog::create([
"sn"=>createSn("user_account_log","sn"),
"user_id"=>$user_id,
"change_object"=>1,
"change_type"=>5,
"action"=>1,
"amount"=>$refund_msg['refund_amount'],
"before_amount"=>$money,
"after_amount"=>$user_money,
"source_sn"=>$refund_msg['order_sn'],
"store_id"=>$refund_msg['store_id'],
"remark"=>$remark,
"create_time"=>time()
]);
}
// 修改订单状态
if($refund_msg['order_type'] == 5){
$rs = OrderGroup::where("order_sn",$refund_msg['source_sn'])->update(['order_status'=>5]);
UserGroup::where("id",$refund_msg['content_id'])->update(['status'=>3]);
}elseif($refund_msg['order_type'] == 1){
$rs = OrderStore::where("order_sn",$refund_msg['source_sn'])->update(['order_status'=>5]);
}
if(isset($rs)){
if(!$rs){
throw new \Exception('退款失败100002');
}
}else{
throw new \Exception('退款失败100003');
}
// if($refund_msg['order_type'] == 5){
// // 扣除店家余额
// $tes_store = TeaStore::where('id', $order['store_id'])->find();
// $total_amount = round($tes_store['total_amount'] - $order_amount,2);
// $balance = round($tes_store['balance'] - $order_amount,2);
// TeaStore::where('id', $order['store_id'])->update(['total_amount'=>$total_amount,'balance'=>$balance]);
// // 添加店家流水
// StoreUserAccountLog::create([
// 'order_sn'=>createSn("store_user_account_log","order_sn"),
// 'change_object'=>1,
// 'change_type'=>$change_type,
// 'action'=>2,
// 'amount' => $order_amount,
// 'before_amount'=>$tes_store['balance'],
// 'after_amount' => $balance,
// 'source_sn' => $order['order_sn'],
// 'store_id'=>$order['store_id'],
// 'room_id'=>$order['room_id'],
// 'remark'=>$remark,
// 'create_time' => time()
// ]);
// }
return true;
}else{
throw new \Exception('暂无订单信息');
}
}
/**
* 支付成功后置操作
*/
private static function afterPaySuccess($order_id, $user_id)
{
// 可以在这里处理:
// 1. 发送通知
// 2. 更新库存
// 3. 记录日志
// 4. 触发其他业务逻辑
// 示例:发送支付成功通知
// NoticeService::sendPaySuccessNotice($user_id, $order_id);
}
}