142 行
4.8 KiB
PHP
142 行
4.8 KiB
PHP
<?php
|
|
|
|
namespace addons\shopro\service\partner;
|
|
|
|
use think\Db;
|
|
use app\admin\model\shopro\user\User as UserModel;
|
|
use addons\shopro\service\Wallet;
|
|
|
|
/**
|
|
* 历史收益全量结转至商城余额服务
|
|
*/
|
|
class WalletMigrationService
|
|
{
|
|
/**
|
|
* 结转前数据预览(只读试算)
|
|
*
|
|
* @return array
|
|
*/
|
|
public function preview()
|
|
{
|
|
$query = UserModel::where('commission', '>', 0);
|
|
$totalCount = (int) $query->count();
|
|
$totalCommission = (float) $query->sum('commission');
|
|
|
|
$sampleList = UserModel::where('commission', '>', 0)
|
|
->field('id,nickname,mobile,money,commission')
|
|
->order('commission', 'desc')
|
|
->limit(20)
|
|
->select();
|
|
|
|
$samples = [];
|
|
foreach ($sampleList as $u) {
|
|
$samples[] = [
|
|
'id' => (int) $u->id,
|
|
'nickname' => (string) ($u->nickname ?: '用户' . $u->id),
|
|
'mobile' => (string) ($u->mobile ?: ''),
|
|
'current_money' => number_format((float) $u->money, 2, '.', ''),
|
|
'current_commission' => number_format((float) $u->commission, 2, '.', ''),
|
|
'target_money' => number_format((float) bcadd((string) $u->money, (string) $u->commission, 2), 2, '.', ''),
|
|
];
|
|
}
|
|
|
|
return [
|
|
'total_users' => $totalCount,
|
|
'total_commission' => number_format($totalCommission, 2, '.', ''),
|
|
'samples' => $samples,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 执行全量结转:将所有会员的 commission 余额转入 money 钱包
|
|
*
|
|
* @param bool $isDryRun 是否只读模拟
|
|
* @param callable|null $progressCallback 进度回调
|
|
* @param array $operator 操作人上下文
|
|
* @return array
|
|
*/
|
|
public function transferAll($isDryRun = false, $progressCallback = null, $operator = [])
|
|
{
|
|
if ($isDryRun) {
|
|
$preview = $this->preview();
|
|
return [
|
|
'status' => 'dry_run',
|
|
'dry_run' => true,
|
|
'total_users' => $preview['total_users'],
|
|
'transferred_amount' => $preview['total_commission'],
|
|
'success_count' => 0,
|
|
'fail_count' => 0,
|
|
'errors' => [],
|
|
'preview' => $preview,
|
|
];
|
|
}
|
|
|
|
$userIds = UserModel::where('commission', '>', 0)->order('id', 'asc')->column('id');
|
|
$totalUsers = count($userIds);
|
|
$successCount = 0;
|
|
$failCount = 0;
|
|
$transferredAmount = '0.00';
|
|
$errors = [];
|
|
|
|
foreach ($userIds as $idx => $userId) {
|
|
try {
|
|
$transferResult = Db::transaction(function () use ($userId) {
|
|
$user = UserModel::where('id', $userId)->lock(true)->find();
|
|
if (!$user) {
|
|
return 0.0;
|
|
}
|
|
|
|
$amount = floatval($user->commission);
|
|
if ($amount <= 0) {
|
|
return 0.0;
|
|
}
|
|
|
|
// 1. 扣减佣金钱包
|
|
Wallet::change($user, 'commission', -$amount, 'transfer_to_money', [
|
|
'batch_migration' => 1,
|
|
'reason' => '全量历史收益结转至商城余额',
|
|
], '收益结转至商城余额');
|
|
|
|
// 2. 增加商城余额
|
|
Wallet::change($user, 'money', $amount, 'transfer_by_commission', [
|
|
'batch_migration' => 1,
|
|
'reason' => '全量历史收益结转至商城余额',
|
|
], '收益结转至商城余额');
|
|
|
|
return $amount;
|
|
});
|
|
|
|
if ($transferResult > 0) {
|
|
$successCount++;
|
|
$transferredAmount = bcadd($transferredAmount, (string) $transferResult, 2);
|
|
}
|
|
|
|
if (is_callable($progressCallback)) {
|
|
$progressCallback($idx + 1, $totalUsers, $userId, $transferResult, null);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
$failCount++;
|
|
$errItem = [
|
|
'user_id' => $userId,
|
|
'error' => $e->getMessage(),
|
|
];
|
|
$errors[] = $errItem;
|
|
|
|
if (is_callable($progressCallback)) {
|
|
$progressCallback($idx + 1, $totalUsers, $userId, 0.0, $e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
return [
|
|
'status' => 'completed',
|
|
'dry_run' => false,
|
|
'total_users' => $totalUsers,
|
|
'success_count' => $successCount,
|
|
'fail_count' => $failCount,
|
|
'transferred_amount' => number_format((float) $transferredAmount, 2, '.', ''),
|
|
'errors' => $errors,
|
|
];
|
|
}
|
|
}
|