增加token检测
This commit is contained in:
parent
6170d5a619
commit
e05ac23cc3
@ -58,3 +58,12 @@ export function replenishAccountPool(module, data) {
|
|||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 使用厂商 Token 探测是否可用(服务端转发)。Cursor 传 { id, accessToken }(会话 JWT)以便回写 is_used;仅传 accessToken 也可探测但不更新库;Windsurf/Kiro 传 { id } */
|
||||||
|
export function probeAccountPoolToken(module, data) {
|
||||||
|
return request({
|
||||||
|
url: `${base(module)}/probeToken`,
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -104,6 +104,17 @@ function copyToken() {
|
|||||||
row.extractStatus === 2 ? '补号' : row.extracted ? '已提取' : '未提取'
|
row.extractStatus === 2 ? '补号' : row.extracted ? '已提取' : '未提取'
|
||||||
}}
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="探测可用">
|
||||||
|
{{
|
||||||
|
row.isUsed === null || row.isUsed === undefined
|
||||||
|
? '未探测'
|
||||||
|
: Number(row.isUsed) === 1
|
||||||
|
? '可用'
|
||||||
|
: Number(row.isUsed) === 0
|
||||||
|
? '已用完'
|
||||||
|
: String(row.isUsed)
|
||||||
|
}}
|
||||||
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="提取时间">{{ row.extractedAt || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="提取时间">{{ row.extractedAt || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="提取平台">
|
<el-descriptions-item label="提取平台">
|
||||||
<el-tag v-if="row.extractedPlatform" :type="platformType" size="small">
|
<el-tag v-if="row.extractedPlatform" :type="platformType" size="small">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, nextTick, onMounted, onUnmounted, reactive, ref, watch } from "vue";
|
import { computed, h, nextTick, onMounted, onUnmounted, reactive, ref, watch } from "vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
import Edit from "./components/edit.vue";
|
import Edit from "./components/edit.vue";
|
||||||
import DetailDialog from "./components/detail.vue";
|
import DetailDialog from "./components/detail.vue";
|
||||||
import ExtractDialog from "./components/extract.vue";
|
import ExtractDialog from "./components/extract.vue";
|
||||||
@ -13,6 +13,7 @@ import {
|
|||||||
getAccountPoolList,
|
getAccountPoolList,
|
||||||
updateAccountPoolRemark,
|
updateAccountPoolRemark,
|
||||||
replenishAccountPool,
|
replenishAccountPool,
|
||||||
|
probeAccountPoolToken,
|
||||||
} from "@/api/accountPool";
|
} from "@/api/accountPool";
|
||||||
|
|
||||||
const moduleKey = "cursor";
|
const moduleKey = "cursor";
|
||||||
@ -33,6 +34,7 @@ const patchVisible = ref(false);
|
|||||||
const query = reactive({
|
const query = reactive({
|
||||||
keyword: "",
|
keyword: "",
|
||||||
status: "",
|
status: "",
|
||||||
|
usable: "",
|
||||||
});
|
});
|
||||||
const activeTypeTab = ref("all");
|
const activeTypeTab = ref("all");
|
||||||
|
|
||||||
@ -49,6 +51,7 @@ const total = ref(0);
|
|||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
const detailRow = ref(null);
|
const detailRow = ref(null);
|
||||||
const detailRemarkSaving = ref(false);
|
const detailRemarkSaving = ref(false);
|
||||||
|
const probeLoadingId = ref(null);
|
||||||
const isMobile = ref(false);
|
const isMobile = ref(false);
|
||||||
const pagination = reactive({
|
const pagination = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
@ -63,6 +66,7 @@ const pagedList = computed(() => tableData.value);
|
|||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
query.keyword = "";
|
query.keyword = "";
|
||||||
query.status = "";
|
query.status = "";
|
||||||
|
query.usable = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const typeTabs = computed(() => {
|
const typeTabs = computed(() => {
|
||||||
@ -75,7 +79,7 @@ const typeTabs = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [query.keyword, query.status, activeTypeTab.value],
|
() => [query.keyword, query.status, query.usable, activeTypeTab.value],
|
||||||
() => {
|
() => {
|
||||||
if (skipWatchFetchDuringUnusedJump.value) return;
|
if (skipWatchFetchDuringUnusedJump.value) return;
|
||||||
pagination.page = 1;
|
pagination.page = 1;
|
||||||
@ -348,6 +352,21 @@ function platformTagType(platform) {
|
|||||||
return PLATFORM_MAP[platform]?.type || "info";
|
return PLATFORM_MAP[platform]?.type || "info";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isUsedLabel(isUsed) {
|
||||||
|
if (isUsed === null || isUsed === undefined) return "未探测";
|
||||||
|
const n = Number(isUsed);
|
||||||
|
if (n === 1) return "可用";
|
||||||
|
if (n === 0) return "已用完";
|
||||||
|
return String(isUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isUsedTagType(isUsed) {
|
||||||
|
const n = Number(isUsed);
|
||||||
|
if (n === 1) return "success";
|
||||||
|
if (n === 0) return "danger";
|
||||||
|
return "info";
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeRow(raw) {
|
function normalizeRow(raw) {
|
||||||
const pick = (...keys) => {
|
const pick = (...keys) => {
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
@ -371,6 +390,11 @@ function normalizeRow(raw) {
|
|||||||
};
|
};
|
||||||
const st = Number(pick("is_extracted", "isExtracted", "IsExtracted"));
|
const st = Number(pick("is_extracted", "isExtracted", "IsExtracted"));
|
||||||
const extractStatus = Number.isFinite(st) ? st : 0;
|
const extractStatus = Number.isFinite(st) ? st : 0;
|
||||||
|
const isUsedRaw = pickNullable("is_used", "isUsed", "IsUsed");
|
||||||
|
const isUsedNum =
|
||||||
|
isUsedRaw === null || isUsedRaw === undefined || isUsedRaw === ""
|
||||||
|
? null
|
||||||
|
: Number(isUsedRaw);
|
||||||
return {
|
return {
|
||||||
id: pick("id", "Id", "ID"),
|
id: pick("id", "Id", "ID"),
|
||||||
type: pick("data_type", "dataType", "type"),
|
type: pick("data_type", "dataType", "type"),
|
||||||
@ -380,6 +404,7 @@ function normalizeRow(raw) {
|
|||||||
remark: pick("remark", "Remark"),
|
remark: pick("remark", "Remark"),
|
||||||
extractStatus,
|
extractStatus,
|
||||||
extracted: extractStatus !== 0,
|
extracted: extractStatus !== 0,
|
||||||
|
isUsed: Number.isFinite(isUsedNum) ? isUsedNum : null,
|
||||||
extractedAt: formatTime(pickNullable("extracted_time", "extractedAt")),
|
extractedAt: formatTime(pickNullable("extracted_time", "extractedAt")),
|
||||||
extractedPlatform: pickNullable("extracted_platform", "extractedPlatform"),
|
extractedPlatform: pickNullable("extracted_platform", "extractedPlatform"),
|
||||||
createdAt: formatTime(pick("create_time", "createdAt")),
|
createdAt: formatTime(pick("create_time", "createdAt")),
|
||||||
@ -394,6 +419,7 @@ async function fetchList() {
|
|||||||
pageSize: pagination.pageSize,
|
pageSize: pagination.pageSize,
|
||||||
keyword: query.keyword || undefined,
|
keyword: query.keyword || undefined,
|
||||||
status: query.status || undefined,
|
status: query.status || undefined,
|
||||||
|
usable: query.usable === "1" || query.usable === "0" ? query.usable : undefined,
|
||||||
type: activeTypeTab.value === "all" ? undefined : activeTypeTab.value,
|
type: activeTypeTab.value === "all" ? undefined : activeTypeTab.value,
|
||||||
});
|
});
|
||||||
if (res?.code !== 200) {
|
if (res?.code !== 200) {
|
||||||
@ -416,6 +442,7 @@ async function jumpToLastUnusedPage() {
|
|||||||
pageSize: pagination.pageSize,
|
pageSize: pagination.pageSize,
|
||||||
keyword: query.keyword || undefined,
|
keyword: query.keyword || undefined,
|
||||||
status: "unused",
|
status: "unused",
|
||||||
|
usable: query.usable === "1" || query.usable === "0" ? query.usable : undefined,
|
||||||
type,
|
type,
|
||||||
});
|
});
|
||||||
if (res?.code !== 200) {
|
if (res?.code !== 200) {
|
||||||
@ -525,6 +552,105 @@ function copyCardInfo(row) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CURSOR_PRO_LIMIT_TEXT = 'Get Cursor Pro for more Agent usage, unlimited Tab, and more.';
|
||||||
|
|
||||||
|
function formatCursorProbeDialogText(d) {
|
||||||
|
const detail = String(d?.detail || '');
|
||||||
|
const rawPreview = String(d?.rawPreview || '');
|
||||||
|
if (detail.includes(CURSOR_PRO_LIMIT_TEXT) || rawPreview.includes(CURSOR_PRO_LIMIT_TEXT)) {
|
||||||
|
return '该TOKEN已用完';
|
||||||
|
}
|
||||||
|
return '该TOKEN可用';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleProbeToken(row) {
|
||||||
|
if (!row?.token) {
|
||||||
|
ElMessage.warning('该行无 Token');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
probeLoadingId.value = row.id;
|
||||||
|
try {
|
||||||
|
const res = await probeAccountPoolToken(moduleKey, {
|
||||||
|
id: row.id,
|
||||||
|
accessToken: row.token,
|
||||||
|
});
|
||||||
|
if (res?.code !== 200) {
|
||||||
|
ElMessage.error(res?.msg || '探测失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const d = res?.data || {};
|
||||||
|
const text = formatCursorProbeDialogText(d);
|
||||||
|
try {
|
||||||
|
await ElMessageBox({
|
||||||
|
title: '检测结果',
|
||||||
|
message: h('div', { class: 'cursor-probe-result' }, text),
|
||||||
|
confirmButtonText: '关闭',
|
||||||
|
customClass: 'cursor-probe-dialog',
|
||||||
|
closeOnClickModal: true,
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
/* 用户关闭弹窗 */
|
||||||
|
}
|
||||||
|
await fetchList();
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('探测请求失败');
|
||||||
|
} finally {
|
||||||
|
probeLoadingId.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleBatchProbe() {
|
||||||
|
if (!selectedRows.value.length) {
|
||||||
|
ElMessage.warning("请先选择数据");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rows = selectedRows.value.filter((r) => r?.token);
|
||||||
|
if (!rows.length) {
|
||||||
|
ElMessage.warning("所选行均无 Token,无法检测");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const skipped = selectedRows.value.length - rows.length;
|
||||||
|
const skipHint =
|
||||||
|
skipped > 0 ? `(已跳过 ${skipped} 条无 Token)` : "";
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm(
|
||||||
|
`将对 ${rows.length} 条 Token进行检测,是否继续?`,
|
||||||
|
"批量检测",
|
||||||
|
{ type: "info", confirmButtonText: "开始", cancelButtonText: "取消" },
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
let ok = 0;
|
||||||
|
let fail = 0;
|
||||||
|
try {
|
||||||
|
for (const row of rows) {
|
||||||
|
try {
|
||||||
|
const res = await probeAccountPoolToken(moduleKey, {
|
||||||
|
id: row.id,
|
||||||
|
accessToken: row.token,
|
||||||
|
});
|
||||||
|
if (res?.code === 200) {
|
||||||
|
ok += 1;
|
||||||
|
} else {
|
||||||
|
fail += 1;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
fail += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fail > 0) {
|
||||||
|
ElMessage.warning(`批量检测完成:成功 ${ok} 条,失败 ${fail} 条`);
|
||||||
|
} else {
|
||||||
|
ElMessage.success(`批量检测完成:共 ${ok} 条`);
|
||||||
|
}
|
||||||
|
await fetchList();
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -553,6 +679,15 @@ function copyCardInfo(row) {
|
|||||||
<el-option label="未提取" value="unused" />
|
<el-option label="未提取" value="unused" />
|
||||||
<el-option label="已提取" value="extracted" />
|
<el-option label="已提取" value="extracted" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
<el-select
|
||||||
|
v-model="query.usable"
|
||||||
|
placeholder="探测可用"
|
||||||
|
clearable
|
||||||
|
class="w-140"
|
||||||
|
>
|
||||||
|
<el-option label="可用" value="1" />
|
||||||
|
<el-option label="已用完" value="0" />
|
||||||
|
</el-select>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
plain
|
plain
|
||||||
@ -568,6 +703,7 @@ function copyCardInfo(row) {
|
|||||||
<el-button type="success" @click="openAddDialog('batch')">批量添加</el-button>
|
<el-button type="success" @click="openAddDialog('batch')">批量添加</el-button>
|
||||||
<el-button type="warning" @click="replenishVisible = true">补号</el-button>
|
<el-button type="warning" @click="replenishVisible = true">补号</el-button>
|
||||||
<el-button @click="markExtractForSelected">批量标记提取</el-button>
|
<el-button @click="markExtractForSelected">批量标记提取</el-button>
|
||||||
|
<el-button type="info" plain @click="handleBatchProbe">批量检测</el-button>
|
||||||
<el-button @click="apiDocVisible = true">接口说明</el-button>
|
<el-button @click="apiDocVisible = true">接口说明</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -613,6 +749,13 @@ function copyCardInfo(row) {
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="探测可用" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="isUsedTagType(row.isUsed)" size="small">
|
||||||
|
{{ isUsedLabel(row.isUsed) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="extractedAt" label="提取时间" width="180" />
|
<el-table-column prop="extractedAt" label="提取时间" width="180" />
|
||||||
<el-table-column label="提取平台" width="120">
|
<el-table-column label="提取平台" width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@ -626,8 +769,16 @@ function copyCardInfo(row) {
|
|||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="220" fixed="right" align="center">
|
<el-table-column label="操作" width="300" fixed="right" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-if="row.token"
|
||||||
|
link
|
||||||
|
type="info"
|
||||||
|
:loading="probeLoadingId === row.id"
|
||||||
|
@click="handleProbeToken(row)"
|
||||||
|
>检测</el-button
|
||||||
|
>
|
||||||
<el-button link type="primary" @click="openDetail(row)"
|
<el-button link type="primary" @click="openDetail(row)"
|
||||||
>详情</el-button
|
>详情</el-button
|
||||||
>
|
>
|
||||||
@ -999,4 +1150,17 @@ function copyCardInfo(row) {
|
|||||||
.pool-tooltip .el-popper__arrow {
|
.pool-tooltip .el-popper__arrow {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cursor 探测结果弹窗(teleport 到 body,需非 scoped) */
|
||||||
|
.cursor-probe-dialog .el-message-box__message {
|
||||||
|
padding: 12px 8px 4px;
|
||||||
|
}
|
||||||
|
.cursor-probe-dialog .cursor-probe-result {
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 600;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import {
|
|||||||
getAccountPoolList,
|
getAccountPoolList,
|
||||||
updateAccountPoolRemark,
|
updateAccountPoolRemark,
|
||||||
replenishAccountPool,
|
replenishAccountPool,
|
||||||
|
probeAccountPoolToken,
|
||||||
} from '@/api/accountPool';
|
} from '@/api/accountPool';
|
||||||
|
|
||||||
const moduleKey = "krio";
|
const moduleKey = "krio";
|
||||||
@ -41,6 +42,7 @@ const total = ref(0);
|
|||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
const detailRow = ref(null);
|
const detailRow = ref(null);
|
||||||
const detailRemarkSaving = ref(false);
|
const detailRemarkSaving = ref(false);
|
||||||
|
const probeLoadingId = ref(null);
|
||||||
const isMobile = ref(false);
|
const isMobile = ref(false);
|
||||||
const pagination = reactive({ page: 1, pageSize: 30 });
|
const pagination = reactive({ page: 1, pageSize: 30 });
|
||||||
|
|
||||||
@ -454,6 +456,31 @@ function copyCardInfo(row) {
|
|||||||
navigator.clipboard.writeText(parts.join('\n')).then(() => { ElMessage.success('已复制'); });
|
navigator.clipboard.writeText(parts.join('\n')).then(() => { ElMessage.success('已复制'); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleProbeToken(row) {
|
||||||
|
if (!row?.token) {
|
||||||
|
ElMessage.warning('该行无 Token');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
probeLoadingId.value = row.id;
|
||||||
|
try {
|
||||||
|
const res = await probeAccountPoolToken(moduleKey, { id: row.id });
|
||||||
|
if (res?.code !== 200) {
|
||||||
|
ElMessage.error(res?.msg || '探测失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const d = res?.data || {};
|
||||||
|
if (d.ok) {
|
||||||
|
ElMessage.success(d.detail || '官方接口响应正常');
|
||||||
|
} else {
|
||||||
|
ElMessage.error(d.detail || '不可用或校验失败');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('探测请求失败');
|
||||||
|
} finally {
|
||||||
|
probeLoadingId.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -543,11 +570,19 @@ function copyCardInfo(row) {
|
|||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="220" fixed="right" align="center">
|
<el-table-column label="操作" width="300" fixed="right" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button link type="primary" @click="openDetail(row)"
|
<el-button link type="primary" @click="openDetail(row)"
|
||||||
>详情</el-button
|
>详情</el-button
|
||||||
>
|
>
|
||||||
|
<el-button
|
||||||
|
v-if="row.token"
|
||||||
|
link
|
||||||
|
type="info"
|
||||||
|
:loading="probeLoadingId === row.id"
|
||||||
|
@click="handleProbeToken(row)"
|
||||||
|
>查可用</el-button
|
||||||
|
>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="!row.extractedAt && !row.extracted"
|
v-if="!row.extractedAt && !row.extracted"
|
||||||
link
|
link
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import {
|
|||||||
getAccountPoolList,
|
getAccountPoolList,
|
||||||
updateAccountPoolRemark,
|
updateAccountPoolRemark,
|
||||||
replenishAccountPool,
|
replenishAccountPool,
|
||||||
|
probeAccountPoolToken,
|
||||||
} from '@/api/accountPool';
|
} from '@/api/accountPool';
|
||||||
|
|
||||||
const moduleKey = "windsurf";
|
const moduleKey = "windsurf";
|
||||||
@ -40,6 +41,7 @@ const total = ref(0);
|
|||||||
const selectedRows = ref([]);
|
const selectedRows = ref([]);
|
||||||
const detailRow = ref(null);
|
const detailRow = ref(null);
|
||||||
const detailRemarkSaving = ref(false);
|
const detailRemarkSaving = ref(false);
|
||||||
|
const probeLoadingId = ref(null);
|
||||||
const isMobile = ref(false);
|
const isMobile = ref(false);
|
||||||
const pagination = reactive({ page: 1, pageSize: 30 });
|
const pagination = reactive({ page: 1, pageSize: 30 });
|
||||||
|
|
||||||
@ -453,6 +455,31 @@ function copyCardInfo(row) {
|
|||||||
navigator.clipboard.writeText(parts.join('\n')).then(() => { ElMessage.success('已复制'); });
|
navigator.clipboard.writeText(parts.join('\n')).then(() => { ElMessage.success('已复制'); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleProbeToken(row) {
|
||||||
|
if (!row?.token) {
|
||||||
|
ElMessage.warning('该行无 Token');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
probeLoadingId.value = row.id;
|
||||||
|
try {
|
||||||
|
const res = await probeAccountPoolToken(moduleKey, { id: row.id });
|
||||||
|
if (res?.code !== 200) {
|
||||||
|
ElMessage.error(res?.msg || '探测失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const d = res?.data || {};
|
||||||
|
if (d.ok) {
|
||||||
|
ElMessage.success(d.detail || '官方接口响应正常');
|
||||||
|
} else {
|
||||||
|
ElMessage.error(d.detail || '不可用或校验失败');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('探测请求失败');
|
||||||
|
} finally {
|
||||||
|
probeLoadingId.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -542,11 +569,19 @@ function copyCardInfo(row) {
|
|||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="220" fixed="right" align="center">
|
<el-table-column label="操作" width="300" fixed="right" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button link type="primary" @click="openDetail(row)"
|
<el-button link type="primary" @click="openDetail(row)"
|
||||||
>详情</el-button
|
>详情</el-button
|
||||||
>
|
>
|
||||||
|
<el-button
|
||||||
|
v-if="row.token"
|
||||||
|
link
|
||||||
|
type="info"
|
||||||
|
:loading="probeLoadingId === row.id"
|
||||||
|
@click="handleProbeToken(row)"
|
||||||
|
>查可用</el-button
|
||||||
|
>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="!row.extractedAt && !row.extracted"
|
v-if="!row.extractedAt && !row.extracted"
|
||||||
link
|
link
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user