177 行
6.4 KiB
PHP
177 行
6.4 KiB
PHP
<?php
|
||
/**
|
||
* 修正提现订单 W202601240278270146002000 钱包扣款类型
|
||
* 业务目标:
|
||
* 1. 扣减用户 20 的商城余额 money 1060.00 元(提现本金 1000 + 手续费 60)
|
||
* 2. 返还用户 20 被误扣的佣金 commission 1060.00 元
|
||
* 3. 记录标准审计流水(WalletLog)
|
||
* 4. 更新提现订单 withdraw_info 标记为商城余额提现
|
||
*/
|
||
|
||
define('APP_PATH', __DIR__ . '/../application/');
|
||
define('ROOT_PATH', dirname(realpath(APP_PATH)) . '/');
|
||
require_once __DIR__ . '/../thinkphp/base.php';
|
||
require_once __DIR__ . '/../thinkphp/helper.php';
|
||
if (is_file(ROOT_PATH . '.env')) {
|
||
$env = parse_ini_file(ROOT_PATH . '.env', true);
|
||
foreach ($env as $key => $val) {
|
||
$name = 'PHP_' . strtoupper($key);
|
||
if (is_array($val)) {
|
||
foreach ($val as $k => $v) {
|
||
$item = $name . '_' . strtoupper($k);
|
||
putenv("$item=$v");
|
||
}
|
||
} else {
|
||
putenv("$name=$val");
|
||
}
|
||
}
|
||
}
|
||
\think\Config::set(\think\Config::load(APP_PATH . 'config.php'));
|
||
\think\Config::set(include APP_PATH . 'database.php', 'database');
|
||
\think\Loader::addNamespace('app', APP_PATH);
|
||
|
||
use think\Db;
|
||
|
||
echo "========================================================\n";
|
||
echo " 提现单 W202601240278270146002000 钱包扣款账目校正脚本\n";
|
||
echo "========================================================\n\n";
|
||
|
||
$withdrawSn = 'W202601240278270146002000';
|
||
|
||
Db::startTrans();
|
||
try {
|
||
// 1. 查询提现单
|
||
$withdraw = Db::name('shopro_withdraw')->where('withdraw_sn', $withdrawSn)->lock(true)->find();
|
||
if (!$withdraw) {
|
||
throw new \Exception("未找到提现单:{$withdrawSn}");
|
||
}
|
||
|
||
$userId = intval($withdraw['user_id']);
|
||
$amount = floatval($withdraw['amount']);
|
||
$chargeFee = floatval($withdraw['charge_fee']);
|
||
$totalNeedDeduct = bcadd((string)$amount, (string)$chargeFee, 2);
|
||
|
||
echo "提现单信息:\n";
|
||
echo "- ID: {$withdraw['id']}\n";
|
||
echo "- 用户ID: {$userId}\n";
|
||
echo "- 提现金额: ¥{$amount}\n";
|
||
echo "- 手续费: ¥{$chargeFee}\n";
|
||
echo "- 应扣总额: ¥{$totalNeedDeduct}\n\n";
|
||
|
||
// 2. 查询用户信息
|
||
$user = Db::name('user')->where('id', $userId)->lock(true)->find();
|
||
if (!$user) {
|
||
throw new \Exception("未找到用户 ID:{$userId}");
|
||
}
|
||
|
||
$currentMoney = (string)$user['money'];
|
||
$currentCommission = (string)$user['commission'];
|
||
|
||
echo "用户校正前资金:\n";
|
||
echo "- 商城余额 money: ¥{$currentMoney}\n";
|
||
echo "- 佣金钱包 commission: ¥{$currentCommission}\n\n";
|
||
|
||
if (bccomp($currentMoney, $totalNeedDeduct, 2) < 0) {
|
||
throw new \Exception("用户商城余额不足扣减 ¥{$totalNeedDeduct}(当前余额:¥{$currentMoney})");
|
||
}
|
||
|
||
// 检查是否已经校正过(防重幂等)
|
||
$alreadyFixed = Db::name('shopro_user_wallet_log')
|
||
->where('user_id', $userId)
|
||
->where('type', 'money')
|
||
->where('event', 'withdraw')
|
||
->where('amount', -floatval($totalNeedDeduct))
|
||
->where('memo', 'like', '%W202601240278270146002000%')
|
||
->find();
|
||
|
||
if ($alreadyFixed) {
|
||
echo "【提示】该提现单已完成过校正,请勿重复执行!\n";
|
||
Db::rollback();
|
||
exit(0);
|
||
}
|
||
|
||
$newMoney = bcsub($currentMoney, $totalNeedDeduct, 2);
|
||
$newCommission = bcadd($currentCommission, $totalNeedDeduct, 2);
|
||
|
||
// 3. 更新用户余额与佣金
|
||
Db::name('user')->where('id', $userId)->update([
|
||
'money' => $newMoney,
|
||
'commission' => $newCommission,
|
||
]);
|
||
|
||
$now = time();
|
||
|
||
// 4. 写入商城余额扣减日志
|
||
Db::name('shopro_user_wallet_log')->insert([
|
||
'user_id' => $userId,
|
||
'type' => 'money',
|
||
'event' => 'withdraw',
|
||
'amount' => -floatval($totalNeedDeduct),
|
||
'before' => $currentMoney,
|
||
'after' => $newMoney,
|
||
'memo' => '修正提现单W202601240278270146002000扣除商城余额',
|
||
'ext' => json_encode([
|
||
'withdraw_id' => (string)$withdraw['id'],
|
||
'withdraw_sn' => $withdrawSn,
|
||
'amount' => (string)$amount,
|
||
'charge_fee' => (string)$chargeFee,
|
||
'fix_reason' => '修正扣错佣金为扣商城余额',
|
||
], JSON_UNESCAPED_UNICODE),
|
||
'oper_type' => 'admin',
|
||
'oper_id' => 1,
|
||
'createtime' => $now,
|
||
]);
|
||
|
||
// 5. 写入佣金返还日志
|
||
Db::name('shopro_user_wallet_log')->insert([
|
||
'user_id' => $userId,
|
||
'type' => 'commission',
|
||
'event' => 'withdraw_error',
|
||
'amount' => floatval($totalNeedDeduct),
|
||
'before' => $currentCommission,
|
||
'after' => $newCommission,
|
||
'memo' => '修正提现单W202601240278270146002000返还误扣佣金',
|
||
'ext' => json_encode([
|
||
'withdraw_id' => (string)$withdraw['id'],
|
||
'withdraw_sn' => $withdrawSn,
|
||
'amount' => (string)$amount,
|
||
'charge_fee' => (string)$chargeFee,
|
||
'fix_reason' => '修正返还误扣佣金',
|
||
], JSON_UNESCAPED_UNICODE),
|
||
'oper_type' => 'admin',
|
||
'oper_id' => 1,
|
||
'createtime' => $now,
|
||
]);
|
||
|
||
// 6. 更新提现单 withdraw_info
|
||
$withdrawInfo = json_decode($withdraw['withdraw_info'], true) ?: [];
|
||
$withdrawInfo['wallet_type'] = 'money';
|
||
$withdrawInfo['提现资产'] = '商城余额';
|
||
Db::name('shopro_withdraw')->where('id', $withdraw['id'])->update([
|
||
'withdraw_info' => json_encode($withdrawInfo, JSON_UNESCAPED_UNICODE),
|
||
'updatetime' => $now,
|
||
]);
|
||
|
||
// 7. 写入提现单操作日志
|
||
Db::name('shopro_withdraw_log')->insert([
|
||
'withdraw_id' => $withdraw['id'],
|
||
'content' => '系统财务校正:已将提现扣款由佣金钱包更正为商城可用余额(扣除余额 ¥' . $totalNeedDeduct . ',退回佣金 ¥' . $totalNeedDeduct . ')',
|
||
'oper_type' => 'admin',
|
||
'oper_id' => 1,
|
||
'createtime' => $now,
|
||
]);
|
||
|
||
Db::commit();
|
||
|
||
echo "【成功】账目校正完成:\n";
|
||
echo "- 商城余额 money: ¥{$currentMoney} -> ¥{$newMoney}(已成功扣除 ¥{$totalNeedDeduct})\n";
|
||
echo "- 佣金钱包 commission: ¥{$currentCommission} -> ¥{$newCommission}(已退还误扣 ¥{$totalNeedDeduct})\n";
|
||
echo "- 提现订单已标记为「商城余额」提现\n";
|
||
echo "- 钱包流水与提现操作日志已写入\n";
|
||
|
||
} catch (\Exception $e) {
|
||
Db::rollback();
|
||
echo "【失败】校正异常回滚:" . $e->getMessage() . "\n";
|
||
exit(1);
|
||
}
|