feat(closed-loop): complete end-to-end closed loops across miniapp, backend, and admin
这个提交包含在:
@@ -93,28 +93,28 @@
|
||||
</div>
|
||||
</a-grid-item>
|
||||
|
||||
<!-- 4. 高危场所风控拦截 -->
|
||||
<!-- 4. 违规举报与高危风控 -->
|
||||
<a-grid-item :span="{ xs: 24, sm: 12, md: 6, lg: 6, xl: 6 }">
|
||||
<div
|
||||
class="decision-card purple-card"
|
||||
@click="router.push('/safety/audit-log')"
|
||||
@click="router.push('/safety/reports')"
|
||||
>
|
||||
<div class="card-icon-wrap">
|
||||
<icon-safe class="card-icon" />
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="card-label">高危私密场所拦截</div>
|
||||
<div class="card-label">违规举报与风控工单</div>
|
||||
<div class="card-num">
|
||||
{{ todos.riskInterceptionsCount }}
|
||||
<span class="unit">次风险阻断</span>
|
||||
{{ todos.pendingReportsCount !== undefined ? todos.pendingReportsCount : todos.riskInterceptionsCount }}
|
||||
<span class="unit">条待处理举报</span>
|
||||
</div>
|
||||
<div class="card-hint">
|
||||
私人住宅/酒店客房红线拦截
|
||||
含高危拦截 {{ todos.riskInterceptionsCount }} 次 · 点击处置
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<a-button type="outline" size="mini">
|
||||
风控日志
|
||||
举报工单
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -135,6 +135,7 @@
|
||||
pendingArbitrationsCount: 1,
|
||||
pendingWithdrawalsCount: 1,
|
||||
pendingWithdrawalAmount: 1250,
|
||||
pendingReportsCount: 1,
|
||||
riskInterceptionsCount: 3,
|
||||
});
|
||||
|
||||
@@ -142,7 +143,8 @@
|
||||
return (
|
||||
todos.value.pendingAuditsCount +
|
||||
todos.value.pendingArbitrationsCount +
|
||||
todos.value.pendingWithdrawalsCount
|
||||
todos.value.pendingWithdrawalsCount +
|
||||
(todos.value.pendingReportsCount || 0)
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -68,6 +68,24 @@
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 待核实违规举报 -->
|
||||
<div v-for="rep in pendingReports" :key="rep.id" class="todo-item arb-item">
|
||||
<div class="item-header">
|
||||
<a-tag color="purple" size="small">违规举报</a-tag>
|
||||
<span class="item-name">{{ rep.reporterName }} 举报 {{ rep.targetName }}</span>
|
||||
</div>
|
||||
<div class="item-desc">
|
||||
{{ rep.reason }} · {{ rep.description || '待风控核实' }}
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
<router-link to="/safety/reports">
|
||||
<a-button type="primary" size="mini">
|
||||
核实处理
|
||||
</a-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
@@ -80,6 +98,7 @@
|
||||
const pendingAudits = ref<any[]>([]);
|
||||
const pendingWithdrawals = ref<any[]>([]);
|
||||
const pendingArbitrations = ref<any[]>([]);
|
||||
const pendingReports = ref<any[]>([]);
|
||||
|
||||
const fetchQuickTodos = async () => {
|
||||
try {
|
||||
@@ -88,6 +107,7 @@
|
||||
pendingAudits.value = (res.data.pendingAudits || []).slice(0, 1);
|
||||
pendingWithdrawals.value = (res.data.pendingWithdrawals || []).slice(0, 1);
|
||||
pendingArbitrations.value = (res.data.pendingArbitrations || []).slice(0, 1);
|
||||
pendingReports.value = (res.data.pendingReports || []).slice(0, 1);
|
||||
}
|
||||
} catch {
|
||||
// 保持兜底
|
||||
|
||||
在新工单中引用
屏蔽一个用户