From 7ab3db121c0c45e4d0c2a9c5eda85aaa6a7e9ba3 Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Sat, 30 May 2026 14:58:17 +0800 Subject: [PATCH] =?UTF-8?q?1.=E7=BB=93=E7=AE=97=E8=AE=B0=E5=BD=95=E4=B8=AD?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=93=E7=AE=97=E4=BF=A1=E6=81=AF=202.?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B8=A0=E9=81=93=E9=A1=B5=E9=9D=A2=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/agent/CommissionRecord.php | 54 +++++++ app/common/lang/en/admin_rule_title.php | 1 + app/common/lang/zh-cn/admin_rule_title.php | 1 + app/common/model/AgentCommissionRecord.php | 5 + .../AdminCommissionDistributionService.php | 9 ++ .../service/ChannelSettlementService.php | 4 +- .../lang/backend/en/agent/commissionRecord.ts | 13 +- .../lang/backend/en/agent/settlementPeriod.ts | 1 + .../backend/zh-cn/agent/commissionRecord.ts | 11 +- .../backend/zh-cn/agent/settlementPeriod.ts | 1 + .../backend/agent/commissionRecord/index.vue | 136 ++++++++++++++++-- .../backend/agent/settlementPeriod/index.vue | 33 ++++- web/src/views/backend/channel/index.vue | 89 +++++++----- 13 files changed, 297 insertions(+), 61 deletions(-) diff --git a/app/admin/controller/agent/CommissionRecord.php b/app/admin/controller/agent/CommissionRecord.php index 017db51..516cc56 100644 --- a/app/admin/controller/agent/CommissionRecord.php +++ b/app/admin/controller/agent/CommissionRecord.php @@ -32,5 +32,59 @@ class CommissionRecord extends Backend $this->model = new \app\common\model\AgentCommissionRecord(); return null; } + + protected function _index(): Response + { + if ($this->request && $this->request->get('select')) { + return $this->select($this->request); + } + + list($where, $alias, $limit, $order) = $this->queryBuilder(); + $res = $this->model + ->field($this->indexField) + ->withJoin($this->withJoinTable, $this->withJoinType) + ->with($this->withJoinTable) + ->alias($alias) + ->where($where) + ->order($order) + ->paginate($limit); + + $list = $this->enrichCommissionRecordList($res->items()); + + return $this->success('', [ + 'list' => $list, + 'total' => $res->total(), + 'remark' => get_route_remark(), + ]); + } + + /** + * @param array $items + * @return array + */ + private function enrichCommissionRecordList(array $items): array + { + if ($items === []) { + return $items; + } + + $out = []; + foreach ($items as $item) { + $row = is_array($item) ? $item : (method_exists($item, 'toArray') ? $item->toArray() : []); + $gross = strval($row['commission_amount'] ?? '0.00'); + $fee = strval($row['handling_fee'] ?? '0.00'); + $net = strval($row['net_commission_amount'] ?? '0.00'); + if (bccomp($net, '0', 2) <= 0 && (bccomp($gross, '0', 2) > 0 || bccomp($fee, '0', 2) > 0)) { + $net = bcsub($gross, $fee, 2); + if (bccomp($net, '0', 2) < 0) { + $net = '0.00'; + } + $row['net_commission_amount'] = $net; + } + $out[] = $row; + } + + return $out; + } } diff --git a/app/common/lang/en/admin_rule_title.php b/app/common/lang/en/admin_rule_title.php index 66661b9..d7d38bd 100644 --- a/app/common/lang/en/admin_rule_title.php +++ b/app/common/lang/en/admin_rule_title.php @@ -121,6 +121,7 @@ return [ 'periodSettings' => 'Period settings', 'manualSettle' => 'Manual settle', 'batchSettlePending' => 'Batch settle pending channels', + 'viewCommissionRecords' => 'View commission records', 'viewDividendRecords' => 'View paid dividend records', 'viewDirectBetRecords' => 'View direct bet records', 'viewSettlementBetRecords' => 'View settlement-scope bets', diff --git a/app/common/lang/zh-cn/admin_rule_title.php b/app/common/lang/zh-cn/admin_rule_title.php index 96fa4ee..91cbd0b 100644 --- a/app/common/lang/zh-cn/admin_rule_title.php +++ b/app/common/lang/zh-cn/admin_rule_title.php @@ -53,6 +53,7 @@ return [ 'periodSettings' => '期号设置', 'manualSettle' => '手动结算', 'batchSettlePending' => '批量结算待结算渠道', + 'viewCommissionRecords' => '查看代理佣金记录', 'viewDividendRecords' => '查看已分红记录', 'viewDirectBetRecords' => '查看直属投注记录', 'viewSettlementBetRecords' => '查看总投注金额', diff --git a/app/common/model/AgentCommissionRecord.php b/app/common/model/AgentCommissionRecord.php index cf450cf..4d2e36d 100644 --- a/app/common/model/AgentCommissionRecord.php +++ b/app/common/model/AgentCommissionRecord.php @@ -15,8 +15,13 @@ class AgentCommissionRecord extends Model 'update_time' => 'integer', 'settled_at' => 'integer', 'commission_rate' => 'string', + 'share_rate' => 'string', 'calc_base_amount' => 'string', 'commission_amount' => 'string', + 'commission_share_percent' => 'string', + 'handling_fee' => 'string', + 'handling_fee_rate' => 'string', + 'net_commission_amount' => 'string', 'status' => 'integer', ]; diff --git a/app/common/service/AdminCommissionDistributionService.php b/app/common/service/AdminCommissionDistributionService.php index 9d071b4..0ac4492 100644 --- a/app/common/service/AdminCommissionDistributionService.php +++ b/app/common/service/AdminCommissionDistributionService.php @@ -194,6 +194,14 @@ class AdminCommissionDistributionService if ($nodes === []) { return []; } + $shareRateByAdmin = []; + foreach ($nodes as $node) { + $nodeAdminId = intval($node['admin_id'] ?? 0); + if ($nodeAdminId <= 0) { + continue; + } + $shareRateByAdmin[$nodeAdminId] = strval($node['share_rate'] ?? '0.00'); + } $defaultRate = self::normalizeHandlingFeeRatePercent($defaultHandlingFeeRate); $merged = []; foreach ($nodes as $node) { @@ -223,6 +231,7 @@ class AdminCommissionDistributionService 'commission_amount' => $gross, 'commission_rate' => $effectiveRate, 'calc_base_amount' => $settlementBase, + 'share_rate' => $shareRateByAdmin[$adminId] ?? '0.00', 'commission_share_percent' => self::calcCommissionSharePercent($gross, $totalCommission), 'handling_fee_rate' => $feeRate, 'handling_fee' => $feeAmount, diff --git a/app/common/service/ChannelSettlementService.php b/app/common/service/ChannelSettlementService.php index 23a6c9e..3210e13 100644 --- a/app/common/service/ChannelSettlementService.php +++ b/app/common/service/ChannelSettlementService.php @@ -73,7 +73,6 @@ class ChannelSettlementService if ($adminId <= 0) { continue; } - unset($row['net_commission_amount']); $row['status'] = 1; $row['settled_at'] = $now; $row['remark'] = strval($row['remark'] ?? '') . ' | 超管结算直接发放'; @@ -370,9 +369,12 @@ class ChannelSettlementService 'channel_id' => $channelId, 'admin_id' => $adminId, 'commission_rate' => strval($dist['commission_rate'] ?? '0.0000'), + 'share_rate' => strval($dist['share_rate'] ?? '0.00'), 'calc_base_amount' => strval($dist['calc_base_amount'] ?? '0.00'), 'commission_amount' => $amount, + 'commission_share_percent' => strval($dist['commission_share_percent'] ?? '0.00'), 'handling_fee' => strval($dist['handling_fee'] ?? '0.00'), + 'handling_fee_rate' => strval($dist['handling_fee_rate'] ?? '0.00'), 'net_commission_amount' => strval($dist['net_commission_amount'] ?? '0.00'), 'status' => 0, 'settled_at' => null, diff --git a/web/src/lang/backend/en/agent/commissionRecord.ts b/web/src/lang/backend/en/agent/commissionRecord.ts index 17b8328..822cedc 100644 --- a/web/src/lang/backend/en/agent/commissionRecord.ts +++ b/web/src/lang/backend/en/agent/commissionRecord.ts @@ -7,11 +7,16 @@ export default { channel_name: 'Channel', admin_id: 'Agent admin', admin_username: 'Agent username', - commission_rate: 'Commission rate', - calc_base_amount: 'Calculation base amount', - commission_amount: 'Commission amount (gross)', - handling_fee: 'Handling fee amount', + calc_base_amount: 'Settlement base', + share_rate: 'Share rate', + commission_rate: 'Effective rate', + commission_amount: 'Commission (gross)', + commission_share_percent: 'Share of total', + handling_fee_rate: 'Handling fee rate', + handling_fee: 'Handling fee', net_commission_amount: 'Net commission', + filter_by_settlement_no: 'Filtered by settlement no.: {no}', + reset_settlement_filter: 'Reset filter', status: 'Status', 'status 0': 'Pending', 'status 1': 'Paid', diff --git a/web/src/lang/backend/en/agent/settlementPeriod.ts b/web/src/lang/backend/en/agent/settlementPeriod.ts index 9fa50b4..9d9510a 100644 --- a/web/src/lang/backend/en/agent/settlementPeriod.ts +++ b/web/src/lang/backend/en/agent/settlementPeriod.ts @@ -15,5 +15,6 @@ export default { remark: 'Remark', create_time: 'Created', update_time: 'Updated', + view_commission_records: 'View commission records', } diff --git a/web/src/lang/backend/zh-cn/agent/commissionRecord.ts b/web/src/lang/backend/zh-cn/agent/commissionRecord.ts index 672ea18..0f09da2 100644 --- a/web/src/lang/backend/zh-cn/agent/commissionRecord.ts +++ b/web/src/lang/backend/zh-cn/agent/commissionRecord.ts @@ -7,11 +7,16 @@ export default { channel_name: '渠道名称', admin_id: '代理管理员', admin_username: '代理账号', - commission_rate: '佣金比例', calc_base_amount: '结算基数', - commission_amount: '佣金金额(费前)', - handling_fee: '手续费金额', + share_rate: '分配比例', + commission_rate: '有效比例', + commission_amount: '佣金(费前)', + commission_share_percent: '占比', + handling_fee_rate: '手续费比例', + handling_fee: '手续费', net_commission_amount: '实发佣金', + filter_by_settlement_no: '当前筛选结算周期号:{no}', + reset_settlement_filter: '重置筛选', status: '状态', 'status 0': '待发放', 'status 1': '已发放', diff --git a/web/src/lang/backend/zh-cn/agent/settlementPeriod.ts b/web/src/lang/backend/zh-cn/agent/settlementPeriod.ts index cf71ed7..1e970a7 100644 --- a/web/src/lang/backend/zh-cn/agent/settlementPeriod.ts +++ b/web/src/lang/backend/zh-cn/agent/settlementPeriod.ts @@ -15,5 +15,6 @@ export default { remark: '备注', create_time: '创建时间', update_time: '更新时间', + view_commission_records: '查看代理佣金记录', } diff --git a/web/src/views/backend/agent/commissionRecord/index.vue b/web/src/views/backend/agent/commissionRecord/index.vue index 13db5d4..dbabdcb 100644 --- a/web/src/views/backend/agent/commissionRecord/index.vue +++ b/web/src/views/backend/agent/commissionRecord/index.vue @@ -2,6 +2,21 @@
+ + + + - + diff --git a/web/src/views/backend/agent/settlementPeriod/index.vue b/web/src/views/backend/agent/settlementPeriod/index.vue index 2eba740..69ebb2d 100644 --- a/web/src/views/backend/agent/settlementPeriod/index.vue +++ b/web/src/views/backend/agent/settlementPeriod/index.vue @@ -21,14 +21,43 @@ import { defaultOptButtons } from '/@/components/table' import TableHeader from '/@/components/table/header/index.vue' import Table from '/@/components/table/index.vue' import baTableClass from '/@/utils/baTable' +import { auth } from '/@/utils/common' +import { routePush } from '/@/utils/router' defineOptions({ name: 'agent/settlementPeriod', }) +const SETTLEMENT_NO_PROP = 'settlementPeriod.settlement_no' + const { t } = useI18n() const tableRef = useTemplateRef('tableRef') -const optButtons: OptButton[] = defaultOptButtons(['edit', 'delete']) +const optButtons: OptButton[] = [ + { + render: 'tipButton', + name: 'viewCommissionRecords', + title: 'agent.settlementPeriod.view_commission_records', + text: '', + type: 'primary', + icon: 'fa fa-list-alt', + class: 'table-row-view-commission-records', + disabledTip: false, + display: () => auth('viewCommissionRecords'), + click: (row: TableRow) => { + const settlementNo = String(row?.settlement_no ?? '').trim() + if (settlementNo === '') { + return + } + void routePush({ + path: '/admin/agent/commissionRecord', + query: { + [SETTLEMENT_NO_PROP]: settlementNo, + }, + }) + }, + }, + ...defaultOptButtons(['edit', 'delete']), +] function formatAmount2(_row: anyObj, _column: any, cellValue: unknown) { if (cellValue === null || cellValue === undefined || cellValue === '') { @@ -149,7 +178,7 @@ const baTable = new baTableClass( sortable: 'custom', timeFormat: 'yyyy-mm-dd hh:MM:ss', }, - { label: t('Operate'), align: 'center', minWidth: 80, render: 'buttons', buttons: optButtons, operator: false, fixed: 'right' }, + { label: t('Operate'), align: 'center', minWidth: 120, render: 'buttons', buttons: optButtons, operator: false, fixed: 'right' }, ], }, { diff --git a/web/src/views/backend/channel/index.vue b/web/src/views/backend/channel/index.vue index e3d277d..a55938c 100644 --- a/web/src/views/backend/channel/index.vue +++ b/web/src/views/backend/channel/index.vue @@ -71,6 +71,7 @@ :model="manualSettle.form" :label-width="manualSettleFormLabelWidth" :label-position="manualSettleFormLabelPosition" + size="small" class="manual-settle-form" > @@ -180,17 +181,13 @@ {{ t('channel.manual_settle_split_scroll_tip') }}

- -
    -
  • {{ line }}
  • -
-
+ + +
    +
  • {{ line }}
  • +
+
+
@@ -441,7 +438,8 @@ const { t } = useI18n() const MANUAL_SETTLE_MOBILE_BREAKPOINT = 768 const manualSettleViewportMobile = ref(typeof window !== 'undefined' ? window.innerWidth <= MANUAL_SETTLE_MOBILE_BREAKPOINT : false) -const manualSettleDialogWidth = computed(() => (manualSettleViewportMobile.value ? '96%' : '860px')) +const manualSettleCalcCollapse = ref([]) +const manualSettleDialogWidth = computed(() => (manualSettleViewportMobile.value ? '96%' : '740px')) const manualSettleFormLabelPosition = computed(() => (manualSettleViewportMobile.value ? 'top' : 'right')) const manualSettleFormLabelWidth = computed(() => (manualSettleViewportMobile.value ? 'auto' : '140px')) const manualSettleTableLayout = computed(() => 'fixed') @@ -1484,9 +1482,9 @@ onUnmounted(() => { display: flex !important; flex-direction: column; width: 92% !important; - max-width: 860px; - max-height: 92vh; - margin: 4vh auto !important; + max-width: 740px; + max-height: 86vh; + margin: 7vh auto !important; padding-bottom: 0; overflow: hidden; } @@ -1501,12 +1499,12 @@ onUnmounted(() => { flex: 1 1 auto; min-height: 0; height: auto !important; - max-height: calc(92vh - 120px); + max-height: calc(86vh - 108px); overflow-y: auto !important; overflow-x: hidden; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; - padding: 12px 16px 16px; + padding: 10px 14px 12px; } :deep(.manual-settle-dialog .el-dialog__footer) { @@ -1528,14 +1526,15 @@ onUnmounted(() => { .manual-settle-form { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - column-gap: 16px; + grid-template-columns: repeat(3, minmax(0, 1fr)); + column-gap: 12px; + row-gap: 0; min-width: 0; max-width: 100%; } .manual-settle-form :deep(.el-form-item) { - margin-bottom: 12px; + margin-bottom: 8px; } .manual-settle-form-item-full { @@ -1648,15 +1647,35 @@ onUnmounted(() => { word-break: keep-all; } -.manual-settle-calc-alert { - margin-top: 12px; +.manual-settle-calc-collapse { + margin-top: 8px; + border: none; +} + +.manual-settle-calc-collapse :deep(.el-collapse-item__header) { + height: 34px; + line-height: 34px; + font-size: 13px; + font-weight: 500; + border-bottom: none; + background: var(--el-fill-color-light); + border-radius: 4px; + padding: 0 10px; +} + +.manual-settle-calc-collapse :deep(.el-collapse-item__wrap) { + border-bottom: none; +} + +.manual-settle-calc-collapse :deep(.el-collapse-item__content) { + padding: 8px 10px 2px; } .manual-settle-calc-list { margin: 0; padding-left: 18px; - line-height: 1.6; - font-size: 13px; + line-height: 1.5; + font-size: 12px; } .manual-settle-calc-list li + li { @@ -1726,7 +1745,7 @@ onUnmounted(() => { } .manual-settle-form { - grid-template-columns: 1fr; + grid-template-columns: repeat(2, minmax(0, 1fr)); } } @@ -1751,6 +1770,10 @@ onUnmounted(() => { padding: 8px 10px 10px; } + .manual-settle-form { + grid-template-columns: 1fr; + } + .manual-settle-form :deep(.el-form-item) { margin-bottom: 10px; } @@ -1778,22 +1801,12 @@ onUnmounted(() => { max-width: 100%; } - .manual-settle-calc-alert { - margin-top: 10px; - } - - .manual-settle-calc-alert :deep(.el-alert__title) { - font-size: 13px; - line-height: 1.4; - } - - .manual-settle-calc-alert :deep(.el-alert__content) { - max-height: none; - overflow: visible; + .manual-settle-calc-collapse :deep(.el-collapse-item__header) { + font-size: 12px; } .manual-settle-calc-list { - font-size: 12px; + font-size: 11px; padding-left: 16px; }