规范:统一自有源码中文注释和中文提交约定
This commit is contained in:
1 parent
bdb9b00b6e
commit
83b7484558
17 files changed
+39
-36
No files matched your search
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
# Backend origin only. The client appends /console/v1.
|
# 仅填写后端源地址;客户端会追加 /console/v1。
|
||||||
# Leave empty when your reverse proxy serves the API on the same origin.
|
# 反向代理在前端同源地址提供接口时留空。
|
||||||
NUXT_PUBLIC_API_BASE=
|
NUXT_PUBLIC_API_BASE=
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
# Generated output and local-only reports are not source formatting targets.
|
# 生成产物和仅供本地使用的报告不参与源码格式化。
|
||||||
node_modules/
|
node_modules/
|
||||||
.nuxt/
|
.nuxt/
|
||||||
.output/
|
.output/
|
||||||
@@ -8,6 +8,6 @@ tests/fixtures/runs/
|
|||||||
docs/
|
docs/
|
||||||
.claude/skills/crashwork-ops/
|
.claude/skills/crashwork-ops/
|
||||||
|
|
||||||
# Preserve supplied static assets and npm's lockfile serialization.
|
# 保留已有静态资源和 npm 锁文件的序列化格式。
|
||||||
public/
|
public/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
@@ -180,6 +180,9 @@ CHROME_PATH=/absolute/path/to/chrome npm test
|
|||||||
多数页面和组件保留恢复后的 Vue 渲染函数及部分短变量名;原始模板、注释和完整变量名无法从发布包完整找回。
|
多数页面和组件保留恢复后的 Vue 渲染函数及部分短变量名;原始模板、注释和完整变量名无法从发布包完整找回。
|
||||||
当前新增注释用于解释已核实的职责、流程和接口边界,不代表找回了原作者的注释,也不代表全站重新手写。
|
当前新增注释用于解释已核实的职责、流程和接口边界,不代表找回了原作者的注释,也不代表全站重新手写。
|
||||||
|
|
||||||
|
项目自有代码的说明性注释统一使用中文,提交信息也统一使用中文。
|
||||||
|
变量名、接口字段、工具指令和第三方版权声明保留原样;注释应解释意图与约束,避免逐行复述代码。
|
||||||
|
|
||||||
维护时直接修改当前源码并正常构建,不要编辑生成的哈希产物。
|
维护时直接修改当前源码并正常构建,不要编辑生成的哈希产物。
|
||||||
`scripts/reconstruct.mjs` 仅是一次性导入留档,不是开发或发布步骤,且会拒绝覆盖现有页面;
|
`scripts/reconstruct.mjs` 仅是一次性导入留档,不是开发或发布步骤,且会拒绝覆盖现有页面;
|
||||||
不要使用不可信的第三方发布产物运行该脚本。
|
不要使用不可信的第三方发布产物运行该脚本。
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Deni shell adapted from OpenVue Foundation Deni (MIT), commit
|
* Deni shell adapted from OpenVue Foundation Deni (MIT), commit
|
||||||
* 72156473d5f73a26f97d35aa5fed3a96059779ef:
|
* 72156473d5f73a26f97d35aa5fed3a96059779ef:
|
||||||
* src/assets/styles/_layout.scss, _sidebar.scss, _topbar.scss.
|
* src/assets/styles/_layout.scss, _sidebar.scss, _topbar.scss.
|
||||||
* Nuxt route slots, measured maintenance offset and accessible mobile focus remain local.
|
* Nuxt 路由插槽、维护横幅偏移测量及移动端无障碍焦点管理保留本地实现。
|
||||||
*/
|
*/
|
||||||
.deni-layout {
|
.deni-layout {
|
||||||
min-height: 100dvh;
|
min-height: 100dvh;
|
||||||
|
|||||||
@@ -509,7 +509,7 @@ var ue = {
|
|||||||
}
|
}
|
||||||
async function Ht() {
|
async function Ht() {
|
||||||
// 打开支付面板时并行读取订单、账户余额与渠道;订单类型决定是否再加载代金券。
|
// 打开支付面板时并行读取订单、账户余额与渠道;订单类型决定是否再加载代金券。
|
||||||
// A visible dialog can outlive session invalidation until route teardown.
|
// 会话失效后,支付弹窗可能直到路由卸载时才关闭,不能仅凭可见状态继续初始化。
|
||||||
if (!Dt.isLoggedIn) return;
|
if (!Dt.isLoggedIn) return;
|
||||||
let e = x.orderId,
|
let e = x.orderId,
|
||||||
t = X;
|
t = X;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { definePreset } from "@openvue/themes";
|
|||||||
import Aura from "@openvue/themes/aura";
|
import Aura from "@openvue/themes/aura";
|
||||||
import locale from "./locale.zh-CN.json";
|
import locale from "./locale.zh-CN.json";
|
||||||
|
|
||||||
// Use the MIT theme package, with the console's blue/slate/zinc palette.
|
// 使用 MIT 许可的主题包,并采用控制台的 blue/slate/zinc 配色。
|
||||||
// 只覆盖 Aura 的语义色阶,保留组件自身设计令牌;浅色用 slate,深色用 zinc。
|
// 只覆盖 Aura 的语义色阶,保留组件自身设计令牌;浅色用 slate,深色用 zinc。
|
||||||
const preset = definePreset(Aura, {
|
const preset = definePreset(Aura, {
|
||||||
semantic: {
|
semantic: {
|
||||||
|
|||||||
+3
-3
@@ -244,7 +244,7 @@ async function withRequestDeadline(
|
|||||||
}, duration);
|
}, duration);
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
// The deadline also covers response-body decoding and any purchase preflight.
|
// 截止时间也覆盖响应体解码和购买预检。
|
||||||
return await Promise.race([
|
return await Promise.race([
|
||||||
Promise.resolve().then(() => operation(controller.signal)),
|
Promise.resolve().then(() => operation(controller.signal)),
|
||||||
deadline,
|
deadline,
|
||||||
@@ -359,7 +359,7 @@ function useApi() {
|
|||||||
|
|
||||||
/** JSON 请求主路径:固定本次身份和请求体 → 必要时限购预检 → 请求 → 验证信封。 */
|
/** JSON 请求主路径:固定本次身份和请求体 → 必要时限购预检 → 请求 → 验证信封。 */
|
||||||
async function request(method, path, options = {}) {
|
async function request(method, path, options = {}) {
|
||||||
// Capture identity before the first await, including when logout clears it immediately.
|
// 在首次 await 前捕获身份,包括退出登录立即清除身份的情况。
|
||||||
const requestToken = auth.token;
|
const requestToken = auth.token;
|
||||||
const headers = { Accept: "application/json" };
|
const headers = { Accept: "application/json" };
|
||||||
if (requestToken) headers.Authorization = `Bearer ${requestToken}`;
|
if (requestToken) headers.Authorization = `Bearer ${requestToken}`;
|
||||||
@@ -876,7 +876,7 @@ const useAuth = defineStore("auth", () => {
|
|||||||
|
|
||||||
// 本地退出立即生效,不等待远端吊销成功;请求已同步捕获旧 Bearer,不会误用新身份。
|
// 本地退出立即生效,不等待远端吊销成功;请求已同步捕获旧 Bearer,不会误用新身份。
|
||||||
function logout() {
|
function logout() {
|
||||||
// request() captures the original Bearer synchronously; remote revocation never owns local logout.
|
// request() 同步捕获原始 Bearer 凭证;远端吊销不决定本地退出是否生效。
|
||||||
const revocation = useApi().post("/logout");
|
const revocation = useApi().post("/logout");
|
||||||
clear();
|
clear();
|
||||||
void revocation.catch(() => {});
|
void revocation.catch(() => {});
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export default defineNuxtRouteMiddleware((to) => {
|
|||||||
);
|
);
|
||||||
const query = { ...to.query };
|
const query = { ...to.query };
|
||||||
delete query.queryParam;
|
delete query.queryParam;
|
||||||
// Canonicalize the router location too; mutating query alone leaves fullPath with the credential.
|
// 同时规范化路由地址;仅修改 query 会让 fullPath 仍保留凭证。
|
||||||
return navigateTo(
|
return navigateTo(
|
||||||
{ path: "/home.htm", query, hash: to.hash },
|
{ path: "/home.htm", query, hash: to.hash },
|
||||||
{ replace: true },
|
{ replace: true },
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ async function verifyAndEnterConsole() {
|
|||||||
isVerifying.value = true;
|
isVerifying.value = true;
|
||||||
verificationError.value = "";
|
verificationError.value = "";
|
||||||
try {
|
try {
|
||||||
// The route guard owns credential extraction; this page never reads it from the URL.
|
// 凭据提取由路由守卫负责,本页不再从 URL 读取。
|
||||||
await auth.verifyLegacyLogin();
|
await auth.verifyLegacyLogin();
|
||||||
if (!disposed) await router.replace("/");
|
if (!disposed) await router.replace("/");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
+2
-2
@@ -255,7 +255,7 @@ async function confirmSecurityVerification(verification) {
|
|||||||
credentials.type === "password" &&
|
credentials.type === "password" &&
|
||||||
captchaNeeded.value
|
captchaNeeded.value
|
||||||
) {
|
) {
|
||||||
// Certification returns to this form for a fresh CAPTCHA before continuing the same login.
|
// 实名认证挑战后先回到当前表单刷新并完成验证码,再续交同一次登录。
|
||||||
pendingVerification.value = { ...verification };
|
pendingVerification.value = { ...verification };
|
||||||
securityDialogVisible.value = false;
|
securityDialogVisible.value = false;
|
||||||
errorMessage.value = "";
|
errorMessage.value = "";
|
||||||
@@ -407,7 +407,7 @@ async function submitLogin() {
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="loginMode === 'code'" class="field">
|
<div v-if="loginMode === 'code'" class="field">
|
||||||
<label for="login-code">验证码</label>
|
<label for="login-code">验证码</label>
|
||||||
<!-- Retain the deployed scoped selectors without changing the shared stylesheet. -->
|
<!-- 保留已部署样式的作用域标记,不改动共享样式表。 -->
|
||||||
<div class="code-row" data-v-7896f676>
|
<div class="code-row" data-v-7896f676>
|
||||||
<InputText
|
<InputText
|
||||||
id="login-code"
|
id="login-code"
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ async function loadSearchResults() {
|
|||||||
searchLoading.value = true;
|
searchLoading.value = true;
|
||||||
listError.value = "";
|
listError.value = "";
|
||||||
try {
|
try {
|
||||||
// Search owns the complete result set; only visibleRows applies local pagination.
|
// 搜索负责收集完整结果,仅由 visibleRows 执行本地分页。
|
||||||
const completeRows = await loadCompleteList(
|
const completeRows = await loadCompleteList(
|
||||||
(page, limit) => api.get("/ssh_key", { page, limit }),
|
(page, limit) => api.get("/ssh_key", { page, limit }),
|
||||||
isCurrent,
|
isCurrent,
|
||||||
@@ -244,7 +244,7 @@ async function copyPublicKey(key) {
|
|||||||
copiedKeyId.value = key.id;
|
copiedKeyId.value = key.id;
|
||||||
copyResetTimer = setTimeout(() => (copiedKeyId.value = null), 2000);
|
copyResetTimer = setTimeout(() => (copiedKeyId.value = null), 2000);
|
||||||
} catch {
|
} catch {
|
||||||
// Clipboard access can be unavailable; the public key remains selectable.
|
// 剪贴板权限或接口可能不可用,用户仍可手工选择并复制公钥。
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ onBeforeUnmount(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- Keep the imported page styles scoped, including the teleported editor. -->
|
<!-- 保留导入样式的页面作用域,包括渲染到页面外部的编辑弹窗。 -->
|
||||||
<div class="list-page" data-v-31489433>
|
<div class="list-page" data-v-31489433>
|
||||||
<div class="list-head" data-v-31489433>
|
<div class="list-head" data-v-31489433>
|
||||||
<h2 data-v-31489433>SSH 密钥</h2>
|
<h2 data-v-31489433>SSH 密钥</h2>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default defineNuxtPlugin({
|
|||||||
(event.key !== null && event.key !== "jwt")
|
(event.key !== null && event.key !== "jwt")
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
// Read the latest value: several storage events may already be queued.
|
// 读取最新值:此时可能已有多个 storage 事件排队。
|
||||||
const persisted = localStorage.getItem("jwt");
|
const persisted = localStorage.getItem("jwt");
|
||||||
if (persisted === auth.token) return;
|
if (persisted === auth.token) return;
|
||||||
if (isValidJwt(persisted)) auth.prepareLogin().commit(persisted);
|
if (isValidJwt(persisted)) auth.prepareLogin().commit(persisted);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ function existsModule(file) {
|
|||||||
}
|
}
|
||||||
function checkImport(source, owner) {
|
function checkImport(source, owner) {
|
||||||
// # 开头的虚拟模块由 Nuxt 生成,本地文件与 npm 包则分别核对实际路径及依赖声明。
|
// # 开头的虚拟模块由 Nuxt 生成,本地文件与 npm 包则分别核对实际路径及依赖声明。
|
||||||
if (source.startsWith("#")) return; // Nuxt-generated public/virtual modules.
|
if (source.startsWith("#")) return; // Nuxt 生成的公共/虚拟模块。
|
||||||
if (source.startsWith("~/")) {
|
if (source.startsWith("~/")) {
|
||||||
if (!existsModule(path.join(root, "app", source.slice(2))))
|
if (!existsModule(path.join(root, "app", source.slice(2))))
|
||||||
failures.push(`${owner}: missing ${source}`);
|
failures.push(`${owner}: missing ${source}`);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/** One-time source reconstruction. Input is explicit; generated app has no runtime link to it. */
|
/** 一次性源码重建;输入显式指定,生成的应用运行时不依赖该输入。 */
|
||||||
/**
|
/**
|
||||||
* 一次性重建留档,不参与日常开发、构建或发布。
|
* 一次性重建留档,不参与日常开发、构建或发布。
|
||||||
* 输入必须是可信的自有 Nuxt 发布目录:脚本会 import 其中的元数据,因此不是安全的第三方解包器。
|
* 输入必须是可信的自有 Nuxt 发布目录:脚本会 import 其中的元数据,因此不是安全的第三方解包器。
|
||||||
@@ -243,7 +243,7 @@ for (const [source, mod] of own) {
|
|||||||
label: path.basename(source, ".vue"),
|
label: path.basename(source, ".vue"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Official libraries replace bundled copies. Resolve tiny re-export wrappers first.
|
// 使用官方库替换内嵌副本,先解析仅重导出的轻量包装模块。
|
||||||
for (const [source, mod] of Object.entries(pc.modules)) {
|
for (const [source, mod] of Object.entries(pc.modules)) {
|
||||||
if (!source.includes("/node_modules/") || mod.resourceType !== "script")
|
if (!source.includes("/node_modules/") || mod.resourceType !== "script")
|
||||||
continue;
|
continue;
|
||||||
@@ -262,7 +262,7 @@ for (const [source, mod] of Object.entries(pc.modules)) {
|
|||||||
label: npm.split("/").at(-1),
|
label: npm.split("/").at(-1),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// The existing chart component is recovered separately; ECharts stays a library dependency.
|
// 现有图表组件单独恢复;ECharts 仍作为库依赖。
|
||||||
const chartOwner = [...owners.entries()].find(
|
const chartOwner = [...owners.entries()].find(
|
||||||
([, v]) => v.source === "components/ChartBox.vue",
|
([, v]) => v.source === "components/ChartBox.vue",
|
||||||
);
|
);
|
||||||
@@ -341,7 +341,7 @@ async function add(file, code, parser) {
|
|||||||
});
|
});
|
||||||
patchFiles.push({ file, code: formatted });
|
patchFiles.push({ file, code: formatted });
|
||||||
}
|
}
|
||||||
// Save route metadata without compiled preload machinery; Nuxt owns the new module graph.
|
// 保存路由元数据,不保留编译后的预加载机制;新模块依赖图由 Nuxt 管理。
|
||||||
const entry = asts.get("CNMaXYQo.js");
|
const entry = asts.get("CNMaXYQo.js");
|
||||||
let routes;
|
let routes;
|
||||||
traverse(entry, {
|
traverse(entry, {
|
||||||
@@ -398,7 +398,7 @@ while (pending.length) {
|
|||||||
}
|
}
|
||||||
if (file === "BLvPXbVl.js") {
|
if (file === "BLvPXbVl.js") {
|
||||||
// 针对此发布包剥离内嵌的 Pinia/密码库实现,保留业务逻辑并接回正式 npm 依赖。
|
// 针对此发布包剥离内嵌的 Pinia/密码库实现,保留业务逻辑并接回正式 npm 依赖。
|
||||||
// Business logic only; Pinia, file downloads and cryptography are npm dependencies.
|
// 仅恢复业务逻辑;Pinia、文件下载和密码学功能通过 npm 依赖提供。
|
||||||
let keep = false;
|
let keep = false;
|
||||||
const body = [];
|
const body = [];
|
||||||
for (const n of ast.program.body) {
|
for (const n of ast.program.body) {
|
||||||
@@ -441,7 +441,7 @@ while (pending.length) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Discard old dependency indexes: Vite reconstructs preload URLs from new imports.
|
// 丢弃旧依赖索引;Vite 根据新导入重建预加载地址。
|
||||||
traverse(ast, {
|
traverse(ast, {
|
||||||
CallExpression(p) {
|
CallExpression(p) {
|
||||||
if (t.isIdentifier(p.node.callee, { name: "__vite__mapDeps" }))
|
if (t.isIdentifier(p.node.callee, { name: "__vite__mapDeps" }))
|
||||||
@@ -510,7 +510,7 @@ while (pending.length) {
|
|||||||
}
|
}
|
||||||
stmt.replaceWithMultiple(imports);
|
stmt.replaceWithMultiple(imports);
|
||||||
}
|
}
|
||||||
// Semantic exported API names are stable throughout the reconstructed project.
|
// 语义化导出接口名在整个重建工程中保持稳定。
|
||||||
for (const s of p.node.body)
|
for (const s of p.node.body)
|
||||||
if (t.isExportNamedDeclaration(s))
|
if (t.isExportNamedDeclaration(s))
|
||||||
for (const spec of s.specifiers) {
|
for (const spec of s.specifiers) {
|
||||||
@@ -619,7 +619,7 @@ for (const { file, code } of patchFiles) {
|
|||||||
});
|
});
|
||||||
if (result.status !== 0) throw Error(result.stdout + result.stderr);
|
if (result.status !== 0) throw Error(result.stdout + result.stderr);
|
||||||
}
|
}
|
||||||
// Static binary assets retain their deployed paths; no JS bundle is copied.
|
// 静态二进制资源保留原部署路径,不复制任何 JS 构建包。
|
||||||
const cssFiles = [
|
const cssFiles = [
|
||||||
// 样式保留发布版 scope 选择器,避免在模板已丢失时重新分配作用域导致外观失配。
|
// 样式保留发布版 scope 选择器,避免在模板已丢失时重新分配作用域导致外观失配。
|
||||||
...new Set(
|
...new Set(
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* Failure modes recorded before the fixes:
|
* 修复前记录的失败场景:
|
||||||
* - Certification HTML must keep its QR-refresh script, without reading or writing the console parent.
|
* - 实名认证 HTML 应保留二维码刷新脚本,但不能读写控制台父页面。
|
||||||
* - Receiving a QR URL is not evidence that an image loaded; pending/broken images must not start login polling.
|
* - 收到二维码地址不等于图片已加载;图片等待或损坏时不得开始登录轮询。
|
||||||
* - A broken image needs an accessible error and a retry, and a fresh loaded image must still permit normal login.
|
* - 图片损坏时应提供可访问的错误提示和重试入口;新图片加载成功后仍应允许正常登录。
|
||||||
* All scenarios enter the actual built pages and replace only the external HTTP service or browser clock.
|
* 所有场景均进入实际构建的页面,仅替换外部 HTTP 服务或浏览器时钟。
|
||||||
*/
|
*/
|
||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import { test } from "node:test";
|
import { test } from "node:test";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Certification summaries must preserve the API state instead of treating every nonzero status as approval.
|
* 认证摘要必须保留接口状态,不能把所有非零状态都视为认证通过。
|
||||||
* Gap: home and the real-name page were never exercised with the same failed/submitted/review payload.
|
* 原有回归缺口:首页与实名认证页面此前未使用相同的失败、已提交、审核中响应进行对照验收。
|
||||||
* Only the external HTTP backend is replaced; login, home tiles, real-name routes and certification forms stay real.
|
* 仅替换外部 HTTP 后端;登录、首页卡片、实名认证路由与认证表单均使用实际实现。
|
||||||
*/
|
*/
|
||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import test from "node:test";
|
import test from "node:test";
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ async function releaseResponse(page, release, path) {
|
|||||||
);
|
);
|
||||||
release.resolve();
|
release.resolve();
|
||||||
await (await response).finished();
|
await (await response).finished();
|
||||||
// Absence assertions observe a bounded idle window after the real fetch has completed.
|
// 真实请求完成后,在有界的空闲观察窗口内断言后续工作未发生。
|
||||||
await page.waitForLoadState("networkidle");
|
await page.waitForLoadState("networkidle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user