All checks were successful
Build and Deploy Front / deploy (push) Successful in 6m43s
Co-authored-by: Cursor <cursoragent@cursor.com>
247 lines
7.6 KiB
Vue
247 lines
7.6 KiB
Vue
<template>
|
|
<div class="agent-admin-commission-container">
|
|
<div class="table-toolbar">
|
|
<div class="toolbar-left">
|
|
<div class="toolbar-filters">
|
|
<a-input-number
|
|
v-model="agentId"
|
|
placeholder="代理Id"
|
|
:min="1"
|
|
allow-clear
|
|
style="width: 140px"
|
|
/>
|
|
<a-select v-model="status" allow-clear placeholder="状态" style="width: 140px">
|
|
<a-option value="pending">待结算</a-option>
|
|
<a-option value="paid">已打款</a-option>
|
|
</a-select>
|
|
<a-button class="app-btn-search" @click="handleSearch">查询</a-button>
|
|
</div>
|
|
<a-button :disabled="!selectedIds.length" @click="markPaid">标记已打款</a-button>
|
|
</div>
|
|
<div class="toolbar-right">
|
|
<a-space :size="8">
|
|
<a-button @click="loadList">刷新</a-button>
|
|
<PaginationPro
|
|
:total-count="totalCount"
|
|
v-model:current-page="currentPage"
|
|
v-model:page-size="pageSize"
|
|
@page-change="loadList"
|
|
@page-size-change="loadList"
|
|
/>
|
|
</a-space>
|
|
</div>
|
|
</div>
|
|
|
|
<a-spin :loading="listLoading" class="list-spin">
|
|
<div ref="tableContainerRef" class="list-wrap">
|
|
<HandsontablePro
|
|
:columns="hotColumns"
|
|
:data="tableRows"
|
|
:total="totalCount"
|
|
:current-page="currentPage"
|
|
:page-size="pageSize"
|
|
:stretch-columns="true"
|
|
:height="handsontableHeight"
|
|
:read-only="true"
|
|
:show-action-column="true"
|
|
:action-renderer="actionRenderer"
|
|
:show-checkbox-column="true"
|
|
@selection-change="onSelectionChange"
|
|
:custom-cell-renderer="customCellRenderer"
|
|
@action-click="handleActionClick"
|
|
/>
|
|
</div>
|
|
</a-spin>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed, onMounted, ref } from 'vue'
|
|
import { Message } from '@arco-design/web-vue'
|
|
import HandsontablePro from '@/components/HandsontablePro/index.vue'
|
|
import PaginationPro from '@/components/PaginationPro/index.vue'
|
|
import { useTableContainerHeight } from '@/composables/useTableContainerHeight'
|
|
import { buildStatusTagHtml } from '@/utils/statusTag'
|
|
import { renderWarehouseActionBtn, wrapWarehouseActions } from '@/utils/warehouseActionRenderer'
|
|
import { AgentAdminApi, type AgentCommissionDto } from '@/api/agent'
|
|
|
|
defineOptions({ name: 'AgentAdminCommission' })
|
|
|
|
const { tableContainerRef, tableHeight } = useTableContainerHeight()
|
|
const handsontableHeight = computed(() => Math.max(tableHeight.value || 0, 400))
|
|
|
|
interface CommissionRow {
|
|
id: number
|
|
agentCode: string
|
|
agentName: string
|
|
serviceNo: string
|
|
customerCode: string
|
|
customerName: string
|
|
baseType: string
|
|
baseAmount: number
|
|
commissionRate: number
|
|
commissionAmount: number
|
|
status: string
|
|
statusName: string
|
|
triggerOrderStatus: string
|
|
createTime: string
|
|
}
|
|
|
|
const tableRows = ref<CommissionRow[]>([])
|
|
const totalCount = ref(0)
|
|
const listLoading = ref(false)
|
|
const agentId = ref<number | undefined>()
|
|
const status = ref<string | undefined>()
|
|
const currentPage = ref(1)
|
|
const pageSize = ref(50)
|
|
const selectedRows = ref<CommissionRow[]>([])
|
|
const selectedIds = computed(() => selectedRows.value.map((x) => x.id).filter((x) => x > 0))
|
|
|
|
const hotColumns = computed(() => [
|
|
{ key: 'agentCode', label: '代理编号', width: 110 },
|
|
{ key: 'serviceNo', label: '运单号', width: 140 },
|
|
{ key: 'customerCode', label: '客户编号', width: 110 },
|
|
{ key: 'baseType', label: '基数类型', width: 100 },
|
|
{ key: 'baseAmount', label: '基数', width: 100 },
|
|
{ key: 'commissionRate', label: '比例', width: 80 },
|
|
{ key: 'commissionAmount', label: '返佣金额', width: 100 },
|
|
{ key: 'statusName', label: '状态', width: 90 },
|
|
{ key: 'triggerOrderStatus', label: '触发状态', width: 120 },
|
|
{ key: 'createTime', label: '计提时间', width: 160 },
|
|
])
|
|
|
|
function pick(row: Record<string, unknown>, camel: string, pascal: string) {
|
|
return row[camel] ?? row[pascal]
|
|
}
|
|
|
|
function mapRow(raw: AgentCommissionDto): CommissionRow {
|
|
const r = raw as unknown as Record<string, unknown>
|
|
const st = String(pick(r, 'status', 'Status') ?? '')
|
|
return {
|
|
id: Number(pick(r, 'id', 'Id') ?? 0),
|
|
agentCode: String(pick(r, 'agentCode', 'AgentCode') ?? ''),
|
|
agentName: String(pick(r, 'agentName', 'AgentName') ?? ''),
|
|
serviceNo: String(pick(r, 'serviceNo', 'ServiceNo') ?? ''),
|
|
customerCode: String(pick(r, 'customerCode', 'CustomerCode') ?? ''),
|
|
customerName: String(pick(r, 'customerName', 'CustomerName') ?? ''),
|
|
baseType: String(pick(r, 'baseType', 'BaseType') ?? ''),
|
|
baseAmount: Number(pick(r, 'baseAmount', 'BaseAmount') ?? 0),
|
|
commissionRate: Number(pick(r, 'commissionRate', 'CommissionRate') ?? 0),
|
|
commissionAmount: Number(pick(r, 'commissionAmount', 'CommissionAmount') ?? 0),
|
|
status: st,
|
|
statusName: st === 'paid' ? '已打款' : '待结算',
|
|
triggerOrderStatus: String(pick(r, 'triggerOrderStatus', 'TriggerOrderStatus') ?? ''),
|
|
createTime: String(pick(r, 'createTime', 'CreateTime') ?? ''),
|
|
}
|
|
}
|
|
|
|
function actionRenderer(row: CommissionRow, rowIndex: number): string {
|
|
if (row.status === 'paid') {
|
|
return '<span style="color:var(--color-text-3);font-size:12px;">--</span>'
|
|
}
|
|
return wrapWarehouseActions(
|
|
[renderWarehouseActionBtn('markPaid', '标记已打款', 'pay')],
|
|
rowIndex,
|
|
)
|
|
}
|
|
|
|
function handleActionClick(row: CommissionRow, _rowIndex: number, action?: string) {
|
|
if (action === 'markPaid') void markPaidIds([row.id])
|
|
}
|
|
|
|
function customCellRenderer(_row: number, col: number, _value: unknown, rowData: CommissionRow): string | null {
|
|
// 操作列 + 序号列 + 复选框列
|
|
const dataColIndex = col - 3
|
|
if (dataColIndex < 0 || dataColIndex >= hotColumns.value.length) return null
|
|
const colKey = hotColumns.value[dataColIndex].key
|
|
if (colKey === 'statusName') {
|
|
return buildStatusTagHtml(rowData.statusName, rowData.status === 'paid' ? 'ok' : 'wait')
|
|
}
|
|
return null
|
|
}
|
|
|
|
function onSelectionChange(rows: CommissionRow[]) {
|
|
selectedRows.value = rows || []
|
|
}
|
|
|
|
async function loadList() {
|
|
listLoading.value = true
|
|
try {
|
|
const res = await AgentAdminApi.commissionList({
|
|
page: currentPage.value,
|
|
pageSize: pageSize.value,
|
|
agentId: agentId.value,
|
|
status: status.value,
|
|
})
|
|
tableRows.value = (res.items || []).map(mapRow)
|
|
totalCount.value = res.total
|
|
selectedRows.value = []
|
|
} catch (e: any) {
|
|
Message.error(e?.message || '加载失败')
|
|
} finally {
|
|
listLoading.value = false
|
|
}
|
|
}
|
|
|
|
function handleSearch() {
|
|
currentPage.value = 1
|
|
void loadList()
|
|
}
|
|
|
|
async function markPaidIds(ids: number[]) {
|
|
const valid = ids.map(Number).filter((x) => x > 0)
|
|
if (!valid.length) return
|
|
try {
|
|
await AgentAdminApi.markPaid(valid)
|
|
Message.success('已标记')
|
|
await loadList()
|
|
} catch (e: any) {
|
|
Message.error(e?.message || '操作失败')
|
|
}
|
|
}
|
|
|
|
async function markPaid() {
|
|
await markPaidIds(selectedIds.value)
|
|
}
|
|
|
|
onMounted(() => void loadList())
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.agent-admin-commission-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
min-height: 0;
|
|
padding: 16px;
|
|
background: #fff;
|
|
}
|
|
.table-toolbar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 12px;
|
|
gap: 12px;
|
|
}
|
|
.toolbar-left {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
.toolbar-filters {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
.list-spin {
|
|
flex: 1;
|
|
min-height: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.list-wrap {
|
|
flex: 1;
|
|
min-height: 0;
|
|
}
|
|
</style>
|