2026-07-28 16:13:32 +08:00

265 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<SettlementPageFrame>
<SettlementPageHeader
icon="el-icon-circle-check"
title="审批回调"
description="处理审批结果。审批通过后自动结算记账,供应商调用 SettleAccounting分销商写入账单和账本。"
endpoint="GET /bill/finance_settlement_apv_callback.dspy"
>
<template #actions>
<button type="button" class="settlement-btn settlement-btn--primary" :disabled="loadingList" @click="loadList">
<i class="el-icon-refresh" />{{ loadingList ? '刷新中...' : '刷新' }}
</button>
</template>
</SettlementPageHeader>
<div class="settlement-split-layout">
<aside class="settlement-card settlement-selector">
<div class="settlement-card-head">
<div class="settlement-card-heading">
<i class="el-icon-filter" />
<span>审批中的结算单</span>
<small class="settlement-card-subtitle">· 2</small>
</div>
</div>
<button
v-for="row in approvalRows"
:key="row.id"
type="button"
class="settlement-selector-item"
:class="{ 'is-active': selectedRow && row.id === selectedRow.id }"
@click="selectRow(row)"
>
<span class="settlement-selector-no">{{ row.no }}</span>
<span class="settlement-selector-name">{{ row.name }}</span>
<span class="settlement-selector-date">{{ row.approvalId }}</span>
<span style="display: block; margin-top: 7px;"><SettlementStatusBadge :status="row.status" /></span>
</button>
</aside>
<main style="min-width: 0;">
<template v-if="selectedRow">
<section class="settlement-card" style="margin-bottom: 20px;">
<div class="settlement-detail-head">
<div style="display: flex; align-items: flex-start; gap: 12px;">
<span class="settlement-page-icon" style="width: 40px; height: 40px; font-size: 19px;"><i class="el-icon-document" /></span>
<div>
<div class="settlement-detail-no">
{{ selectedRow.no }}
<SettlementStatusBadge :status="selectedRow.status" />
</div>
<div class="settlement-detail-meta">
<i class="el-icon-office-building" /> {{ selectedRow.name }}
<span style="margin: 0 7px; color: #cbd5e1;">|</span>
<i class="el-icon-date" /> {{ selectedRow.start }} ~ {{ selectedRow.end }}
</div>
</div>
</div>
</div>
<div class="settlement-metric-grid settlement-metric-grid--three" style="margin: 0; padding: 0 20px 20px;">
<SettlementMetricCard label="销售金额" :value="selectedRow.sales" icon="el-icon-wallet" />
<SettlementMetricCard label="结算金额" :value="selectedRow.settlement" variant="emerald" icon="el-icon-s-order" />
<SettlementMetricCard label="平台收入" :value="selectedRow.income" variant="amber" icon="el-icon-s-marketing" />
</div>
</section>
<section class="settlement-card" style="margin-bottom: 20px;">
<div class="settlement-form-section">
<div class="settlement-section-title">
<span class="settlement-section-title-icon"><i class="el-icon-s-promotion" /></span>
<div>
<b>审批回调</b>
<span>处理审批结果</span>
</div>
</div>
<div class="settlement-form-stack">
<div class="settlement-field">
<label class="settlement-label">审批 ID *</label>
<input v-model.trim="form.apv_id" class="settlement-input" type="text" placeholder="请输入审批实例 ID">
<small style="display: block; margin-top: 6px; color: #94a3b8; font-size: 11px;">可传 apv_id approval_id</small>
</div>
<div class="settlement-field">
<label class="settlement-label">审批状态 *</label>
<div class="settlement-callback-grid">
<button type="button" class="settlement-option-card" :class="{ 'is-active': form.status === 'start' }" @click="form.status = 'start'">
<span class="settlement-option-card-head"><i class="el-icon-time" />审批中</span>
<p>审批进行中</p>
</button>
<button type="button" class="settlement-option-card" :class="{ 'is-active': form.status === 'agree' }" @click="form.status = 'agree'">
<span class="settlement-option-card-head"><i class="el-icon-circle-check" />审批通过</span>
<p>自动结算记账</p>
</button>
<button type="button" class="settlement-option-card" :class="{ 'is-active': form.status === 'refuse' }" @click="form.status = 'refuse'">
<span class="settlement-option-card-head"><i class="el-icon-circle-close" />审批拒绝</span>
<p>返回待处理状态</p>
</button>
<button type="button" class="settlement-option-card" :class="{ 'is-active': form.status === 'terminate' }" @click="form.status = 'terminate'">
<span class="settlement-option-card-head"><i class="el-icon-remove-outline" />审批撤销</span>
<p>终止当前审批流程</p>
</button>
</div>
</div>
<section class="settlement-alert" style="margin: 0;">
<span class="settlement-alert-icon"><i class="el-icon-circle-check" /></span>
<div class="settlement-alert-content">
<b>审批通过后执行记账</b>
<p>供应商结算将调用 SettleAccounting分销商结算将写入账单和账本</p>
</div>
</section>
<section v-if="result" class="settlement-alert" style="margin: 0;">
<span class="settlement-alert-icon"><i class="el-icon-circle-check" /></span>
<div class="settlement-alert-content">
<b>回调处理成功</b>
<p>结算单 ID{{ result.id || '-' }}处理状态<SettlementStatusBadge :status="result.status" /></p>
</div>
</section>
<button type="button" class="settlement-btn settlement-btn--primary" :disabled="submitting" @click="submitCallback">
<i class="el-icon-arrow-right" />{{ submitting ? '处理中...' : '提交回调' }}
</button>
</div>
</div>
</section>
<section class="settlement-card">
<div class="settlement-card-head">
<div class="settlement-card-heading">
<i class="el-icon-time" />
<span>本次会话回调记录</span>
</div>
</div>
<div v-for="item in history" :key="item.time" class="settlement-history-item">
<div class="settlement-history-top">
<span class="is-mono is-muted">{{ item.time }}</span>
<SettlementStatusBadge :status="item.status" />
</div>
<div class="settlement-history-meta">
<span>结算单<b>{{ item.no }}</b></span>
<span>审批 ID<b>{{ item.apvId }}</b></span>
<span>操作<b>{{ item.action }}</b></span>
</div>
</div>
<div v-if="!history.length" class="settlement-history-item" style="color: #94a3b8;">暂无本次会话回调记录</div>
</section>
</template>
<section v-else class="settlement-card settlement-card--padded" style="color: #94a3b8; text-align: center;">
{{ loadingList ? '正在加载审批中的结算单...' : '暂无审批中的结算单' }}
</section>
</main>
</div>
</SettlementPageFrame>
</template>
<script>
import SettlementPageFrame from './SettlementPageFrame'
import SettlementPageHeader from './SettlementPageHeader'
import SettlementMetricCard from './SettlementMetricCard'
import SettlementStatusBadge from './SettlementStatusBadge'
import { approvalCallbackAPI, settlementListAPI } from '@/api/FinancialSettlementCenter'
import {
getAccountingOrgId,
getItems,
getPayload,
normalizeSettlement
} from './settlementHelpers'
export default {
name: 'ApprovalCallback',
components: {
SettlementPageFrame,
SettlementPageHeader,
SettlementMetricCard,
SettlementStatusBadge
},
data() {
return {
loadingList: false,
submitting: false,
approvalRows: [],
selectedRow: null,
result: null,
history: [],
form: {
apv_id: '',
status: 'agree'
}
}
},
mounted() {
this.loadList()
},
methods: {
async loadList() {
const accountingOrgid = getAccountingOrgId(this.$route)
if (!accountingOrgid) {
this.$message.warning('未获取到核算机构 ID')
return
}
this.loadingList = true
try {
const payload = getPayload(await settlementListAPI({
accounting_orgid: accountingOrgid,
current_page: 1,
page_size: 100
}))
this.approvalRows = getItems(payload).map(normalizeSettlement).filter(row => {
return row.approvalId && ['approving', 'approved'].includes(row.status)
})
this.selectedRow = this.approvalRows[0] || null
this.form.apv_id = this.selectedRow ? this.selectedRow.approvalId : ''
} catch (error) {
this.$message.error(error.message || '审批中结算单查询失败')
} finally {
this.loadingList = false
}
},
selectRow(row) {
this.selectedRow = row
this.form.apv_id = row.approvalId || ''
this.result = null
},
async submitCallback() {
if (!this.form.apv_id) {
this.$message.warning('请输入审批 ID')
return
}
this.submitting = true
try {
const payload = getPayload(await approvalCallbackAPI({
apv_id: this.form.apv_id,
status: this.form.status
}))
const item = Array.isArray(payload) ? payload[0] : (getItems(payload)[0] || payload)
this.result = normalizeSettlement(item)
this.history.unshift({
time: new Date().toLocaleString('zh-CN'),
no: this.selectedRow ? this.selectedRow.no : '-',
apvId: this.form.apv_id,
action: this.getActionLabel(),
status: this.result.status
})
this.$message.success('审批回调处理成功')
await this.loadList()
} catch (error) {
this.$message.error(error.message || '审批回调处理失败')
} finally {
this.submitting = false
}
},
getActionLabel() {
return {
start: '审批中',
agree: '审批通过',
refuse: '审批拒绝',
terminate: '审批撤销'
}[this.form.status]
}
}
}
</script>