|
1 | 1 | const activeTab = Vue.ref("dash"); |
2 | 2 | const menuOptions = [ |
3 | 3 | { label: "工作台", key: "dash" }, |
4 | | - { label: "数据", key: "data" }, |
5 | 4 | { label: "账号管理", key: "accounts" }, |
6 | 5 | { label: "邮箱设置", key: "mail" }, |
7 | 6 | { label: "SMS管理", key: "sms" }, |
|
975 | 974 | { type: "selection", multiple: true }, |
976 | 975 | { title: "#", key: "index", width: 56 }, |
977 | 976 | { 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 } }, |
979 | 978 | { |
980 | 979 | title: "测活", |
981 | 980 | key: "test_status", |
|
1004 | 1003 | ); |
1005 | 1004 | } |
1006 | 1005 | }, |
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 | + } |
1008 | 1027 | ]; |
1009 | 1028 |
|
1010 | 1029 | function accountExportableRows() { |
|
1177 | 1196 | { default: () => "未测" } |
1178 | 1197 | ); |
1179 | 1198 | } |
| 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 | + } |
1180 | 1224 | } |
1181 | 1225 | ]; |
1182 | 1226 |
|
|
1224 | 1268 | return payload.data; |
1225 | 1269 | } |
1226 | 1270 |
|
| 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 | + |
1227 | 1335 | function assignConfig(cfg) { |
1228 | 1336 | dashForm.num_accounts = Number(cfg.num_accounts || 1); |
1229 | 1337 | dashForm.num_files = Number(cfg.num_files || 1); |
|
2309 | 2417 | body: { emails } |
2310 | 2418 | }); |
2311 | 2419 | accountSelection.value = []; |
2312 | | - await Promise.all([refreshAccounts(false), refreshJson(false)]); |
| 2420 | + await refreshAccounts(false); |
2313 | 2421 | message.success( |
2314 | 2422 | `删除完成:账号 ${Number(data.deleted || 0)} 条,` |
2315 | 2423 | + `accounts.txt ${Number(data.removed_txt_lines || 0)} 行,` |
|
3031 | 3139 | async function initialLoad() { |
3032 | 3140 | await loadConfig(); |
3033 | 3141 | await Promise.all([ |
3034 | | - refreshJson(false), |
3035 | 3142 | refreshAccounts(false), |
3036 | 3143 | loadRemoteCache(), |
3037 | 3144 | loadMailProviders(), |
|
3050 | 3157 | await pullLogs(); |
3051 | 3158 | pollTick += 1; |
3052 | 3159 | if (status.running && pollTick % 4 === 0) { |
3053 | | - await Promise.all([refreshJson(false), refreshAccounts(false)]); |
| 3160 | + await refreshAccounts(false); |
3054 | 3161 | } |
3055 | 3162 | if ( |
3056 | 3163 | activeTab.value === "accounts" && |
|
0 commit comments