merge: 合并 DevOps 简历亮点到测试环境

This commit is contained in:
湛兮
2026-06-12 17:05:49 +08:00
4 changed files with 137 additions and 26 deletions
+15
View File
@@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" role="img" aria-labelledby="title">
<title id="title">DevOps 运维平台</title>
<defs>
<linearGradient id="panel" x1="18" x2="78" y1="14" y2="82" gradientUnits="userSpaceOnUse">
<stop stop-color="#22d3ee" />
<stop offset="1" stop-color="#8b5cf6" />
</linearGradient>
</defs>
<rect width="96" height="96" rx="22" fill="#08111f" />
<rect x="16" y="20" width="64" height="48" rx="10" fill="url(#panel)" opacity="0.18" />
<rect x="20" y="24" width="56" height="40" rx="7" fill="#0f172a" stroke="#38bdf8" stroke-opacity="0.65" />
<path d="M29 37h19M29 48h11M53 48h14" stroke="#e0f2fe" stroke-width="4" stroke-linecap="round" />
<circle cx="62" cy="37" r="5" fill="#34d399" />
<path d="M31 74h34M39 64v10M57 64v10" stroke="#a5b4fc" stroke-width="4" stroke-linecap="round" />
</svg>

After

Width:  |  Height:  |  Size: 876 B

