mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 10:00:30 +08:00
feat(m5): add failure reason tagging and batch retry
This commit is contained in:
@@ -62,6 +62,14 @@
|
|||||||
<div v-if="isPending" class="status-row">
|
<div v-if="isPending" class="status-row">
|
||||||
<el-button v-permission="'callback:process'" type="success" :loading="patchingStatus" @click="setStatus('PROCESSED')">标为已处理</el-button>
|
<el-button v-permission="'callback:process'" type="success" :loading="patchingStatus" @click="setStatus('PROCESSED')">标为已处理</el-button>
|
||||||
<el-button v-permission="'callback:process'" type="danger" :loading="patchingStatus" @click="setStatus('FAILED')">标为失败</el-button>
|
<el-button v-permission="'callback:process'" type="danger" :loading="patchingStatus" @click="setStatus('FAILED')">标为失败</el-button>
|
||||||
|
<el-select v-model="failureReason" clearable placeholder="失败原因" style="width: 180px">
|
||||||
|
<el-option label="SN未关联合同" value="SN_NOT_LINKED" />
|
||||||
|
<el-option label="网络超时" value="NETWORK_TIMEOUT" />
|
||||||
|
<el-option label="SN已吊销" value="SN_REVOKED" />
|
||||||
|
<el-option label="设备指纹不匹配" value="DEVICE_MISMATCH" />
|
||||||
|
<el-option label="比特接口错误" value="BITANSWER_ERROR" />
|
||||||
|
<el-option label="其他" value="OTHER" />
|
||||||
|
</el-select>
|
||||||
<el-button v-permission="'callback:process'" type="info" :loading="patchingStatus" @click="setStatus('IGNORED')">忽略</el-button>
|
<el-button v-permission="'callback:process'" type="info" :loading="patchingStatus" @click="setStatus('IGNORED')">忽略</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -109,6 +117,7 @@ const loading = ref(false);
|
|||||||
const patchingStatus = ref(false);
|
const patchingStatus = ref(false);
|
||||||
const replaying = ref(false);
|
const replaying = ref(false);
|
||||||
const savingLink = ref(false);
|
const savingLink = ref(false);
|
||||||
|
const failureReason = ref("");
|
||||||
const row = ref(null);
|
const row = ref(null);
|
||||||
const webhookDeliveryStatus = ref(null);
|
const webhookDeliveryStatus = ref(null);
|
||||||
const webhookDeliveryLoading = ref(false);
|
const webhookDeliveryLoading = ref(false);
|
||||||
@@ -238,7 +247,13 @@ async function setStatus(status) {
|
|||||||
}
|
}
|
||||||
patchingStatus.value = true;
|
patchingStatus.value = true;
|
||||||
try {
|
try {
|
||||||
await patchCallbackInboxStatus(id, { status });
|
const body = { status };
|
||||||
|
if (status === "FAILED" && failureReason.value) {
|
||||||
|
body.failureReason = failureReason.value;
|
||||||
|
body.operatorNote = failureReason.value;
|
||||||
|
}
|
||||||
|
await patchCallbackInboxStatus(id, body);
|
||||||
|
failureReason.value = "";
|
||||||
ElMessage.success("状态已更新");
|
ElMessage.success("状态已更新");
|
||||||
await load();
|
await load();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -14,11 +14,13 @@
|
|||||||
<el-input v-model="filterSnCode" clearable placeholder="SN 编码" class="filter" style="width: 140px" @keyup.enter="load" />
|
<el-input v-model="filterSnCode" clearable placeholder="SN 编码" class="filter" style="width: 140px" @keyup.enter="load" />
|
||||||
<el-input v-model="filterProjectId" clearable placeholder="项目 ID" class="filter" style="width: 120px" @keyup.enter="load" />
|
<el-input v-model="filterProjectId" clearable placeholder="项目 ID" class="filter" style="width: 120px" @keyup.enter="load" />
|
||||||
<el-button type="primary" :loading="loading" @click="load">查询</el-button>
|
<el-button type="primary" :loading="loading" @click="load">查询</el-button>
|
||||||
|
<el-button @click="handleBatchRetry" :disabled="selectedCallbacks.length === 0">批量重试</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table v-loading="loading" :data="rows" stripe style="width: 100%">
|
<el-table v-loading="loading" :data="rows" stripe style="width: 100%" @selection-change="handleSelectionChange">
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column prop="sourceSystem" label="来源" width="120" show-overflow-tooltip />
|
<el-table-column prop="sourceSystem" label="来源" width="120" show-overflow-tooltip />
|
||||||
<el-table-column prop="externalMessageId" label="外部消息 ID" min-width="160" show-overflow-tooltip />
|
<el-table-column prop="externalMessageId" label="外部消息 ID" min-width="160" show-overflow-tooltip />
|
||||||
<el-table-column prop="eventType" label="事件类型" min-width="140" show-overflow-tooltip />
|
<el-table-column prop="eventType" label="事件类型" min-width="140" show-overflow-tooltip />
|
||||||
@@ -58,7 +60,7 @@ import { ref, onMounted } from "vue";
|
|||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { useAuthStore } from "../stores/auth";
|
import { useAuthStore } from "../stores/auth";
|
||||||
import { listCallbackInbox } from "../api/platform";
|
import { listCallbackInbox, replayCallbackWebhookDelivery } from "../api/platform";
|
||||||
import { apiErrorMessage } from "../utils/apiErrorMessage";
|
import { apiErrorMessage } from "../utils/apiErrorMessage";
|
||||||
|
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
@@ -73,6 +75,26 @@ const filterStatus = ref("");
|
|||||||
const filterEventType = ref("");
|
const filterEventType = ref("");
|
||||||
const filterSnCode = ref("");
|
const filterSnCode = ref("");
|
||||||
const filterProjectId = ref("");
|
const filterProjectId = ref("");
|
||||||
|
const selectedCallbacks = ref([]);
|
||||||
|
|
||||||
|
function handleSelectionChange(val) {
|
||||||
|
selectedCallbacks.value = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleBatchRetry() {
|
||||||
|
let success = 0;
|
||||||
|
let fail = 0;
|
||||||
|
for (const cb of selectedCallbacks.value) {
|
||||||
|
try {
|
||||||
|
await replayCallbackWebhookDelivery(cb.id);
|
||||||
|
success++;
|
||||||
|
} catch {
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ElMessage.success(`重试完成: ${success} 成功, ${fail} 失败`);
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
auth.restoreAxiosAuth();
|
auth.restoreAxiosAuth();
|
||||||
|
|||||||
Reference in New Issue
Block a user