169 lines
6.8 KiB
PHP
169 lines
6.8 KiB
PHP
|
|
<?php
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace app\services\syj;
|
||
|
|
|
||
|
|
use app\dao\syj\PromoteSettlementDao;
|
||
|
|
use app\dao\syj\PromoteTaskDao;
|
||
|
|
use app\services\BaseServices;
|
||
|
|
use app\services\user\UserBrokerageServices;
|
||
|
|
use app\services\user\UserServices;
|
||
|
|
use think\annotation\Inject;
|
||
|
|
use think\exception\ValidateException;
|
||
|
|
use think\facade\Db;
|
||
|
|
|
||
|
|
class SyjPromoteSettlementServices extends BaseServices
|
||
|
|
{
|
||
|
|
#[Inject]
|
||
|
|
protected PromoteSettlementDao $dao;
|
||
|
|
|
||
|
|
#[Inject]
|
||
|
|
protected PromoteTaskDao $taskDao;
|
||
|
|
|
||
|
|
public function complete(array $task): array
|
||
|
|
{
|
||
|
|
return Db::transaction(function () use ($task) {
|
||
|
|
$taskId = (int)$task['id'];
|
||
|
|
if ($this->dao->be(['task_id' => $taskId, 'settle_type' => 'complete'])) {
|
||
|
|
return $this->dao->getOne(['task_id' => $taskId, 'settle_type' => 'complete'])->toArray();
|
||
|
|
}
|
||
|
|
$gross = $this->money($task['base_amount']);
|
||
|
|
$settlement = $this->dao->save([
|
||
|
|
'task_id' => $taskId,
|
||
|
|
'uid' => (int)$task['uid'],
|
||
|
|
'settle_type' => 'complete',
|
||
|
|
'gross_amount' => $gross,
|
||
|
|
'fee_rate' => '0.00',
|
||
|
|
'fee_amount' => '0.00',
|
||
|
|
'net_amount' => $gross,
|
||
|
|
'audit_status' => 1,
|
||
|
|
'audit_time' => time(),
|
||
|
|
])->toArray();
|
||
|
|
$brokerageId = $this->grantBrokerage((int)$task['uid'], $gross, $taskId, '推四免一任务完成结算,任务号:' . $task['task_no']);
|
||
|
|
$this->dao->update((int)$settlement['id'], ['brokerage_id' => $brokerageId]);
|
||
|
|
$this->taskDao->update($taskId, ['status' => 1, 'finish_time' => time()]);
|
||
|
|
return $settlement;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
public function applyCashout(int $uid, int $taskId): array
|
||
|
|
{
|
||
|
|
return Db::transaction(function () use ($uid, $taskId) {
|
||
|
|
$task = $this->taskDao->get($taskId);
|
||
|
|
if (!$task || (int)$task['uid'] !== $uid) {
|
||
|
|
throw new ValidateException('推广任务不存在');
|
||
|
|
}
|
||
|
|
if ((int)$task['status'] !== 0) {
|
||
|
|
throw new ValidateException('当前任务状态不可提前兑现');
|
||
|
|
}
|
||
|
|
$progress = (int)$task['progress_count'];
|
||
|
|
if ($progress < 1 || $progress >= (int)$task['target_count']) {
|
||
|
|
throw new ValidateException('当前进度不可提前兑现');
|
||
|
|
}
|
||
|
|
if ($this->dao->be(['task_id' => $taskId, 'settle_type' => 'early_cashout'])) {
|
||
|
|
throw new ValidateException('已提交提前兑现申请');
|
||
|
|
}
|
||
|
|
[$gross, $fee, $net] = $this->calcEarlyCashout($task->toArray());
|
||
|
|
$settlement = $this->dao->save([
|
||
|
|
'task_id' => $taskId,
|
||
|
|
'uid' => $uid,
|
||
|
|
'settle_type' => 'early_cashout',
|
||
|
|
'gross_amount' => $gross,
|
||
|
|
'fee_rate' => $this->money($task['fee_rate']),
|
||
|
|
'fee_amount' => $fee,
|
||
|
|
'net_amount' => $net,
|
||
|
|
'audit_status' => 0,
|
||
|
|
])->toArray();
|
||
|
|
$this->taskDao->update($taskId, ['status' => 5]);
|
||
|
|
return $settlement;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
public function auditCashout(int $settlementId, int $auditUid, int $status, string $remark = ''): void
|
||
|
|
{
|
||
|
|
Db::transaction(function () use ($settlementId, $auditUid, $status, $remark) {
|
||
|
|
$settlement = $this->dao->get($settlementId);
|
||
|
|
if (!$settlement || $settlement['settle_type'] !== 'early_cashout') {
|
||
|
|
throw new ValidateException('提前兑现申请不存在');
|
||
|
|
}
|
||
|
|
if ((int)$settlement['audit_status'] !== 0) {
|
||
|
|
throw new ValidateException('申请已审核');
|
||
|
|
}
|
||
|
|
$task = $this->taskDao->get((int)$settlement['task_id']);
|
||
|
|
if (!$task || (int)$task['status'] !== 5) {
|
||
|
|
throw new ValidateException('任务状态不可审核');
|
||
|
|
}
|
||
|
|
if ($status === 1) {
|
||
|
|
$brokerageId = $this->grantBrokerage((int)$settlement['uid'], (string)$settlement['net_amount'], (int)$task['id'], '推四免一提前兑现到账,任务号:' . $task['task_no']);
|
||
|
|
$this->dao->update($settlementId, [
|
||
|
|
'audit_status' => 1,
|
||
|
|
'audit_uid' => $auditUid,
|
||
|
|
'audit_remark' => $remark,
|
||
|
|
'audit_time' => time(),
|
||
|
|
'brokerage_id' => $brokerageId,
|
||
|
|
]);
|
||
|
|
$this->taskDao->update((int)$task['id'], ['status' => 2, 'cashout_time' => time()]);
|
||
|
|
} elseif ($status === 2) {
|
||
|
|
$this->dao->update($settlementId, [
|
||
|
|
'audit_status' => 2,
|
||
|
|
'audit_uid' => $auditUid,
|
||
|
|
'audit_remark' => $remark,
|
||
|
|
'audit_time' => time(),
|
||
|
|
]);
|
||
|
|
$this->taskDao->update((int)$task['id'], ['status' => 0]);
|
||
|
|
} else {
|
||
|
|
throw new ValidateException('审核状态不正确');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
public function listForUser(int $uid, int $page, int $limit): array
|
||
|
|
{
|
||
|
|
return $this->dao->getUserList($uid, $page, $limit);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function adminList(array $where, int $page, int $limit): array
|
||
|
|
{
|
||
|
|
return $this->dao->getAdminList($where, $page, $limit);
|
||
|
|
}
|
||
|
|
|
||
|
|
private function calcEarlyCashout(array $task): array
|
||
|
|
{
|
||
|
|
$rates = json_decode((string)$task['reward_rates'], true);
|
||
|
|
if (!is_array($rates)) {
|
||
|
|
$rates = [10, 20, 30, 40];
|
||
|
|
}
|
||
|
|
$step = max(1, (int)$task['progress_count']);
|
||
|
|
$rate = (float)($rates[$step - 1] ?? 0);
|
||
|
|
$gross = bcmul((string)$task['base_amount'], bcdiv((string)$rate, '100', 4), 2);
|
||
|
|
$fee = bcmul($gross, bcdiv((string)$task['fee_rate'], '100', 4), 2);
|
||
|
|
$net = bcsub($gross, $fee, 2);
|
||
|
|
return [$gross, $fee, $net];
|
||
|
|
}
|
||
|
|
|
||
|
|
private function grantBrokerage(int $uid, string $amount, int $taskId, string $mark): int
|
||
|
|
{
|
||
|
|
/** @var UserServices $userServices */
|
||
|
|
$userServices = app()->make(UserServices::class);
|
||
|
|
$current = (string)($userServices->value(['uid' => $uid], 'brokerage_price') ?: '0');
|
||
|
|
$balance = bcadd($current, $amount, 2);
|
||
|
|
$userServices->bcInc($uid, 'brokerage_price', $amount, 'uid');
|
||
|
|
|
||
|
|
/** @var UserBrokerageServices $brokerageServices */
|
||
|
|
$brokerageServices = app()->make(UserBrokerageServices::class);
|
||
|
|
$row = $brokerageServices->income('syj_promote_settlement', $uid, [
|
||
|
|
'number' => $amount,
|
||
|
|
'mark' => $mark,
|
||
|
|
], $balance, $taskId);
|
||
|
|
if ($row && method_exists($row, 'getData')) {
|
||
|
|
return (int)$row->getData('id');
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private function money(float|string $amount): string
|
||
|
|
{
|
||
|
|
return number_format((float)$amount, 2, '.', '');
|
||
|
|
}
|
||
|
|
}
|