优化分红方式

This commit is contained in:
2026-04-17 16:46:38 +08:00
parent 2e0bcd3f23
commit 9954ea741b
15 changed files with 677 additions and 373 deletions

View File

@@ -63,15 +63,6 @@ class Admin extends Backend
->order($order)
->paginate($limit);
$items = $res->items();
$topGroupUids = $this->getTopGroupUserMap(array_column($items, 'id'));
foreach ($items as &$item) {
$id = $item['id'] ?? null;
if ($id === 1 || isset($topGroupUids[$id])) {
$item['commission_rate'] = null;
}
}
unset($item);
return $this->success('', [
'list' => $items,
'total' => $res->total(),
@@ -204,16 +195,6 @@ class Admin extends Backend
$data['channel_id'] = ($groupChannelId === null || $groupChannelId === '') ? null : $groupChannelId;
}
$data['invite_code'] = $this->generateUniqueInviteCode();
$requireCommissionRate = $this->requireCommissionRate($data['group_arr'] ?? []);
if ($requireCommissionRate) {
if (!$this->isValidCommissionRate($data['commission_rate'] ?? null)) {
return $this->error(__('Please enter a valid commission rate for non-top role group'));
}
$commissionRes = $this->validateAdminCommissionByGroups($data['group_arr'] ?? [], floatval((string)$data['commission_rate']));
if ($commissionRes !== null) return $commissionRes;
} else {
$data['commission_rate'] = null;
}
$result = false;
if (!empty($data['group_arr'])) {
$authRes = $this->checkGroupAuth($data['group_arr']);
@@ -277,18 +258,12 @@ class Admin extends Backend
return $this->error('请选择且仅选择一个角色组');
}
// 未提交分红比例时,若角色组未变更则沿用数据库原值(避免表单单项 number 校验把空串判错)
$postedGroups = array_map('intval', $data['group_arr'] ?? []);
$rowGroups = array_map('intval', $row->group_arr ?? []);
sort($postedGroups);
sort($rowGroups);
$sameGroups = $postedGroups === $rowGroups;
$postedCommission = $data['commission_rate'] ?? null;
if (($postedCommission === null || $postedCommission === '') && $sameGroups && $this->isValidCommissionRate($row['commission_rate'] ?? null)) {
$data['commission_rate'] = $row['commission_rate'];
}
// 当前管理员编辑自身时,不允许修改角色组和分红比
// 当前管理员编辑自身时,不允许修改角色组
if ((int)$this->auth->id === (int)$id) {
$postedGroups = $data['group_arr'] ?? [];
if (!is_array($postedGroups)) {
@@ -297,9 +272,7 @@ class Admin extends Backend
$originGroups = $row->group_arr ?? [];
sort($postedGroups);
sort($originGroups);
$postedRate = $data['commission_rate'] ?? null;
$originRate = $row['commission_rate'] ?? null;
if ($postedGroups !== $originGroups || (string)$postedRate !== (string)$originRate) {
if ($postedGroups !== $originGroups) {
return $this->error(__('You cannot modify your own management group!'));
}
}
@@ -367,16 +340,6 @@ class Admin extends Backend
} else {
$data['channel_id'] = ($groupChannelId === null || $groupChannelId === '') ? null : $groupChannelId;
}
$requireCommissionRate = $this->requireCommissionRate($data['group_arr'] ?? []);
if ($requireCommissionRate) {
if (!$this->isValidCommissionRate($data['commission_rate'] ?? null)) {
return $this->error(__('Please enter a valid commission rate for non-top role group'));
}
$commissionRes = $this->validateAdminCommissionByGroups($data['group_arr'] ?? [], floatval((string)$data['commission_rate']), intval((string)$id));
if ($commissionRes !== null) return $commissionRes;
} else {
$data['commission_rate'] = null;
}
$result = false;
$this->model->startTrans();
try {
@@ -515,73 +478,6 @@ class Admin extends Backend
return $code;
}
private function requireCommissionRate(array $groupIds): bool
{
if (!$groupIds) {
return false;
}
$count = Db::name('admin_group')
->where('id', 'in', $groupIds)
->where('pid', '<>', 0)
->count();
return $count > 0;
}
private function isValidCommissionRate(mixed $value): bool
{
if ($value === null || $value === '') {
return false;
}
$rate = trim((string)$value);
if (!preg_match('/^(100(\.00?)?|[0-9]{1,2}(\.[0-9]{1,2})?)$/', $rate)) {
return false;
}
return true;
}
private function validateAdminCommissionByGroups(array $groupIds, float $currentRate, ?int $excludeAdminId = null): ?Response
{
if (!$groupIds) {
return null;
}
$groups = Db::name('admin_group')
->where('id', 'in', $groupIds)
->where('pid', '<>', 0)
->column('name', 'id');
foreach ($groups as $groupId => $groupName) {
$query = Db::name('admin_group_access')->alias('aga')
->join('admin a', 'aga.uid = a.id')
->where('aga.group_id', intval((string)$groupId));
if ($excludeAdminId !== null) {
$query = $query->where('a.id', '<>', $excludeAdminId);
}
$sum = (float)$query->sum('a.commission_rate');
$remaining = 100 - $sum;
if ($currentRate > $remaining + 0.000001) {
$exceed = $currentRate - $remaining;
return $this->error(sprintf('角色组[%s]分红比例总和不能超过100%%,当前剩余 %.2f%%,本次超出 %.2f%%', $groupName, max(0, $remaining), $exceed));
}
}
return null;
}
private function getTopGroupUserMap(array $userIds): array
{
if (!$userIds) {
return [];
}
$uids = Db::name('admin_group_access')->alias('aga')
->join('admin_group ag', 'aga.group_id = ag.id')
->where('aga.uid', 'in', $userIds)
->where('ag.pid', 0)
->column('aga.uid');
$map = [];
foreach ($uids as $uid) {
$map[$uid] = true;
}
return $map;
}
private function normalizeSingleGroup(array $data): array
{
if (!array_key_exists('group_arr', $data)) {