Browse Source
SEO / 线上地址 - Seo.tsx canonical 由 window.location.origin 固定为 https://www.baskbuddy.com, OSS 资源统一走 oss.baskbuddy.com;en 组织名统一为 BaskBuddy (Shanghai) Technology Co., Ltd. - 新增 public/sitemap.xml(含 xhtml:link 三语 alternates),更新 robots.txt、nginx-spa.conf i18n 三语 - Privacy.tsx 重写:原 const isZh = locale !== 'en' 使 /hk/privacy 整页渲染简体, 改为 ZH/HK/EN 三份独立正文,标题与署名按 locale 取值 - Business/NotFound 改用 tr(zh,hk,en) 并移除 isZh;Sustainability/Contact 补 hk 分支 - 8 个 /hk/* 页面的简体字泄漏归零(仅保留语言切换器上的「简」标签) 死代码清理 - global.css 删 997 行 Astro 时代遗留 CSS(余 119 类,0 未引用) - useClientEffects 移除 .stat-value[data-target] 计数与 .copy-btn 剪贴板两个恒空的观察器 - 删 vercel.json(实际部署走 nginx,零引用)与 src/placeholder.ts 首页 - 新增 CompanyVideo 视频区,以及 MemberProfileModal + i18n/teamDetails 团队详情 - 愿景带去重:删掉与 CompanyVideo 左栏重复的「5大核心赛道 / 8+自研产品」两格, 只保留「全球 / 长期」;statsIcons 同步缩为两项——它按下标映射,不改则图标整体错位 - 新增 .stat-band--pair:桌面端 2 列、720px 居中,不影响共用该类名的 Investors 四格版; 英文 Long-term 原在 390px 屏折成两行,按 :lang(en) 单独收一档字号,中文保持原大小 验证:npm run typecheck、npm run build 通过;headless Edge + CDP 于 390/768/1024/1440 四断点逐页核对三语布局,单元格均单行无溢出,Investors 数据带无回归。master
43 changed files with 1806 additions and 1665 deletions
@ -1,5 +1,4 @@ |
|||||
User-agent: * |
User-agent: * |
||||
Allow: / |
Allow: / |
||||
Disallow: /api/ |
|
||||
|
|
||||
Sitemap: https://baskbuddy.com/sitemap.xml |
Sitemap: https://www.baskbuddy.com/sitemap.xml |
||||
|
|||||
@ -0,0 +1,244 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" |
||||
|
xmlns:xhtml="http://www.w3.org/1999/xhtml"> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>weekly</changefreq> |
||||
|
<priority>1.0</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>weekly</changefreq> |
||||
|
<priority>1.0</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>weekly</changefreq> |
||||
|
<priority>1.0</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/about</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/about"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en/about</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/about"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk/about</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/about"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/about"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/business</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.9</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/business"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en/business</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.9</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/business"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk/business</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.9</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/business"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/business"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/news</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>weekly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/news"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en/news</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>weekly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/news"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk/news</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>weekly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/news"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/news"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/sustainability</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.7</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/sustainability"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en/sustainability</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.7</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/sustainability"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk/sustainability</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.7</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/sustainability"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/sustainability"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/investors</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.7</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/investors"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en/investors</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.7</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/investors"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk/investors</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.7</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/investors"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/investors"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/contact</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/contact"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en/contact</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/contact"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk/contact</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>monthly</changefreq> |
||||
|
<priority>0.8</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/contact"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/contact"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/privacy</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>yearly</changefreq> |
||||
|
<priority>0.3</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/privacy"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/en/privacy</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>yearly</changefreq> |
||||
|
<priority>0.3</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/privacy"/> |
||||
|
</url> |
||||
|
<url> |
||||
|
<loc>https://www.baskbuddy.com/hk/privacy</loc> |
||||
|
<lastmod>2026-09-20</lastmod> |
||||
|
<changefreq>yearly</changefreq> |
||||
|
<priority>0.3</priority> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://www.baskbuddy.com/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="zh-HK" href="https://www.baskbuddy.com/hk/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="en-US" href="https://www.baskbuddy.com/en/privacy"/> |
||||
|
<xhtml:link rel="alternate" hreflang="x-default" href="https://www.baskbuddy.com/privacy"/> |
||||
|
</url> |
||||
|
</urlset> |
||||
@ -0,0 +1,113 @@ |
|||||
|
import { getTranslation, type Locale } from '../i18n/utils'; |
||||
|
|
||||
|
/* ===================================================================== |
||||
|
* 公司宣传视频展示模块(首页第二屏) |
||||
|
* |
||||
|
* 版式:左栏通栏品牌色面板承载文案,右栏为「INTRODUCTION」+ 视频画面。 |
||||
|
* 播放策略:直接展示浏览器原生控制条(<video controls>),preload="metadata"。 |
||||
|
* ===================================================================== */ |
||||
|
|
||||
|
/** |
||||
|
* 视频地址(和其他素材一致,走 OSS 直链)。 |
||||
|
* OSS 上为压好的网页版(约 16 MB,见 Content-Length: 16030006);未压缩母版 |
||||
|
* (约 173 MB)放在仓库根目录 media/ 下仅供本地留档——该目录已被 .gitignore |
||||
|
* 忽略,且不在 public/ 内,因此不会被打进 dist/ 或上传到服务器。 |
||||
|
*/ |
||||
|
export const COMPANY_VIDEO_SRC = 'https://oss.baskbuddy.com/baskbuddy/introduction.mp4'; |
||||
|
|
||||
|
/** |
||||
|
* 可选封面图(16:9 观感最佳)。 |
||||
|
* 留空则直接展示视频首帧,无需额外准备图片。 |
||||
|
*/ |
||||
|
export const COMPANY_VIDEO_POSTER = ''; |
||||
|
|
||||
|
/** |
||||
|
* 左侧面板底色。 |
||||
|
* 指定品牌蓝 #3d5afe(与 ICIDP「激情」同色),白字对比度约 5.1:1,稳过 AA。 |
||||
|
*/ |
||||
|
const PANEL_BG = '#3d5afe'; |
||||
|
|
||||
|
export default function CompanyVideo({ locale }: { locale: Locale }) { |
||||
|
const v = getTranslation(locale).home.video; |
||||
|
|
||||
|
return ( |
||||
|
<section className="relative w-full overflow-hidden bg-[var(--bg-primary)] xl:flex xl:min-h-screen xl:items-center"> |
||||
|
{/* 桌面端:左侧固定 850px 的品牌色面板,通栏到视口左/上/下缘; |
||||
|
整段 min-h-screen 占满整屏,内容垂直居中。 */} |
||||
|
<div |
||||
|
aria-hidden="true" |
||||
|
className="hidden xl:block absolute inset-y-0 left-0 w-[850px] max-w-[68vw]" |
||||
|
style={{ background: PANEL_BG }} |
||||
|
/> |
||||
|
|
||||
|
<div className="relative w-full px-4 sm:px-6 xl:px-0"> |
||||
|
<div className="xl:flex xl:items-center"> |
||||
|
{/* ===== 左栏:文案(坐落在 850px 蓝色面板内) ===== |
||||
|
移动/平板端由文案块自带品牌色底并通栏出血;xl 起交给上面的通栏面板。 |
||||
|
版式参照数字 Nexus「01 | Introduction」:大数字 + 单位 + 一段说明的统计块纵列。 */} |
||||
|
<div className="relative xl:w-[850px] xl:shrink-0"> |
||||
|
<span |
||||
|
aria-hidden="true" |
||||
|
className="xl:hidden absolute -inset-x-4 sm:-inset-x-6 inset-y-0" |
||||
|
style={{ background: PANEL_BG }} |
||||
|
/> |
||||
|
|
||||
|
<div className="relative -mx-4 sm:-mx-6 px-4 sm:px-6 py-14 xl:mx-0 xl:px-0 xl:py-24 xl:pl-20 xl:pr-24"> |
||||
|
<h2 className="max-w-[560px] text-h2 xl:text-h1 font-bold font-[family-name:var(--font-display)] leading-[1.15] tracking-tight text-[var(--brand-white)]"> |
||||
|
{v.title} |
||||
|
</h2> |
||||
|
|
||||
|
<p className="mt-3 max-w-[520px] text-body leading-[1.9] text-[color-mix(in_oklch,var(--brand-white)_80%,transparent)]"> |
||||
|
{v.subtitle} |
||||
|
</p> |
||||
|
|
||||
|
<div className="mt-10 flex flex-col gap-9 xl:mt-12 xl:gap-10"> |
||||
|
{v.intro.map((item) => ( |
||||
|
<div key={item.unit} className="scroll-reveal"> |
||||
|
<div className="flex flex-wrap items-baseline gap-x-2.5 gap-y-1"> |
||||
|
<span className="text-h1 font-bold leading-none font-[family-name:var(--font-display)] tracking-tight text-[var(--brand-white)] whitespace-nowrap"> |
||||
|
{item.value} |
||||
|
</span> |
||||
|
<span className="text-h3 font-semibold text-[var(--brand-white)]"> |
||||
|
{item.unit} |
||||
|
</span> |
||||
|
</div> |
||||
|
<p className="mt-2.5 max-w-[520px] text-body leading-[1.85] text-[color-mix(in_oklch,var(--brand-white)_78%,transparent)]"> |
||||
|
{item.desc} |
||||
|
</p> |
||||
|
</div> |
||||
|
))} |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
{/* ===== 右栏:章节序号 + 视频画面 ===== |
||||
|
视频为直角画框,负外边距左移压在蓝色面板上;宽度随右栏自动拉伸, |
||||
|
在 1920+ 视口约占页面宽度 62%~65%。 */} |
||||
|
<div className="relative mt-12 pb-14 xl:mt-0 xl:min-w-0 xl:flex-1 xl:py-24 xl:pr-8 2xl:pr-12"> |
||||
|
<div className="xl:-ml-40"> |
||||
|
<div className="mb-6 flex items-center justify-end gap-3"> |
||||
|
<span className="text-body-sm font-mono uppercase tracking-[0.22em] text-[var(--text-muted)]"> |
||||
|
{v.eyebrow} |
||||
|
</span> |
||||
|
</div> |
||||
|
|
||||
|
{/* 16:9 直角画框:黑底兜底,封面未加载/比例不符时也不会露白; |
||||
|
直接展示原生控制条播放 */} |
||||
|
<div className="relative aspect-video w-full overflow-hidden bg-[var(--brand-black)] shadow-[var(--shadow-md)]"> |
||||
|
<video |
||||
|
src={COMPANY_VIDEO_SRC} |
||||
|
poster={COMPANY_VIDEO_POSTER || undefined} |
||||
|
className="absolute inset-0 w-full h-full object-cover" |
||||
|
preload="metadata" |
||||
|
playsInline |
||||
|
controls |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,178 @@ |
|||||
|
import { useEffect, useRef } from 'react'; |
||||
|
import { Icon } from '@/icons'; |
||||
|
import type { MemberDetail, TeamDetailId } from '@/i18n/zh'; |
||||
|
|
||||
|
/** 弹窗展示的成员快照。刻意做成「对象快照」而不是索引: |
||||
|
轮播的 4s 自动切换会让 teamMembers[teamIdx] 换人,弹窗内容必须钉住点击那一刻的人。 |
||||
|
不含长简介——那是异步加载的,走下面的 DetailState。 */ |
||||
|
export type MemberProfile = { |
||||
|
name: string; |
||||
|
role: string; |
||||
|
group: string; |
||||
|
photo?: string; |
||||
|
/** 无照片时的占位字(About 的 memberInitial 算好传进来) */ |
||||
|
initials: string; |
||||
|
nationality?: string; |
||||
|
detailId: TeamDetailId; |
||||
|
}; |
||||
|
|
||||
|
/** 长简介的加载状态。弹窗头部(姓名/岗位/国籍)不依赖它,所以点开即有内容, |
||||
|
正文区先占位、加载完再填——长简介在单独的 chunk 里,见 i18n/teamDetails/。 */ |
||||
|
export type DetailState = |
||||
|
| { status: 'loading' } |
||||
|
| { status: 'ready'; detail: MemberDetail } |
||||
|
| { status: 'error' }; |
||||
|
|
||||
|
type Labels = { |
||||
|
close: string; |
||||
|
nationalityLabel: string; |
||||
|
introLabel: string; |
||||
|
strengthsLabel: string; |
||||
|
traitsLabel: string; |
||||
|
loadingLabel: string; |
||||
|
errorLabel: string; |
||||
|
}; |
||||
|
|
||||
|
/** 成员详情弹窗。 |
||||
|
* 用原生 <dialog> + showModal() 而不是 portal + 手写遮罩: |
||||
|
* · top layer 渲染天然逃出 .page-enter / .scroll-reveal 的 transform 包含块 |
||||
|
* (否则 fixed 定位会以那个祖先为基准、跟着页面滚); |
||||
|
* · 自带 Esc 关闭、焦点陷阱、背景 inert,省掉 portal / z-index 军备竞赛; |
||||
|
* · 仍是 DOM 子树里的节点,字体与字色自动继承 RootLayout(portal 到 body 会丢)。 */ |
||||
|
export default function MemberProfileModal({ |
||||
|
member, |
||||
|
detail, |
||||
|
labels, |
||||
|
onClose, |
||||
|
}: { |
||||
|
member: MemberProfile; |
||||
|
detail: DetailState; |
||||
|
labels: Labels; |
||||
|
onClose: () => void; |
||||
|
}) { |
||||
|
const dialogRef = useRef<HTMLDialogElement>(null); |
||||
|
const titleId = 'member-profile-title'; |
||||
|
|
||||
|
useEffect(() => { |
||||
|
const el = dialogRef.current; |
||||
|
if (!el) return; |
||||
|
// StrictMode 下 effect 会跑两遍,对已 open 的 dialog 再调 showModal() 会抛 InvalidStateError
|
||||
|
if (!el.open) el.showModal(); |
||||
|
// 焦点落在弹窗容器而非关闭按钮上,屏读先念标题
|
||||
|
el.focus(); |
||||
|
|
||||
|
// 锁背景滚动。body 上已有 overflow-x:hidden 与安全区内边距,所以用 class 而不是内联
|
||||
|
// style,避免把 padding 覆盖掉;--sbw 补偿滚动条消失的宽度,防止锁定瞬间横向抖动。
|
||||
|
document.body.style.setProperty( |
||||
|
'--sbw', |
||||
|
`${Math.max(0, window.innerWidth - document.documentElement.clientWidth)}px`, |
||||
|
); |
||||
|
document.body.classList.add('is-modal-open'); |
||||
|
|
||||
|
return () => { |
||||
|
document.body.classList.remove('is-modal-open'); |
||||
|
document.body.style.removeProperty('--sbw'); |
||||
|
if (el.open) el.close(); |
||||
|
}; |
||||
|
}, []); |
||||
|
|
||||
|
return ( |
||||
|
<dialog |
||||
|
ref={dialogRef} |
||||
|
className="member-modal" |
||||
|
tabIndex={-1} |
||||
|
aria-labelledby={titleId} |
||||
|
// Esc:拦下原生关闭,统一由 React 卸载(状态只有一个来源)
|
||||
|
onCancel={(e) => { |
||||
|
e.preventDefault(); |
||||
|
onClose(); |
||||
|
}} |
||||
|
// 点遮罩关闭:::backdrop 不是 DOM 节点,点到它时 target 就是 dialog 本身;
|
||||
|
// 弹窗内容由 head + body 两段铺满,所以只有遮罩会命中这个判断。
|
||||
|
onMouseDown={(e) => { |
||||
|
if (e.target === dialogRef.current) onClose(); |
||||
|
}} |
||||
|
> |
||||
|
<div className="member-modal-head"> |
||||
|
<div className="member-modal-portrait"> |
||||
|
{member.photo ? ( |
||||
|
<img |
||||
|
src={member.photo} |
||||
|
alt="" |
||||
|
className="absolute inset-0 h-full w-full object-cover" |
||||
|
decoding="async" |
||||
|
/> |
||||
|
) : ( |
||||
|
<span |
||||
|
aria-hidden="true" |
||||
|
className="absolute inset-0 flex items-center justify-center" |
||||
|
style={{ |
||||
|
background: |
||||
|
'linear-gradient(160deg, color-mix(in oklch, var(--brand-accent) 16%, var(--bg-primary)) 0%, color-mix(in oklch, var(--brand-accent) 34%, var(--bg-primary)) 100%)', |
||||
|
}} |
||||
|
> |
||||
|
<span className="text-h3 font-bold font-[family-name:var(--font-display)] text-[var(--brand-accent-deep)]"> |
||||
|
{member.initials} |
||||
|
</span> |
||||
|
</span> |
||||
|
)} |
||||
|
</div> |
||||
|
|
||||
|
<div className="min-w-0 flex-1"> |
||||
|
<div className="text-body-sm font-mono uppercase tracking-[0.22em] text-[var(--text-muted)]"> |
||||
|
{member.group} |
||||
|
</div> |
||||
|
<h2 |
||||
|
id={titleId} |
||||
|
className="mt-2 text-h2 font-bold font-[family-name:var(--font-display)] leading-tight text-[var(--brand-black)]" |
||||
|
> |
||||
|
{member.name} |
||||
|
</h2> |
||||
|
<div className="mt-1.5 text-body text-[var(--text-secondary)]">{member.role}</div> |
||||
|
{/* 国籍标签:英文国名比中文长得多,nowrap 防止在窄屏被拆成两行。 |
||||
|
国籍不随长简介一起异步加载,所以这个标签点开即在。 */} |
||||
|
{member.nationality && ( |
||||
|
<span className="mt-3 inline-flex items-center gap-1.5 whitespace-nowrap rounded-full border border-[var(--border-light)] bg-[var(--bg-subtle)] px-3 py-1 text-body-sm text-[var(--text-muted)]"> |
||||
|
{labels.nationalityLabel} · {member.nationality} |
||||
|
</span> |
||||
|
)} |
||||
|
</div> |
||||
|
|
||||
|
<button |
||||
|
type="button" |
||||
|
onClick={onClose} |
||||
|
aria-label={labels.close} |
||||
|
className="-mt-1 ml-auto flex h-9 w-9 flex-none items-center justify-center rounded-full border border-[var(--border-light)] text-[var(--text-muted)] transition-colors duration-200 hover:border-[var(--brand-black)] hover:text-[var(--brand-black)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--brand-accent)]" |
||||
|
> |
||||
|
<Icon name="x" className="h-4 w-4" /> |
||||
|
</button> |
||||
|
</div> |
||||
|
|
||||
|
<div className="member-modal-body"> |
||||
|
{detail.status === 'ready' ? ( |
||||
|
<> |
||||
|
<section className="member-modal-section"> |
||||
|
<h3>{labels.introLabel}</h3> |
||||
|
<p>{detail.detail.intro}</p> |
||||
|
</section> |
||||
|
<section className="member-modal-section"> |
||||
|
<h3>{labels.strengthsLabel}</h3> |
||||
|
<p>{detail.detail.strengths}</p> |
||||
|
</section> |
||||
|
<section className="member-modal-section"> |
||||
|
<h3>{labels.traitsLabel}</h3> |
||||
|
<p>{detail.detail.traits}</p> |
||||
|
</section> |
||||
|
</> |
||||
|
) : ( |
||||
|
// aria-live:加载完成/失败时读屏会念出变化,而不是静默换掉正文。
|
||||
|
// min-h 只是给占位一个下限,免得弹窗先矮后高跳一下——不能写进
|
||||
|
// .member-modal-body 的 min-height,那条被 flex 收缩用着(见 global.css)。
|
||||
|
<p aria-live="polite" className="min-h-[180px] text-body text-[var(--text-muted)]"> |
||||
|
{detail.status === 'loading' ? labels.loadingLabel : labels.errorLabel} |
||||
|
</p> |
||||
|
)} |
||||
|
</div> |
||||
|
</dialog> |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
import type { MemberDetail, TeamDetailId } from '../zh'; |
||||
|
|
||||
|
/** Team member profiles (English). See ./zh.ts for why these live outside en.ts. */ |
||||
|
export const enTeamDetails = { |
||||
|
'yang-xingxing': { |
||||
|
intro: |
||||
|
'Yang Xingxing is a full-stack engineer and the front-end lead for our core job-and-recruitment intelligence product. They own front-end and back-end architecture, core system development, API governance and feature iteration, and take part in requirement reviews and technical decision-making. Day to day they build with Vibe Coding, and have shipped RAG retrieval-augmented systems and Agent modules that bring large-model capability into our business systems.', |
||||
|
strengths: |
||||
|
'Fluent across mainstream front-end frameworks such as React and Vue, with Node.js, Java and Python on the back end, and solid grounding in microservice architecture, high-concurrency optimisation and cloud-native deployment. Able to build RAG knowledge bases, vector search and document-processing pipelines, orchestrate Agent tasks, and carry a project independently from requirement analysis and system design through to delivery — using AI tooling where it genuinely speeds development up.', |
||||
|
traits: |
||||
|
'Always tracking frontier work on Agents and RAG, and putting it into production. Rigorous in code, with a focus on stability, maintainability and extensibility. Communicates well across teams, reads business requirements accurately, and delivers solutions that are both technically sound and commercially useful.', |
||||
|
}, |
||||
|
'zhang-shun': { |
||||
|
intro: |
||||
|
'Zhang Shun is a back-end engineer and product manager, and leads our core job-and-recruitment intelligence product. Their work covers back-end system design, feature development, database design, API development, performance tuning and day-to-day system maintenance.', |
||||
|
strengths: |
||||
|
'Experienced with Java, Spring Boot, MySQL and Redis, with a strong programming foundation and solid system-design ability. They can independently handle requirement analysis, API design, feature development and troubleshooting, with a firm focus on security, stability and code quality, backed by deep experience in data processing, service architecture and business logic.', |
||||
|
traits: |
||||
|
'Careful and rigorous, with a strong sense of responsibility, good logical thinking and clear communication. They hold to coding standards, data security and risk control, are skilled at tracking down complex technical problems, and work closely with every team to land projects on stable, dependable technical foundations.', |
||||
|
}, |
||||
|
'chen-jie': { |
||||
|
intro: |
||||
|
'Chen Jie is a front-end engineer and the front-end lead for our core content-and-social intelligence product. They are responsible for building and maintaining project pages — layout, interactions, API integration and multi-device adaptation.', |
||||
|
strengths: |
||||
|
'Familiar with the front-end development workflow and equipped with a solid technical foundation, they deliver page development, performance optimisation and troubleshooting efficiently, and have a deep understanding of mobile adaptation and user experience.', |
||||
|
traits: |
||||
|
'Meticulous and responsible, with close attention to coding standards and detail, plus patience and good communication skills. They work steadily alongside product, design, back-end and QA teams to make sure projects ship on schedule and to a high standard.', |
||||
|
}, |
||||
|
'zhang-buyun': { |
||||
|
intro: |
||||
|
'Zhang Buyun is a front-end engineer and UI designer, and leads our core content-and-social intelligence product. They build and maintain our H5, WeChat Mini Program and PC pages, integrate APIs with back-end engineers, implement interactions and motion, and keep improving front-end performance and cross-platform compatibility — alongside requirement reviews, technical design and production troubleshooting.', |
||||
|
strengths: |
||||
|
'Comfortable with the mainstream front-end stack (Vue, React, Taro and more), with a solid grounding in HTML, CSS and JavaScript. They turn UI designs into faithful code, have hands-on experience with front-end engineering, componentisation and performance work, and can take a page from first build all the way through to API integration.', |
||||
|
traits: |
||||
|
'Clear-headed and detail-oriented, with high standards for code quality and user experience. They communicate well and work as part of a team, turning business requirements into technical implementation quickly. Steady and quick to learn, they work patiently through problems and coordinate closely with product, design and back-end colleagues.', |
||||
|
}, |
||||
|
} satisfies Record<TeamDetailId, MemberDetail>; |
||||
|
|
||||
|
export default enTeamDetails; |
||||
@ -0,0 +1,39 @@ |
|||||
|
import type { MemberDetail, TeamDetailId } from '../zh'; |
||||
|
|
||||
|
/** 團隊成員長簡介(繁體)。拆分理由見 ./zh.ts。 */ |
||||
|
export const hkTeamDetails = { |
||||
|
'yang-xingxing': { |
||||
|
intro: |
||||
|
'楊幸幸,全棧開發工程師,目前擔任公司核心業務——求職招聘智能服務產品的前端負責人,主要負責前後端架構設計、核心業務系統研發、接口治理與產品功能迭代,參與需求評審與技術方案決策;日常以 Vibe Coding 方式編碼開發,同時基於業務場景落地 RAG 檢索增強系統與 Agent 智能體模組,推動大模型能力與業務系統整合。', |
||||
|
strengths: |
||||
|
'精通 React/Vue 等主流前端框架與 Node.js/Java/Python 後端技術,熟悉微服務架構、高併發場景優化與雲原生部署;具備 RAG 知識庫建構、向量檢索、文件處理及 Agent 任務編排能力,擁有從需求分析、系統設計到業務開發與 AI 應用落地的全鏈路獨立開發能力,能合理運用 AI 開發工具提升編碼效率。', |
||||
|
traits: |
||||
|
'持續關注 Agent、RAG 等前沿技術並落地業務,編碼嚴謹,重視系統穩定性、可維護性與可擴展性;擅長跨團隊溝通協作,能準確理解業務需求,輸出兼具技術合理性與業務價值的解決方案,善用 AI 工具賦能研發,為團隊產品迭代與技術建設提供支撐。', |
||||
|
}, |
||||
|
'zhang-shun': { |
||||
|
intro: |
||||
|
'張順,現任公司後端開發工程師兼產品經理,目前擔任公司核心業務——求職招聘智能服務產品的負責人,主要負責後端系統設計、業務功能開發、數據庫設計、接口開發、效能優化以及系統日常維護工作。', |
||||
|
strengths: |
||||
|
'熟悉 Java、Spring Boot、MySQL、Redis 等後端技術,具備紮實的編程基礎與良好的系統設計能力,能獨立完成業務需求分析、接口設計、功能開發與問題排查,重視系統安全性、穩定性與程式碼品質,在數據處理、服務架構及業務邏輯實現上經驗豐富。', |
||||
|
traits: |
||||
|
'做事認真嚴謹,責任心強,具備良好的邏輯思維、問題分析與溝通協作能力。工作中注重程式碼規範、數據安全與風險控制,善於定位並解決複雜技術問題,能積極配合各部門推進項目落地,以穩定可靠的技術方案為公司業務發展提供後端支持。', |
||||
|
}, |
||||
|
'chen-jie': { |
||||
|
intro: |
||||
|
'陳潔,現任前端開發工程師,目前擔任公司核心業務——內容社交智能服務產品的前端負責人,主要負責公司項目頁面的開發與維護,包括頁面搭建、互動實現、接口聯調以及多機型適配等工作。', |
||||
|
strengths: |
||||
|
'熟悉前端開發流程,具備紮實的前端技術基礎,能高效完成頁面開發、效能優化和問題排查,對移動端適配與用戶體驗有很深的體會和了解。', |
||||
|
traits: |
||||
|
'做事認真細緻,責任心強,注重程式碼規範與細節打磨,具備良好的耐心與溝通能力。工作中踏實穩重,善於配合產品、設計、後端及測試團隊完成協作,以專業嚴謹的工作態度保障項目按期高品質上線。', |
||||
|
}, |
||||
|
'zhang-buyun': { |
||||
|
intro: |
||||
|
'張卜允,現任前端開發工程師兼 UI 設計師,目前擔任公司核心業務——內容社交智能服務產品的負責人,主要負責公司 H5、微信小程序及 PC 端頁面的開發與維護,與後端工程師對接接口聯調,實現頁面互動與動態效果,持續優化前端效能與多端相容性,並參與需求評審、技術方案設計及線上問題排查等工作。', |
||||
|
strengths: |
||||
|
'熟悉主流前端技術棧(Vue/React/Taro 等),具備紮實的 HTML、CSS、JavaScript 基礎,能高效還原 UI 設計稿,對前端工程化、組件化開發及效能優化有一定實踐經驗,能獨立完成從頁面搭建到接口對接的完整開發流程。', |
||||
|
traits: |
||||
|
'邏輯清晰,注重細節,對程式碼規範與用戶體驗有較高要求;具備良好的溝通能力與團隊協作意識,能快速理解業務需求並轉化為技術實現。工作中踏實穩重,學習能力強,面對問題耐心排查,善於配合產品、設計及後端同事推進項目,以嚴謹負責的技術態度為公司產品研發與業務落地提供可靠保障。', |
||||
|
}, |
||||
|
} satisfies Record<TeamDetailId, MemberDetail>; |
||||
|
|
||||
|
export default hkTeamDetails; |
||||
@ -0,0 +1,27 @@ |
|||||
|
import type { MemberDetail, TeamDetailId } from '../zh'; |
||||
|
import type { Locale } from '../utils'; |
||||
|
|
||||
|
export type TeamDetailMap = Record<TeamDetailId, MemberDetail>; |
||||
|
|
||||
|
/** 每个语种一个 chunk。Vite 看到的是静态字面量的 import(),能静态分析出这三个分包, |
||||
|
* 所以它们不会被打进主包——这正是把长简介从 i18n/*.ts 里搬出来的目的。 */ |
||||
|
const loaders: Record<Locale, () => Promise<{ default: TeamDetailMap }>> = { |
||||
|
zh: () => import('./zh'), |
||||
|
hk: () => import('./hk'), |
||||
|
en: () => import('./en'), |
||||
|
}; |
||||
|
|
||||
|
/** 缓存的是 Promise 而不是结果:弹窗开着时若因故重入,也不会并发打两次请求。 */ |
||||
|
const cache = new Map<Locale, Promise<TeamDetailMap>>(); |
||||
|
|
||||
|
/** 按需拉取某个语种的成员长简介。同一语种只发一次请求。 */ |
||||
|
export function loadTeamDetails(locale: Locale): Promise<TeamDetailMap> { |
||||
|
let pending = cache.get(locale); |
||||
|
if (!pending) { |
||||
|
pending = loaders[locale]().then((m) => m.default); |
||||
|
// 失败时把 promise 从缓存里摘掉,否则后续每次重试都只会拿到同一个 rejected promise
|
||||
|
pending.catch(() => cache.delete(locale)); |
||||
|
cache.set(locale, pending); |
||||
|
} |
||||
|
return pending; |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
import type { MemberDetail, TeamDetailId } from '../zh'; |
||||
|
|
||||
|
/** 团队成员长简介(简体)。 |
||||
|
* |
||||
|
* 刻意从 zh.ts 里拆出来单独放,原因只有一个:这三段正文每人 300–450 字,而 |
||||
|
* 9 位成员里只有 4 位有——它却跟着 locale 一起被打进主包,导致首页、业务、 |
||||
|
* 新闻这些根本用不到的页面每次首屏都在下载它。挪到这里之后,由 About 在用户 |
||||
|
* 真要开弹窗时才 `import()`,见 ./index.ts。 |
||||
|
* |
||||
|
* 用 Record<TeamDetailId, ...> 收口:少写一位成员、或写了 id 联合类型里没有的 |
||||
|
* 键,都会在 tsc 阶段报错。三个语种各一份,缺一即挂。 */ |
||||
|
export const zhTeamDetails = { |
||||
|
'yang-xingxing': { |
||||
|
intro: |
||||
|
'杨幸幸,全栈开发工程师,目前担任公司核心业务——求职招聘智能服务产品的前端负责人,主要负责前后端架构设计、核心业务系统研发、接口治理与产品功能迭代,参与需求评审与技术方案决策;日常以 Vibe Coding 方式编码开发,同时基于业务场景落地 RAG 检索增强系统与 Agent 智能体模块,推动大模型能力与业务系统集成。', |
||||
|
strengths: |
||||
|
'精通 React/Vue 等主流前端框架与 Node.js/Java/Python 后端技术,熟悉微服务架构、高并发场景优化与云原生部署;具备 RAG 知识库构建、向量检索、文档处理及 Agent 任务编排能力,拥有从需求分析、系统设计到业务开发与 AI 应用落地的全链路独立开发能力,能够合理运用 AI 开发工具提升编码效率。', |
||||
|
traits: |
||||
|
'持续关注 Agent、RAG 等前沿技术并落地业务,编码严谨,重视系统稳定性、可维护性与可扩展性;擅长跨团队沟通协作,能够准确理解业务需求,输出兼具技术合理性与业务价值的解决方案,善用 AI 工具赋能研发,为团队产品迭代与技术建设提供支撑。', |
||||
|
}, |
||||
|
'zhang-shun': { |
||||
|
intro: |
||||
|
'张顺,现任公司后端开发工程师兼产品经理,目前担任公司核心业务——求职招聘智能服务产品的负责人,主要负责后端系统设计、业务功能开发、数据库设计、接口开发、性能优化以及系统日常维护工作。', |
||||
|
strengths: |
||||
|
'熟悉 Java、Spring Boot、MySQL、Redis 等后端技术,具备扎实的编程基础和良好的系统设计能力,能够独立完成业务需求分析、接口设计、功能开发与问题排查,重视系统安全性、稳定性和代码质量,在数据处理、服务架构及业务逻辑实现上经验丰富。', |
||||
|
traits: |
||||
|
'做事认真严谨,责任心强,具备良好的逻辑思维、问题分析与沟通协作能力。工作中注重代码规范、数据安全和风险控制,善于定位并解决复杂技术问题,能够积极配合各部门推进项目落地,以稳定可靠的技术方案为公司业务发展提供后端支持。', |
||||
|
}, |
||||
|
'chen-jie': { |
||||
|
intro: |
||||
|
'陈洁,现任前端开发工程师,目前担任公司核心业务——内容社交智能服务产品的前端负责人,主要负责公司项目页面的开发与维护,包括页面搭建、交互实现、接口联调以及多机型适配等工作。', |
||||
|
strengths: |
||||
|
'熟悉前端开发流程,具备扎实的前端技术基础,能够高效完成页面开发、性能优化和问题排查,对移动端适配与用户体验有很深的体会和了解。', |
||||
|
traits: |
||||
|
'做事认真细致,责任心强,注重代码规范与细节打磨,具备良好的耐心与沟通能力。工作中踏实稳重,善于配合产品、设计、后端及测试团队完成协作,以专业严谨的工作态度保障项目按期高质量上线。', |
||||
|
}, |
||||
|
'zhang-buyun': { |
||||
|
intro: |
||||
|
'张卜允,现任前端开发工程师兼 UI 设计师,目前担任公司核心业务——内容社交智能服务产品的负责人,主要负责公司 H5、微信小程序及 PC 端页面的开发与维护,与后端工程师对接接口联调,实现页面交互与动态效果,持续优化前端性能与多端兼容性,并参与需求评审、技术方案设计及线上问题排查等工作。', |
||||
|
strengths: |
||||
|
'熟悉主流前端技术栈(Vue/React/Taro 等),具备扎实的 HTML、CSS、JavaScript 基础,能够高效还原 UI 设计稿,对前端工程化、组件化开发及性能优化有一定实践经验,能够独立完成从页面搭建到接口对接的完整开发流程。', |
||||
|
traits: |
||||
|
'逻辑清晰,注重细节,对代码规范和用户体验有较高要求;具备良好的沟通能力与团队协作意识,能够快速理解业务需求并转化为技术实现。工作中踏实稳重,学习能力强,面对问题耐心排查,善于配合产品、设计及后端同事推进项目,以严谨负责的技术态度为公司产品研发与业务落地提供可靠保障。', |
||||
|
}, |
||||
|
} satisfies Record<TeamDetailId, MemberDetail>; |
||||
|
|
||||
|
export default zhTeamDetails; |
||||
@ -1,5 +0,0 @@ |
|||||
// 统一占位图:全站内容图(办公/团队/业务/新闻/横幅等)共用此图。
|
|
||||
// 图片统一托管于 OSS:https://oss.baskbuddy.com/baskbuddy/
|
|
||||
// 若要替换占位图,把对应文件上传到 OSS 后改本常量一处即可全局生效。
|
|
||||
export const PLACEHOLDER_IMG = |
|
||||
'https://oss.baskbuddy.com/baskbuddy/placeholder.jpg'; |
|
||||
File diff suppressed because it is too large
@ -1,13 +0,0 @@ |
|||||
{ |
|
||||
"rewrites": [ |
|
||||
{ "source": "/robots.txt", "destination": "/robots.txt" }, |
|
||||
{ "source": "/sitemap.xml", "destination": "/sitemap.xml" }, |
|
||||
{ "source": "/og-default.png", "destination": "/og-default.png" }, |
|
||||
{ "source": "/og-about.png", "destination": "/og-about.png" }, |
|
||||
{ "source": "/og-business.png", "destination": "/og-business.png" }, |
|
||||
{ "source": "/og-innovation.png", "destination": "/og-innovation.png" }, |
|
||||
{ "source": "/og-join.png", "destination": "/og-join.png" }, |
|
||||
{ "source": "/og-contact.png", "destination": "/og-contact.png" }, |
|
||||
{ "source": "/(.*)", "destination": "/index.html" } |
|
||||
] |
|
||||
} |
|
||||
Loading…
Reference in new issue