Skip to content
This repository was archived by the owner on Apr 22, 2026. It is now read-only.

Commit 1ebec51

Browse files
committed
release(v1.0.1): 支持access_token复制并精简账号页面
1 parent c0109e6 commit 1ebec51

6 files changed

Lines changed: 350 additions & 33 deletions

File tree

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.0-dev
1+
1.0.1

codex_register/gui_frontend_app_setup.js

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const activeTab = Vue.ref("dash");
22
const menuOptions = [
33
{ label: "工作台", key: "dash" },
4-
{ label: "数据", key: "data" },
54
{ label: "账号管理", key: "accounts" },
65
{ label: "邮箱设置", key: "mail" },
76
{ label: "SMS管理", key: "sms" },
@@ -975,7 +974,7 @@
975974
{ type: "selection", multiple: true },
976975
{ title: "#", key: "index", width: 56 },
977976
{ title: "邮箱", key: "email", minWidth: 220, ellipsis: { tooltip: true } },
978-
{ title: "密码", key: "password", minWidth: 180, ellipsis: { tooltip: true } },
977+
{ title: "密码", key: "password", width: 150, ellipsis: { tooltip: true } },
979978
{
980979
title: "测活",
981980
key: "test_status",
@@ -1004,7 +1003,27 @@
10041003
);
10051004
}
10061005
},
1007-
{ title: "备注", key: "note", minWidth: 300, ellipsis: { tooltip: true } }
1006+
{ title: "备注", key: "note", minWidth: 300, ellipsis: { tooltip: true } },
1007+
{
1008+
title: "功能",
1009+
key: "actions",
1010+
width: 88,
1011+
render(row) {
1012+
const token = String((row && row.access_token) || "").trim();
1013+
return Vue.h(
1014+
naive.NButton,
1015+
{
1016+
size: "small",
1017+
type: "primary",
1018+
tertiary: true,
1019+
disabled: !token,
1020+
title: "复制 access_token",
1021+
onClick: () => accountCopyToken(row)
1022+
},
1023+
{ default: () => "复制AT" }
1024+
);
1025+
}
1026+
}
10081027
];
10091028

10101029
function accountExportableRows() {
@@ -1177,6 +1196,31 @@
11771196
{ default: () => "未测" }
11781197
);
11791198
}
1199+
},
1200+
{
1201+
title: "功能",
1202+
key: "actions",
1203+
width: 88,
1204+
render(row) {
1205+
const token = String((row && row.access_token) || "").trim();
1206+
const provider = normalizeRemoteAccountProvider(settingsForm.remote_account_provider);
1207+
const canDownload = (
1208+
provider === "cliproxyapi"
1209+
&& !!String((row && row.file_name) || "").trim()
1210+
);
1211+
return Vue.h(
1212+
naive.NButton,
1213+
{
1214+
size: "small",
1215+
type: "primary",
1216+
tertiary: true,
1217+
disabled: !(token || canDownload),
1218+
title: "复制 access_token",
1219+
onClick: () => remoteCopyToken(row)
1220+
},
1221+
{ default: () => "复制AT" }
1222+
);
1223+
}
11801224
}
11811225
];
11821226

@@ -1224,6 +1268,70 @@
12241268
return payload.data;
12251269
}
12261270

