<!DOCTYPE html>
|
<html lang="zh-CN">
|
<head>
|
<meta charset="UTF-8" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<title>通知上报</title>
|
<link rel="stylesheet" href="../../static/vue/element/element.css" />
|
<style>
|
[v-cloak] {
|
display: none;
|
}
|
|
html,
|
body {
|
margin: 0;
|
min-height: 100%;
|
font-family: "Avenir Next", "PingFang SC", "Microsoft YaHei", sans-serif;
|
background:
|
radial-gradient(1200px 420px at 0% -5%, rgba(36, 91, 160, 0.14), transparent 55%),
|
radial-gradient(1000px 500px at 100% 0%, rgba(35, 147, 120, 0.11), transparent 60%),
|
linear-gradient(180deg, #f2f6fb 0%, #edf2f7 100%);
|
color: #243447;
|
}
|
|
.page-shell {
|
max-width: 1680px;
|
margin: 0 auto;
|
padding: 16px;
|
box-sizing: border-box;
|
}
|
|
.hero {
|
border-radius: 18px;
|
padding: 18px 20px 16px;
|
color: #fff;
|
background: linear-gradient(135deg, #114a7a 0%, #226ca1 44%, #1f9c8c 100%);
|
box-shadow: 0 18px 36px rgba(17, 74, 122, 0.22);
|
margin-bottom: 14px;
|
overflow: hidden;
|
position: relative;
|
}
|
|
.hero::after {
|
content: "";
|
position: absolute;
|
right: -60px;
|
top: -90px;
|
width: 280px;
|
height: 280px;
|
border-radius: 50%;
|
background: rgba(255, 255, 255, 0.08);
|
filter: blur(2px);
|
}
|
|
.hero-head {
|
position: relative;
|
z-index: 1;
|
display: flex;
|
align-items: flex-start;
|
justify-content: space-between;
|
gap: 12px;
|
flex-wrap: wrap;
|
}
|
|
.hero-title {
|
display: flex;
|
flex-direction: column;
|
gap: 6px;
|
}
|
|
.hero-title-main {
|
font-size: 22px;
|
font-weight: 700;
|
letter-spacing: 0.4px;
|
}
|
|
.hero-title-sub {
|
font-size: 13px;
|
opacity: 0.9;
|
max-width: 760px;
|
line-height: 1.6;
|
}
|
|
.hero-actions {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
flex-wrap: wrap;
|
}
|
|
.summary-grid {
|
position: relative;
|
z-index: 1;
|
margin-top: 16px;
|
display: grid;
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
gap: 10px;
|
}
|
|
.summary-card {
|
min-height: 78px;
|
border-radius: 14px;
|
padding: 12px 14px;
|
background: rgba(255, 255, 255, 0.15);
|
border: 1px solid rgba(255, 255, 255, 0.22);
|
backdrop-filter: blur(3px);
|
}
|
|
.summary-card .label {
|
font-size: 12px;
|
opacity: 0.86;
|
}
|
|
.summary-card .value {
|
margin-top: 7px;
|
font-size: 24px;
|
font-weight: 700;
|
line-height: 1.15;
|
word-break: break-all;
|
}
|
|
.summary-card .sub {
|
margin-top: 6px;
|
font-size: 12px;
|
opacity: 0.88;
|
word-break: break-all;
|
}
|
|
.panel {
|
border-radius: 18px;
|
border: 1px solid #dbe4ef;
|
background:
|
radial-gradient(700px 220px at -10% 0%, rgba(41, 112, 196, 0.05), transparent 55%),
|
radial-gradient(860px 260px at 110% 16%, rgba(31, 156, 140, 0.06), transparent 58%),
|
rgba(250, 252, 255, 0.88);
|
box-shadow: 0 16px 32px rgba(39, 63, 92, 0.08);
|
overflow: hidden;
|
}
|
|
.toolbar-card {
|
padding: 16px 16px 6px;
|
margin-bottom: 14px;
|
}
|
|
.toolbar-title {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 10px;
|
margin-bottom: 14px;
|
flex-wrap: wrap;
|
}
|
|
.toolbar-title .main {
|
font-size: 16px;
|
font-weight: 700;
|
color: #243447;
|
}
|
|
.toolbar-title .sub {
|
font-size: 12px;
|
color: #7b8ba1;
|
}
|
|
.filter-grid {
|
display: grid;
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
gap: 12px;
|
}
|
|
.filter-item.full {
|
grid-column: span 2;
|
}
|
|
.filter-actions {
|
margin-top: 14px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 12px;
|
flex-wrap: wrap;
|
}
|
|
.filter-actions-left,
|
.filter-actions-right {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
flex-wrap: wrap;
|
}
|
|
.board {
|
padding: 14px;
|
}
|
|
.board-head {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 10px;
|
margin-bottom: 12px;
|
flex-wrap: wrap;
|
}
|
|
.board-head .title {
|
font-size: 15px;
|
font-weight: 700;
|
color: #26384d;
|
}
|
|
.board-head .desc {
|
font-size: 12px;
|
color: #8594a8;
|
}
|
|
.board .el-tabs__nav-wrap::after {
|
background: rgba(222, 230, 238, 0.86);
|
}
|
|
.table-shell {
|
border-radius: 16px;
|
overflow: hidden;
|
border: 1px solid #e0e8f2;
|
background: rgba(255, 255, 255, 0.9);
|
}
|
|
.table-toolbar {
|
padding: 12px 12px 0;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 10px;
|
flex-wrap: wrap;
|
}
|
|
.table-toolbar-left,
|
.table-toolbar-right {
|
display: flex;
|
align-items: center;
|
gap: 10px;
|
flex-wrap: wrap;
|
}
|
|
.table-note {
|
font-size: 12px;
|
color: #8090a4;
|
}
|
|
.code-text {
|
font-family: Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
font-size: 12px;
|
}
|
|
.payload-box {
|
max-height: 62vh;
|
overflow: auto;
|
border-radius: 12px;
|
border: 1px solid #d9e4f0;
|
background: linear-gradient(180deg, #fbfdff 0%, #f4f8fc 100%);
|
padding: 14px;
|
margin: 0;
|
white-space: pre-wrap;
|
word-break: break-word;
|
line-height: 1.65;
|
color: #28405a;
|
font-family: Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
font-size: 12px;
|
}
|
|
.pagination-wrap {
|
padding: 12px 14px 14px;
|
display: flex;
|
justify-content: flex-end;
|
background: rgba(255, 255, 255, 0.72);
|
}
|
|
.empty-hint {
|
padding: 34px 12px;
|
text-align: center;
|
color: #8c9aae;
|
font-size: 13px;
|
}
|
|
@media (max-width: 1360px) {
|
.summary-grid {
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
}
|
|
.filter-grid {
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
}
|
|
.filter-item.full {
|
grid-column: span 1;
|
}
|
}
|
|
@media (max-width: 900px) {
|
.page-shell {
|
padding: 10px;
|
}
|
|
.summary-grid,
|
.filter-grid {
|
grid-template-columns: 1fr;
|
}
|
|
.hero-title-main {
|
font-size: 18px;
|
}
|
|
.table-toolbar,
|
.filter-actions {
|
align-items: flex-start;
|
}
|
|
.pagination-wrap {
|
justify-content: center;
|
}
|
}
|
</style>
|
</head>
|
<body>
|
<div id="app" class="page-shell" v-cloak>
|
<section class="hero">
|
<div class="hero-head">
|
<div class="hero-title">
|
<div class="hero-title-main">通知上报中心</div>
|
<div class="hero-title-sub">查看当前待通知队列、接口发送日志,支持按任务/设备快速筛选,并对失败或待发送通知执行手动补发。</div>
|
</div>
|
<div class="hero-actions">
|
<el-button type="primary" icon="el-icon-refresh" :loading="summaryLoading" @click="refreshAll">刷新全局</el-button>
|
</div>
|
</div>
|
<div class="summary-grid">
|
<div class="summary-card">
|
<div class="label">上报开关</div>
|
<div class="value">{{ summary['notifyEnable$'] || '-' }}</div>
|
<div class="sub">`notifyEnable` = {{ summary.notifyEnable || '-' }}</div>
|
</div>
|
<div class="summary-card">
|
<div class="label">当前队列数</div>
|
<div class="value">{{ summary.queueCount || 0 }}</div>
|
<div class="sub">Redis 中待上报或待重试通知</div>
|
</div>
|
<div class="summary-card">
|
<div class="label">通知日志数</div>
|
<div class="value">{{ summary.logCount || 0 }}</div>
|
<div class="sub">通知接口历史调用记录</div>
|
</div>
|
<div class="summary-card">
|
<div class="label">通知地址</div>
|
<div class="value" style="font-size: 16px;">{{ summary.notifyEndpoint || '-' }}</div>
|
<div class="sub">来源:notifyUri + notifyUriPath</div>
|
</div>
|
</div>
|
</section>
|
|
<section class="panel toolbar-card">
|
<div class="toolbar-title">
|
<div>
|
<div class="main">筛选条件</div>
|
<div class="sub">队列与日志共用同一组查询条件,切换页签时保持一致。</div>
|
</div>
|
</div>
|
|
<div class="filter-grid">
|
<div class="filter-item">
|
<el-select v-model="filters.notifyType" clearable placeholder="通知类型" size="medium">
|
<el-option label="堆垛机" value="Crn"></el-option>
|
<el-option label="双伸位堆垛机" value="DualCrn"></el-option>
|
<el-option label="输送线" value="Devp"></el-option>
|
<el-option label="RGV" value="Rgv"></el-option>
|
<el-option label="任务" value="task"></el-option>
|
</el-select>
|
</div>
|
<div class="filter-item">
|
<el-input v-model.trim="filters.device" placeholder="设备号" clearable></el-input>
|
</div>
|
<div class="filter-item">
|
<el-input v-model.trim="filters.taskNo" placeholder="任务号" clearable></el-input>
|
</div>
|
<div class="filter-item">
|
<el-input v-model.trim="filters.superTaskNo" placeholder="上级任务号" clearable></el-input>
|
</div>
|
<div class="filter-item">
|
<el-input v-model.trim="filters.msgType" placeholder="消息类型/描述" clearable></el-input>
|
</div>
|
<div class="filter-item">
|
<el-select v-model="filters.result" clearable placeholder="日志结果">
|
<el-option label="成功" :value="1"></el-option>
|
<el-option label="失败" :value="0"></el-option>
|
</el-select>
|
</div>
|
<div class="filter-item full">
|
<el-input v-model.trim="filters.condition" placeholder="通用搜索:任务号、消息描述、报文关键字、Redis Key" clearable></el-input>
|
</div>
|
</div>
|
|
<div class="filter-actions">
|
<div class="filter-actions-left">
|
<el-button type="primary" icon="el-icon-search" :loading="queue.loading || log.loading" @click="handleSearch">查询</el-button>
|
<el-button icon="el-icon-refresh-left" @click="handleReset">重置</el-button>
|
</div>
|
<div class="filter-actions-right">
|
<span class="table-note">当前页签:{{ activeTab === 'queue' ? '通知队列' : '发送日志' }}</span>
|
</div>
|
</div>
|
</section>
|
|
<section class="panel board">
|
<div class="board-head">
|
<div>
|
<div class="title">通知查看与补发</div>
|
<div class="desc">当前队列显示 Redis 实时数据,发送日志显示历史接口调用结果。</div>
|
</div>
|
</div>
|
|
<el-tabs v-model="activeTab" @tab-click="handleTabChange">
|
<el-tab-pane label="当前通知队列" name="queue">
|
<div class="table-shell">
|
<div class="table-toolbar">
|
<div class="table-toolbar-left">
|
<el-button type="primary" size="mini" icon="el-icon-position" :disabled="queue.selection.length === 0" :loading="resendLoading" @click="batchResendQueue">批量补发</el-button>
|
<span class="table-note">已选 {{ queue.selection.length }} 条</span>
|
</div>
|
<div class="table-toolbar-right">
|
<span class="table-note">展示待发送和待重试通知</span>
|
</div>
|
</div>
|
<el-table
|
:data="queue.records"
|
border
|
stripe
|
height="520"
|
v-loading="queue.loading"
|
@selection-change="queue.selection = $event"
|
:header-cell-style="headerCellStyle">
|
<el-table-column type="selection" width="48"></el-table-column>
|
<el-table-column prop="id" label="通知ID" min-width="180" show-overflow-tooltip>
|
<template slot-scope="scope">
|
<span class="code-text">{{ scope.row.id }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="notifyType$" label="通知类型" width="120"></el-table-column>
|
<el-table-column prop="device" label="设备号" width="88"></el-table-column>
|
<el-table-column prop="taskNo" label="任务号" min-width="120" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="superTaskNo" label="上级任务号" min-width="130" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="msgDesc" label="消息描述" min-width="180" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="retryProgress$" label="重试次数" width="88"></el-table-column>
|
<el-table-column prop="retryTime" label="间隔(s)" width="84"></el-table-column>
|
<el-table-column prop="lastRetryTime$" label="上次重试时间" width="168"></el-table-column>
|
<el-table-column label="队列状态" width="104">
|
<template slot-scope="scope">
|
<el-tag size="mini" :type="scope.row.queueStatus$ === '待发送' ? 'success' : 'warning'">{{ scope.row.queueStatus$ || '-' }}</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" width="170" fixed="right">
|
<template slot-scope="scope">
|
<el-button type="text" size="mini" @click="openPayload('通知报文', scope.row.requestPayload)">查看报文</el-button>
|
<el-button type="text" size="mini" @click="resendQueueRow(scope.row)">补发</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div v-if="!queue.loading && queue.records.length === 0" class="empty-hint">当前没有待发送通知</div>
|
<div class="pagination-wrap">
|
<el-pagination
|
background
|
layout="total, sizes, prev, pager, next, jumper"
|
:current-page="queue.page.curr"
|
:page-sizes="[15, 30, 50, 100, 200]"
|
:page-size="queue.page.limit"
|
:total="queue.page.total"
|
@size-change="handleQueueSizeChange"
|
@current-change="handleQueuePageChange">
|
</el-pagination>
|
</div>
|
</div>
|
</el-tab-pane>
|
|
<el-tab-pane label="通知发送日志" name="log">
|
<div class="table-shell">
|
<div class="table-toolbar">
|
<div class="table-toolbar-left">
|
<el-button type="primary" size="mini" icon="el-icon-position" :disabled="log.selection.length === 0" :loading="resendLoading" @click="batchResendLog">批量补发</el-button>
|
<span class="table-note">已选 {{ log.selection.length }} 条</span>
|
</div>
|
<div class="table-toolbar-right">
|
<span class="table-note">支持从历史日志重新发送通知</span>
|
</div>
|
</div>
|
<el-table
|
:data="log.records"
|
border
|
stripe
|
height="520"
|
v-loading="log.loading"
|
@selection-change="log.selection = $event"
|
:header-cell-style="headerCellStyle">
|
<el-table-column type="selection" width="48"></el-table-column>
|
<el-table-column prop="createTime$" label="发送时间" width="166"></el-table-column>
|
<el-table-column label="结果" width="84">
|
<template slot-scope="scope">
|
<el-tag v-if="scope.row.result === 1" size="mini" type="success">成功</el-tag>
|
<el-tag v-else-if="scope.row.result === 0" size="mini" type="danger">失败</el-tag>
|
<span v-else>-</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="notifyType$" label="通知类型" width="120"></el-table-column>
|
<el-table-column prop="device" label="设备号" width="88"></el-table-column>
|
<el-table-column prop="taskNo" label="任务号" min-width="120" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="superTaskNo" label="上级任务号" min-width="130" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="msgDesc" label="消息描述" min-width="180" show-overflow-tooltip></el-table-column>
|
<el-table-column label="操作" width="250" fixed="right">
|
<template slot-scope="scope">
|
<el-button type="text" size="mini" @click="openPayload('通知报文', scope.row.requestPayload)">查看报文</el-button>
|
<el-button type="text" size="mini" @click="openPayload('接口响应', scope.row.response)">查看响应</el-button>
|
<el-button type="text" size="mini" @click="resendLogRow(scope.row)">补发</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div v-if="!log.loading && log.records.length === 0" class="empty-hint">当前筛选条件下没有通知日志</div>
|
<div class="pagination-wrap">
|
<el-pagination
|
background
|
layout="total, sizes, prev, pager, next, jumper"
|
:current-page="log.page.curr"
|
:page-sizes="[15, 30, 50, 100, 200]"
|
:page-size="log.page.limit"
|
:total="log.page.total"
|
@size-change="handleLogSizeChange"
|
@current-change="handleLogPageChange">
|
</el-pagination>
|
</div>
|
</div>
|
</el-tab-pane>
|
</el-tabs>
|
</section>
|
|
<el-dialog :title="dialog.title" :visible.sync="dialog.visible" width="72%" :close-on-click-modal="false">
|
<pre class="payload-box">{{ dialog.content || '-' }}</pre>
|
</el-dialog>
|
</div>
|
|
<script type="text/javascript" src="../../static/vue/js/vue.min.js"></script>
|
<script type="text/javascript" src="../../static/vue/element/element.js"></script>
|
<script type="text/javascript" src="../../static/js/common.js" charset="utf-8"></script>
|
<script>
|
new Vue({
|
el: '#app',
|
data: function () {
|
return {
|
activeTab: 'queue',
|
summaryLoading: false,
|
resendLoading: false,
|
summary: {},
|
filters: {
|
notifyType: '',
|
device: '',
|
taskNo: '',
|
superTaskNo: '',
|
msgType: '',
|
result: null,
|
condition: ''
|
},
|
queue: {
|
loading: false,
|
records: [],
|
selection: [],
|
page: {
|
curr: 1,
|
limit: 15,
|
total: 0
|
}
|
},
|
log: {
|
loading: false,
|
records: [],
|
selection: [],
|
page: {
|
curr: 1,
|
limit: 15,
|
total: 0
|
}
|
},
|
dialog: {
|
visible: false,
|
title: '',
|
content: ''
|
},
|
headerCellStyle: {
|
background: '#f7f9fc',
|
color: '#2d4058',
|
fontWeight: 600
|
}
|
};
|
},
|
created: function () {
|
this.refreshAll();
|
},
|
methods: {
|
buildFilterParams: function (includeResult) {
|
var params = {};
|
var filters = this.filters;
|
if (filters.notifyType) params.notifyType = filters.notifyType;
|
if (filters.device !== '' && filters.device !== null && filters.device !== undefined) {
|
params.device = filters.device;
|
}
|
if (filters.taskNo) params.taskNo = filters.taskNo;
|
if (filters.superTaskNo) params.superTaskNo = filters.superTaskNo;
|
if (filters.msgType) params.msgType = filters.msgType;
|
if (filters.condition) params.condition = filters.condition;
|
if (includeResult && filters.result !== '' && filters.result !== null && filters.result !== undefined) {
|
params.result = filters.result;
|
}
|
return params;
|
},
|
buildQueryString: function (params) {
|
var search = [];
|
Object.keys(params).forEach(function (key) {
|
if (params[key] === '' || params[key] === null || params[key] === undefined) {
|
return;
|
}
|
search.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
|
});
|
return search.join('&');
|
},
|
fetchJson: function (url, options) {
|
var requestOptions = options || {};
|
requestOptions.headers = requestOptions.headers || {};
|
requestOptions.headers.token = localStorage.getItem('token');
|
if (requestOptions.body && !requestOptions.headers['Content-Type']) {
|
requestOptions.headers['Content-Type'] = 'application/json;charset=UTF-8';
|
}
|
return fetch(url, requestOptions).then(function (response) {
|
return response.json();
|
});
|
},
|
ensureSuccess: function (res, fallback) {
|
if (res && res.code === 403) {
|
top.location.href = baseUrl + '/';
|
return false;
|
}
|
if (!res || res.code !== 200) {
|
this.$message.error((res && res.msg) || fallback || '请求失败');
|
return false;
|
}
|
return true;
|
},
|
refreshAll: function () {
|
this.loadSummary();
|
this.loadQueue();
|
this.loadLog();
|
},
|
loadSummary: function () {
|
var self = this;
|
self.summaryLoading = true;
|
self.fetchJson(baseUrl + '/notifyReport/summary/auth')
|
.then(function (res) {
|
if (!self.ensureSuccess(res, '获取通知概览失败')) {
|
return;
|
}
|
self.summary = res.data || {};
|
})
|
.finally(function () {
|
self.summaryLoading = false;
|
});
|
},
|
loadQueue: function () {
|
var self = this;
|
self.queue.loading = true;
|
var params = self.buildFilterParams(false);
|
params.curr = self.queue.page.curr;
|
params.limit = self.queue.page.limit;
|
self.fetchJson(baseUrl + '/notifyReport/queue/list/auth?' + self.buildQueryString(params))
|
.then(function (res) {
|
if (!self.ensureSuccess(res, '获取通知队列失败')) {
|
return;
|
}
|
self.queue.records = (res.data && res.data.records) || [];
|
self.queue.page.total = (res.data && res.data.total) || 0;
|
self.queue.selection = [];
|
})
|
.finally(function () {
|
self.queue.loading = false;
|
});
|
},
|
loadLog: function () {
|
var self = this;
|
self.log.loading = true;
|
var params = self.buildFilterParams(true);
|
params.curr = self.log.page.curr;
|
params.limit = self.log.page.limit;
|
self.fetchJson(baseUrl + '/notifyReport/log/list/auth?' + self.buildQueryString(params))
|
.then(function (res) {
|
if (!self.ensureSuccess(res, '获取通知日志失败')) {
|
return;
|
}
|
self.log.records = (res.data && res.data.records) || [];
|
self.log.page.total = (res.data && res.data.total) || 0;
|
self.log.selection = [];
|
})
|
.finally(function () {
|
self.log.loading = false;
|
});
|
},
|
handleSearch: function () {
|
this.queue.page.curr = 1;
|
this.log.page.curr = 1;
|
this.refreshAll();
|
},
|
handleReset: function () {
|
this.filters = {
|
notifyType: '',
|
device: '',
|
taskNo: '',
|
superTaskNo: '',
|
msgType: '',
|
result: null,
|
condition: ''
|
};
|
this.queue.page.curr = 1;
|
this.log.page.curr = 1;
|
this.refreshAll();
|
},
|
handleTabChange: function () {
|
if (this.activeTab === 'queue' && this.queue.records.length === 0) {
|
this.loadQueue();
|
return;
|
}
|
if (this.activeTab === 'log' && this.log.records.length === 0) {
|
this.loadLog();
|
}
|
},
|
handleQueuePageChange: function (page) {
|
this.queue.page.curr = page;
|
this.loadQueue();
|
},
|
handleQueueSizeChange: function (size) {
|
this.queue.page.limit = size;
|
this.queue.page.curr = 1;
|
this.loadQueue();
|
},
|
handleLogPageChange: function (page) {
|
this.log.page.curr = page;
|
this.loadLog();
|
},
|
handleLogSizeChange: function (size) {
|
this.log.page.limit = size;
|
this.log.page.curr = 1;
|
this.loadLog();
|
},
|
openPayload: function (title, content) {
|
this.dialog.title = title;
|
this.dialog.content = content || '';
|
this.dialog.visible = true;
|
},
|
resendRequest: function (payload) {
|
var self = this;
|
self.resendLoading = true;
|
return self.fetchJson(baseUrl + '/notifyReport/resend/auth', {
|
method: 'POST',
|
body: JSON.stringify(payload)
|
}).then(function (res) {
|
if (!self.ensureSuccess(res, '补发失败')) {
|
return;
|
}
|
var data = res.data || {};
|
var message = '成功 ' + (data.successCount || 0) + ' 条';
|
if ((data.failCount || 0) > 0) {
|
message += ',失败 ' + data.failCount + ' 条';
|
}
|
self.$message({
|
type: (data.failCount || 0) > 0 ? 'warning' : 'success',
|
message: message
|
});
|
self.loadSummary();
|
self.loadQueue();
|
self.loadLog();
|
if ((data.failCount || 0) > 0) {
|
self.openPayload('补发结果', JSON.stringify(data.details || [], null, 2));
|
}
|
}).finally(function () {
|
self.resendLoading = false;
|
});
|
},
|
confirmResend: function (payload, title) {
|
var self = this;
|
self.$confirm(title || '确定执行手动补发吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(function () {
|
self.resendRequest(payload);
|
}).catch(function () {});
|
},
|
resendQueueRow: function (row) {
|
this.confirmResend({
|
sourceType: 'queue',
|
redisKeys: [row.redisKey]
|
}, '确定补发该队列通知吗?');
|
},
|
resendLogRow: function (row) {
|
this.confirmResend({
|
sourceType: 'log',
|
logIds: [row.logId]
|
}, '确定按该日志重新补发通知吗?');
|
},
|
batchResendQueue: function () {
|
var keys = this.queue.selection.map(function (item) {
|
return item.redisKey;
|
});
|
if (keys.length === 0) {
|
this.$message.warning('请选择要补发的队列通知');
|
return;
|
}
|
this.confirmResend({
|
sourceType: 'queue',
|
redisKeys: keys
|
}, '确定批量补发选中的队列通知吗?');
|
},
|
batchResendLog: function () {
|
var ids = this.log.selection.map(function (item) {
|
return item.logId;
|
});
|
if (ids.length === 0) {
|
this.$message.warning('请选择要补发的通知日志');
|
return;
|
}
|
this.confirmResend({
|
sourceType: 'log',
|
logIds: ids
|
}, '确定批量补发选中的通知日志吗?');
|
}
|
}
|
});
|
</script>
|
</body>
|
</html>
|