+28 -5
View File
@@ -1,3 +1,6 @@
/**
* 将简历数据渲染为对话式作品集页面,负责不同回合的 DOM 结构装配。
*/
import { import {
experiences, experiences,
focusAreas, focusAreas,
@@ -119,15 +122,28 @@ function skillsContent(answer) {
answer.append(el("div", "a-title gen", "Token Stream / Skills")); answer.append(el("div", "a-title gen", "Token Stream / Skills"));
const HOT = new Set([ const HOT = new Set([
"SSE 流式通信", "SSE 流式通信",
"Next.js", "Next.js 16",
"React", "React 19",
"React Native", "React Native",
"TypeScript", "TypeScript",
"NestJS",
"MySQL",
"Redis",
"Jenkins",
"Gitea",
"BPMN",
"Qiankun", "Qiankun",
]); ]);
const grid = el("div", "skills-grid");
skills.forEach((group) => { skills.forEach((group) => {
const wrap = el("div", "skill-group"); const wrap = el("div", "skill-group gen");
wrap.append(el("div", "g-name", group.group)); const head = el("div", "g-head");
head.append(
el("div", "g-name", group.group),
el("span", "g-count", `${group.items.length}`),
);
wrap.append(head);
if (group.summary) wrap.append(el("p", "g-summary", group.summary));
const row = el("div", "tag-row"); const row = el("div", "tag-row");
group.items.forEach((item) => { group.items.forEach((item) => {
row.append( row.append(
@@ -135,8 +151,9 @@ function skillsContent(answer) {
); );
}); });
wrap.append(row); wrap.append(row);
answer.append(wrap); grid.append(wrap);
}); });
answer.append(grid);
} }
function experienceContent(answer) { function experienceContent(answer) {
@@ -200,6 +217,9 @@ const CONTENT = {
/* ---------- 装配 ---------- */ /* ---------- 装配 ---------- */
/**
* 根据对话回合配置生成主内容区,保留滚动叙事所需的 section 结构。
*/
export function renderDialogue(mount) { export function renderDialogue(mount) {
rounds.forEach((round) => { rounds.forEach((round) => {
const section = el("section", "round"); const section = el("section", "round");
@@ -228,6 +248,9 @@ export function renderDialogue(mount) {
}); });
} }
/**
* 生成右侧回合导航节点,并把点击行为交给滚动编排模块处理。
*/
export function renderRail(mount, onJump) { export function renderRail(mount, onJump) {
rounds.forEach((round) => { rounds.forEach((round) => {
const node = el("button", "rail-node"); const node = el("button", "rail-node");
+51 -17
View File
@@ -1,6 +1,10 @@
/**
* 维护作品集页面的简历指标、能力标签、项目经历和职业路径文案。
*/
export const metrics = [ export const metrics = [
{ value: "7 年", label: "Web 与跨端前端经验" }, { value: "7 年", label: "Web 与跨端前端经验" },
{ value: "2 条", label: "近一年参与的产品线" }, { value: "2 条", label: "近一年参与的产品线" },
{ value: "6 个", label: "纳管项目发布闭环" },
{ value: "SSE", label: "对话流、思考态、消息重试" }, { value: "SSE", label: "对话流、思考态、消息重试" },
{ value: "12 个", label: "微前端拆分基础项目" }, { value: "12 个", label: "微前端拆分基础项目" },
{ value: "30%", label: "消息渲染链路优化结果" }, { value: "30%", label: "消息渲染链路优化结果" },
@@ -25,50 +29,80 @@ export const focusAreas = [
}, },
{ {
title: "工程习惯", title: "工程习惯",
summary: "经历过微前端拆分、跨项目公共包、i18n 协作、监控接入和代码审查,能把模块交付和团队维护放在一起考虑。", summary: "经历过微前端拆分、跨项目公共包、i18n 协作、监控接入、发布平台和代码审查,能把模块交付和团队维护放在一起考虑。",
points: ["Qiankun", "Monorepo", "i18n", "Code Review"], points: ["Qiankun", "Monorepo", "DevOps", "Code Review"],
}, },
]; ];
/**
* 首页自我介绍回合的关键叙事点,突出近一年方向与个人项目信号。
*/
export const resumeSignals = [ export const resumeSignals = [
"前端经验覆盖 PC 管理后台、小程序、H5、React Native 和微前端,最近一年主要在 AI 产品团队做业务前端。", "前端经验覆盖 PC 管理后台、小程序、H5、React Native 和微前端,最近一年主要在 AI 产品团队做业务前端。",
"SeaBuzz 侧更偏用户体验:对话、内容流、新闻详情、游客数据、分享和反馈链路。", "SeaBuzz 侧更偏用户体验:对话、内容流、新闻详情、游客数据、分享和反馈链路。",
"SeaCloud / Vtrix 侧更偏控制台:Pricing、Billing、API Keys、组织权限、交易筛选和分销配置。", "SeaCloud / Vtrix 侧更偏控制台:Pricing、Billing、API Keys、组织权限、交易筛选和分销配置。",
"技术栈以 React / Next.js / React Native / TypeScript 为主,也有 Vue、UniApp 和 Qiankun 项目经验。", "个人工程实践里搭建了 DevOps 运维平台,把 Gitea、Jenkins、BPMN、通知、审计、Agent 诊断和 Jenkins 直构导入串成发布闭环。",
"技术栈以 React / Next.js / React Native / TypeScript 为主,能覆盖 Vue、UniApp、Qiankun、NestJS、MySQL、Redis 和 Jenkins/Gitea 发布链路。",
]; ];
/**
* 技能栏按招聘方扫读路径分组,避免基础设施与数据层能力被埋在项目详情里。
*/
export const skills = [ export const skills = [
{ {
group: "对话与内容", group: "前端主栈",
items: ["SSE 流式通信", "打字机响应", "Markdown/LaTeX", "来源引用", "对话历史", "新闻详情"], summary: "主力交付栈,覆盖 AI 产品、控制台、移动端和多端内容流。",
items: ["React 19", "Next.js 16", "React Native", "TypeScript", "Vue 3", "Element Plus", "Tailwind CSS", "Zustand", "Alova"],
}, },
{ {
group: "控制台", group: "数据与后端协作",
items: ["Pricing", "Billing", "API Keys", "组织权限", "额度限制", "交易筛选", "Excel 导出"], summary: "能理解接口、数据模型和状态一致性,不只停留在页面拼装。",
items: ["NestJS", "OpenAPI", "DTO 校验", "Prisma", "MySQL", "Redis", "BullMQ", "幂等键", "乐观锁"],
}, },
{ {
group: "跨端体验", group: "DevOps 与发布",
items: ["React Native", "Expo Router", "NativeWind", "游客转登录", "只读分享", "Smart Image"], summary: "从个人项目实践中补齐发布闭环、可观测性和运维诊断意识。",
items: ["DevOps 平台", "Jenkins", "Jenkins 直构导入", "Gitea", "BPMN", "Outbox", "审计日志", "构建日志脱敏", "Runbook"],
}, },
{ {
group: "Web 主栈", group: "AI 对话与内容",
items: ["Next.js", "React", "Vue 3", "TypeScript", "Tailwind CSS", "Zustand", "Alova"], summary: "最近一年重点投入的方向,关注流式体验、上下文恢复和内容可读性。",
items: ["SSE 流式通信", "打字机响应", "Markdown/LaTeX", "来源引用", "思考态", "对话历史", "新闻详情"],
}, },
{ {
group: "小程序与 H5", group: "控制台业务",
items: ["UniApp", "微信小程序", "飞书小程序", "H5", "摄像头扫码", "低功耗蓝牙"], summary: "长期处理权限、账务、额度、筛选导出等后台业务边界。",
items: ["Pricing", "Billing", "API Keys", "组织权限", "额度限制", "交易筛选", "Excel 导出", "成员权限"],
}, },
{ {
group: "工程协作", group: "跨端与小程序",
items: ["pnpm Monorepo", "Git Submodules", "Qiankun", "Lerna", "i18n 同步", "Code Review"], summary: "覆盖 App、H5、小程序和门店设备链路,能处理端侧能力差异。",
items: ["Expo Router", "NativeWind", "UniApp", "微信小程序", "飞书小程序", "游客转登录", "Smart Image", "摄像头扫码", "低功耗蓝牙"],
}, },
{ {
group: "工程与质量", group: "工程协作与质量",
items: ["ARMS 监控", "CDN 优化", "Playwright", "Git Flow", "分支规范", "新人培训"], summary: "偏团队长期维护视角,关注复用、规范、监控和评审质量。",
items: ["pnpm Monorepo", "Git Submodules", "Qiankun", "Lerna", "i18n 同步", "ARMS 监控", "Playwright", "Git Flow", "Code Review"],
}, },
]; ];
export const projects = [ export const projects = [
{
id: "devops-platform",
name: "DevOps 运维平台",
logo: "/logos/devops-platform.svg",
period: "2026.06 - 至今",
subtitle: "个人项目发布与可观测控制台",
summary:
"从零搭建一套自用 DevOps 运维平台,把本地与线上项目的发布、Jenkins 构建与直构导入、Gitea refs、BPMN 流程、通知 outbox、审计日志和 Agent 诊断收敛到一个控制台。",
modules: [
"前端采用 Vue 3、Vite、TypeScript、Element Plus 和 Pinia,提供登录、成员权限、项目诊断、发布中心、运行记录、系统配置和全局 Agent 抽屉。",
"后端采用 NestJS、Prisma、MySQL、Redis/BullMQ,接入统一 envelope、DTO 校验、结构化日志、审计记录、幂等键和发布单乐观锁。",
"打通 Gitea 分支/tag/commit/PR 摘要、平台触发 Jenkins queue/build 同步、Jenkins 直接构建反向导入、构建日志脱敏读取、取消/重试发布和 BPMN 节点高亮。",
"将通知投递改为 outbox 持久化与可重试模型,并把 LLM Agent 限定在发布风险、失败诊断、Runbook、发布说明和事故复盘场景。",
],
tech: ["Vue 3", "NestJS", "TypeScript", "Prisma", "MySQL", "Redis", "BullMQ", "Jenkins", "Gitea", "BPMN"],
},
{ {
id: "vtrix", id: "vtrix",
name: "SeaCloud / Vtrix", name: "SeaCloud / Vtrix",
+43 -4
View File
@@ -581,19 +581,53 @@ main {
} }
/* ============ Round 4: 技能 ============ */ /* ============ Round 4: 技能 ============ */
.skills-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
}
.skill-group { .skill-group {
margin-bottom: 20px; min-width: 0;
padding: 14px;
border: 1px solid rgba(139, 151, 173, 0.18);
border-radius: 8px;
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)),
rgba(11, 17, 32, 0.54);
}
.g-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 8px;
} }
.skill-group .g-name { .skill-group .g-name {
font-family: var(--mono); font-family: var(--mono);
font-size: 11px; font-size: 11px;
letter-spacing: 0.2em; letter-spacing: 0;
color: var(--ink-faint); color: var(--ink);
margin-bottom: 8px;
text-transform: uppercase; text-transform: uppercase;
} }
.g-count {
flex: 0 0 auto;
font-family: var(--mono);
font-size: 10px;
color: var(--ink-faint);
}
.g-summary {
min-height: 42px;
margin-bottom: 12px;
font-size: 12px;
line-height: 1.65;
color: var(--ink-dim);
}
.skill-token { .skill-token {
font-family: var(--mono); font-family: var(--mono);
font-size: 12px; font-size: 12px;
@@ -607,6 +641,7 @@ main {
.skill-token.hot { .skill-token.hot {
border-color: rgba(34, 211, 238, 0.5); border-color: rgba(34, 211, 238, 0.5);
background: rgba(34, 211, 238, 0.08);
color: var(--cyan); color: var(--cyan);
} }
@@ -768,6 +803,10 @@ main {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.skills-grid {
grid-template-columns: 1fr;
}
#session-rail { #session-rail {
right: auto; right: auto;
top: 54px; top: 54px;