1271+
async function copyText(text) {
1272+
const raw = String(text || "");
1273+
if (!raw) {
1274+
throw new Error("空内容无法复制");
1275+
}
1276+
if (navigator && navigator.clipboard && typeof navigator.clipboard.writeText === "function") {
1277+
await navigator.clipboard.writeText(raw);
1278+
return;
1279+
}
1280+
const el = document.createElement("textarea");
1281+
el.value = raw;
1282+
el.setAttribute("readonly", "readonly");
1283+
el.style.position = "fixed";
1284+
el.style.left = "-9999px";
1285+
document.body.appendChild(el);
1286+
el.focus();
1287+
el.select();
1288+
try {
1289+
const ok = document.execCommand("copy");
1290+
if (!ok) throw new Error("浏览器不支持复制");
1291+
} finally {
1292+
document.body.removeChild(el);
1293+
}
1294+
}
1295+
1296+
async function accountCopyToken(row) {
1297+
const token = String((row && row.access_token) || "").trim();
1298+
if (!token) {
1299+
message.warning("该本地账号暂无可复制 access_token");
1300+
return;
1301+
}
1302+
try {
1303+
await copyText(token);
1304+
message.success("已复制本地账号 access_token");
1305+
} catch (e) {
1306+
message.error(String(e.message || e));
1307+
}
1308+
}
1309+
1310+
async function remoteCopyToken(row) {
1311+
try {
1312+
let token = String((row && row.access_token) || "").trim();
1313+
if (!token) {
1314+
const data = await apiRequest("/api/remote/access-token", {
1315+
method: "POST",
1316+
body: {
1317+
id: String((row && row.id) || "").trim(),
1318+
file_name: String((row && row.file_name) || "").trim()
1319+
}
1320+
});
1321+
token = String((data && data.access_token) || "").trim();
1322+
if (!token) {
1323+
throw new Error("接口未返回 access_token");
1324+
}
1325+
if (row) row.access_token = token;
1326+
}
1327+
1328+
await copyText(token);
1329+
message.success("已复制云端账号 access_token");
1330+
} catch (e) {
1331+
message.error(String(e.message || e));
1332+
}
1333+
}
1334+
12271335
function assignConfig(cfg) {
12281336
dashForm.num_accounts = Number(cfg.num_accounts || 1);
12291337
dashForm.num_files = Number(cfg.num_files || 1);
@@ -2309,7 +2417,7 @@
23092417
body: { emails }
23102418
});
23112419
accountSelection.value = [];
2312-
await Promise.all([refreshAccounts(false), refreshJson(false)]);
2420+
await refreshAccounts(false);
23132421
message.success(
23142422
`删除完成:账号 ${Number(data.deleted || 0)} 条,`
23152423
+ `accounts.txt ${Number(data.removed_txt_lines || 0)} 行,`
@@ -3031,7 +3139,6 @@
30313139
async function initialLoad() {
30323140
await loadConfig();
30333141
await Promise.all([
3034-
refreshJson(false),
30353142
refreshAccounts(false),
30363143
loadRemoteCache(),
30373144
loadMailProviders(),
@@ -3050,7 +3157,7 @@
30503157
await pullLogs();
30513158
pollTick += 1;
30523159
if (status.running && pollTick % 4 === 0) {
3053-
await Promise.all([refreshJson(false), refreshAccounts(false)]);
3160+
await refreshAccounts(false);
30543161
}
30553162
if (
30563163
activeTab.value === "accounts" &&

codex_register/gui_frontend_app_template.html

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ <h1>注册任务面板</h1>
100100
<n-alert type="info" title="运行说明" :show-icon="false">
101101
启动后会在后台按配置调用 r_with_pwd.run,日志实时出现在底部。<br />
102102
会按“文件数量 × 每文件注册数”分批创建 accounts_*.json;失败会自动补位,尽量补齐每个文件目标。<br />
103-
建议先保存配置,再开始任务;停止后可在「数据」页继续管理导出与同步。
103+
建议先保存配置,再开始任务;停止后可在「账号管理」页继续管理导出与同步。
104104
</n-alert>
105105
<n-alert style="margin-top: 10px" type="success" title="提速建议" :show-icon="false">
106106
并发仅作用于当前文件,建议 2~3;冷却 1~3 秒;开启加速模式可缩短 OTP 轮询与网络退避等待。<br />
@@ -114,31 +114,6 @@ <h1>注册任务面板</h1>
114114
</n-card>
115115
</div>
116116

117-
<div v-else-if="activeTab === 'data'" class="tab-page">
118-
<n-card class="glass-card" title="导出 JSON" size="small">
119-
<template #header-extra>
120-
<span class="meta">{{ jsonInfo.file_count }} 个文件 · {{ jsonInfo.account_total }} 账号</span>
121-
</template>
122-
<div class="toolbar">
123-
<n-button class="toolbar-btn" @click="refreshJson(true)">刷新</n-button>
124-
<n-button class="toolbar-btn" @click="jsonSelectAll">全选</n-button>
125-
<n-button class="toolbar-btn" @click="jsonSelectNone">全不选</n-button>
126-
<n-button class="toolbar-btn" type="error" ghost @click="deleteSelectedJson">删除已勾选</n-button>
127-
</div>
128-
<n-data-table
129-
class="json-table"
130-
size="small"
131-
table-layout="fixed"
132-
:single-line="false"
133-
:columns="jsonColumns"
134-
:data="jsonRows"
135-
:row-key="rowKeyPath"
136-
:row-class-name="jsonRowClassName"
137-
v-model:checked-row-keys="jsonSelection"
138-
/>
139-
</n-card>
140-
</div>
141-
142117
<div v-else-if="activeTab === 'accounts'" class="tab-page">
143118
<n-card class="glass-card account-manage-card" title="账号管理" size="small">
144119
<n-tabs class="account-manage-tabs" type="segment" :value="accountManageTab" @update:value="accountManageTab = $event">

codex_register/gui_server_runtime.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,13 @@ def do_POST(self) -> None:
287287
self._ok(service.remote_bulk_update_groups(account_ids, group_ids))
288288
return
289289

290+
if path == "/api/remote/access-token":
291+
payload = self._read_json_body()
292+
aid = payload.get("id")
293+
file_name = payload.get("file_name")
294+
self._ok(service.remote_access_token(aid, file_name))
295+
return
296+
290297
if path == "/api/flclash/probe":
291298
payload = self._read_json_body()
292299
self._ok(

0 commit comments

Comments
 (0)