diff --git a/nginx-spa.conf b/nginx-spa.conf
index ee5444e..70cd167 100644
--- a/nginx-spa.conf
+++ b/nginx-spa.conf
@@ -45,8 +45,11 @@ server {
}
# all other routes fall back to index.html for React Router
+ # index.html 必须每次回源校验(no-cache):SPA 入口引用带 hash 的 /assets 文件,
+ # 部署新版后旧 hash 会被删除;浏览器缓存了旧 HTML 就会请求到 404 的 JS → 白屏。
location / {
try_files $uri $uri/ /index.html;
+ add_header Cache-Control "no-cache";
}
}
diff --git a/package-lock.json b/package-lock.json
index 68e84ee..9800259 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,8 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.28.0",
- "tailwind-merge": "^3.0.0"
+ "tailwind-merge": "^3.0.0",
+ "three": "^0.186.0"
},
"devDependencies": {
"@types/node": "^24.13.3",
@@ -1815,6 +1816,12 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/three": {
+ "version": "0.186.0",
+ "resolved": "https://registry.npmmirror.com/three/-/three-0.186.0.tgz",
+ "integrity": "sha512-cr/fIM2ddMSVbYVgkfD4jLJv7Fh/8ZTjvo+7gQeSVGUZHxpx9FDwoL5iC7hUz/LiRA8wMbqfnb90xKfm1/HHkQ==",
+ "license": "MIT"
+ },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
diff --git a/package.json b/package.json
index a993544..661affe 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,8 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.28.0",
- "tailwind-merge": "^3.0.0"
+ "tailwind-merge": "^3.0.0",
+ "three": "^0.186.0"
},
"devDependencies": {
"@types/node": "^24.13.3",
diff --git a/public/baskbuddy-logo.png b/public/baskbuddy-logo.png
deleted file mode 100644
index d21ae89..0000000
Binary files a/public/baskbuddy-logo.png and /dev/null differ
diff --git a/public/connect-life.jpg b/public/connect-life.jpg
deleted file mode 100644
index 9f27171..0000000
Binary files a/public/connect-life.jpg and /dev/null differ
diff --git a/public/hero-bg.jpg b/public/hero-bg.jpg
deleted file mode 100644
index ac1abc6..0000000
Binary files a/public/hero-bg.jpg and /dev/null differ
diff --git a/public/innovation-hero.jpg b/public/innovation-hero.jpg
deleted file mode 100644
index 5730cb1..0000000
Binary files a/public/innovation-hero.jpg and /dev/null differ
diff --git a/public/office-warmth.jpg b/public/office-warmth.jpg
deleted file mode 100644
index 53eb4b5..0000000
Binary files a/public/office-warmth.jpg and /dev/null differ
diff --git a/public/pillar-consumer.jpg b/public/pillar-consumer.jpg
deleted file mode 100644
index 28b4ab4..0000000
Binary files a/public/pillar-consumer.jpg and /dev/null differ
diff --git a/public/pillar-enterprise.jpg b/public/pillar-enterprise.jpg
deleted file mode 100644
index f97c0a7..0000000
Binary files a/public/pillar-enterprise.jpg and /dev/null differ
diff --git a/public/pillar-future.jpg b/public/pillar-future.jpg
deleted file mode 100644
index fb6da2b..0000000
Binary files a/public/pillar-future.jpg and /dev/null differ
diff --git a/public/team-female.jpg b/public/team-female.jpg
deleted file mode 100644
index 10c7b64..0000000
Binary files a/public/team-female.jpg and /dev/null differ
diff --git a/public/team-male.jpg b/public/team-male.jpg
deleted file mode 100644
index 0176c59..0000000
Binary files a/public/team-male.jpg and /dev/null differ
diff --git a/src/assets/dog.svg b/src/assets/dog.svg
new file mode 100644
index 0000000..91b4c23
--- /dev/null
+++ b/src/assets/dog.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/src/components/EcosystemMap.tsx b/src/components/EcosystemMap.tsx
index 6b8a4eb..86f49fb 100644
--- a/src/components/EcosystemMap.tsx
+++ b/src/components/EcosystemMap.tsx
@@ -14,7 +14,7 @@ type Aud = { c: boolean; b: boolean; f: boolean };
const MATRIX: Aud[][] = [
// 内容社交:青核 / 音酷 / 蜜恋
[{ c: true, b: false, f: false }, { c: true, b: false, f: false }, { c: true, b: false, f: false }],
- // 职场服务:职来 / 看山
+ // 职场服务:轻松聘 / 智愿通
[{ c: true, b: true, f: false }, { c: true, b: true, f: false }],
// 数字支付:妥哒
[{ c: true, b: true, f: false }],
diff --git a/src/components/Mascot.tsx b/src/components/Mascot.tsx
index 76a0937..72aa288 100644
--- a/src/components/Mascot.tsx
+++ b/src/components/Mascot.tsx
@@ -1,6 +1,7 @@
import { useEffect, useRef, useState, useCallback } from 'react';
import { useLocation } from 'react-router-dom';
import { getLocaleFromPathname, type Locale } from '@/i18n/utils';
+import dogSvgRaw from '@/assets/dog.svg?raw';
type Mood = 'idle' | 'wave' | 'think' | 'cheer' | 'squeeze';
@@ -165,6 +166,35 @@ export default function Mascot() {
const hideTimerRef = useRef(null);
const idleTimerRef = useRef(null);
const scrollCooldownRef = useRef(null);
+ const mascotBtnRef = useRef(null);
+
+ // 视线跟随:小狗眼睛随鼠标方向轻微转动(外层 g 位移,与眨眼动画分层不冲突)。
+ // 位移上限 7 个 SVG 用户单位(缩到 90px 后约 2px 屏幕位移),克制不夸张。
+ useEffect(() => {
+ const btn = mascotBtnRef.current;
+ if (!btn) return;
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
+ if (window.matchMedia('(hover: none)').matches) return; // 触屏无悬停语义
+ let raf = 0;
+ const onMove = (e: PointerEvent) => {
+ const r = btn.getBoundingClientRect();
+ const dx = e.clientX - (r.left + r.width / 2);
+ const dy = e.clientY - (r.top + r.height / 2);
+ const dist = Math.hypot(dx, dy) || 1;
+ const k = Math.min(dist / 240, 1) * 7;
+ if (raf) return;
+ raf = requestAnimationFrame(() => {
+ raf = 0;
+ btn.style.setProperty('--eye-x', `${((dx / dist) * k).toFixed(2)}`);
+ btn.style.setProperty('--eye-y', `${((dy / dist) * k).toFixed(2)}`);
+ });
+ };
+ window.addEventListener('pointermove', onMove, { passive: true });
+ return () => {
+ window.removeEventListener('pointermove', onMove);
+ if (raf) cancelAnimationFrame(raf);
+ };
+ }, []);
const clearAllTimers = () => {
[showTimerRef, hideTimerRef, idleTimerRef, scrollCooldownRef].forEach((r) => {
@@ -350,6 +380,7 @@ export default function Mascot() {
);
diff --git a/src/components/Sustainability.tsx b/src/components/Sustainability.tsx
index af56a4f..8bffd6e 100644
--- a/src/components/Sustainability.tsx
+++ b/src/components/Sustainability.tsx
@@ -17,11 +17,11 @@ export default function Sustainability({ locale }: { locale: Locale }) {
// 责任 × 产品挂钩:三方向对应 5 赛道 8 产品中的具体落点
// ti/pi = track/product 索引,与 i18n business.tracks 顺序一致
- // 0 内容社交(青核/音酷/蜜恋) · 1 职场服务(职来/看山) · 2 数字支付(妥哒) · 3 人工智能(阿布AI) · 4 生活服务(听愿)
+ // 0 内容社交(青核/音酷/蜜恋) · 1 职场服务(轻松聘/智愿通) · 2 数字支付(妥哒) · 3 人工智能(阿布AI) · 4 生活服务(听愿)
const links = [
// 绿色低碳:阿布 AI 的算力能效
[{ ti: 3, pi: 0, role: tr('算力能效', '算力能效', 'Compute efficiency') }],
- // 数字普惠:妥哒支付普惠 · 看山知识普惠 · 职来职业流动 · 听愿心愿互助
+ // 数字普惠:妥哒支付普惠 · 智愿通知识普惠 · 轻松聘职业流动 · 听愿心愿互助
[
{ ti: 2, pi: 0, role: tr('支付普惠', '支付普惠', 'Payment inclusion') },
{ ti: 1, pi: 1, role: tr('知识普惠', '知識普惠', 'Knowledge inclusion') },
diff --git a/src/i18n/hk.ts b/src/i18n/hk.ts
index 7a147cc..0c72d14 100644
--- a/src/i18n/hk.ts
+++ b/src/i18n/hk.ts
@@ -116,7 +116,7 @@ export const hk = {
about: {
title: '關於我們',
subtitle: '巴適夥伴,一生相伴',
- intro: `巴適夥伴(上海)科技有限公司是一家聚焦數字生活服務領域,依託多品牌、多垂直賽道的產品佈局,面向不同用戶群體提供優質產品與服務的高科技企業,透過旗下多家獨立運營的子公司,分別深耕內容社交(青核、音酷、蜜戀)、職場服務(職來、看山)、數字支付(妥噠)、人工智能(阿布 AI)、生活服務(聽願)等多個領域,始終堅持以用戶需求為核心,堅持品質第一與技術創新,為員工創造成長空間,為用戶創造美好生活,為社會創造長期價值。`,
+ intro: `巴適夥伴(上海)科技有限公司是一家聚焦數字生活服務領域,依託多品牌、多垂直賽道的產品佈局,面向不同用戶群體提供優質產品與服務的高科技企業,透過旗下多家獨立運營的子公司,分別深耕內容社交(青核、音酷、蜜戀)、職場服務(輕鬆聘、智願通)、數字支付(妥噠)、人工智能(阿布 AI)、生活服務(聽願)等多個領域,始終堅持以用戶需求為核心,堅持品質第一與技術創新,為員工創造成長空間,為用戶創造美好生活,為社會創造長期價值。`,
visionMission: {
vision: '打造全球領先的數字生活服務生態,讓不同需求的用戶都能獲得優質適配的產品體驗',
mission: '以創新技術連接人與服務,依託多元垂直領域產品,為不同用戶群體打造便捷高效、富有價值的美好生活',
@@ -261,8 +261,8 @@ export const hk = {
color: '#1A1A1A',
icon: 'briefcase',
products: [
- { name: '職來', enName: 'mydreamjob', desc: '精準高效的求職服務平台——全鏈條一站式求職服務,讓求職與成長一步到位', slogan: '職來,滿足你的所有職場願望,您求職路上最信賴的同行夥伴', role: '精準求職服務平台', audience: '求職者與招聘企業', ecosystem: '成長生態 · 雙邊市場入口', icon: 'briefcase' },
- { name: '看山', enName: 'Peaksight', desc: '精準高效的升學服務平台——中學生升學路上值得信賴的人生規劃助手', slogan: '看山,幫你看見屬於自己的高山,一步一步攀登人生高峰', role: '精準升學服務平台', audience: '中學生與家長', ecosystem: '成長生態 · 升學規劃節點', icon: 'mountain' },
+ { name: '輕鬆聘', enName: 'mydreamjob', desc: '精準高效的求職服務平台——全鏈條一站式求職服務,讓求職與成長一步到位', slogan: '輕鬆聘,滿足你的所有職場願望,您求職路上最信賴的同行夥伴', role: '精準求職服務平台', audience: '求職者與招聘企業', ecosystem: '成長生態 · 雙邊市場入口', icon: 'briefcase' },
+ { name: '智願通', enName: 'Peaksight', desc: '精準高效的升學服務平台——中學生升學路上值得信賴的人生規劃助手', slogan: '智願通,幫你看見屬於自己的高山,一步一步攀登人生高峰', role: '精準升學服務平台', audience: '中學生與家長', ecosystem: '成長生態 · 升學規劃節點', icon: 'mountain' },
],
},
{
@@ -478,7 +478,7 @@ export const hk = {
contact: '聯繫我們',
},
contact: {
- jobs: { label: '求職諮詢', hint: '職來 · 看山團隊直招' },
+ jobs: { label: '求職諮詢', hint: '輕鬆聘 · 智願通團隊直招' },
biz: { label: '商務合作', hint: '產品合作 · 市場聯動' },
email: 'baskbuddy@163.com',
address: '中國 · 上海市靜安區康寧路288弄2號410室',
diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts
index 9c11aac..3b89711 100644
--- a/src/i18n/zh.ts
+++ b/src/i18n/zh.ts
@@ -156,7 +156,7 @@ export const zh = {
about: {
title: '关于我们',
subtitle: '巴适伙伴,一生相伴',
- intro: `巴适伙伴(上海)科技有限公司是一家聚焦数字生活服务领域,依托多品牌、多垂直赛道的产品布局,面向不同用户群体提供优质产品与服务的高科技企业,通过旗下多家独立运营的子公司,分别深耕内容社交(青核、音酷、蜜恋)、职场服务(职来、看山)、数字支付(妥哒)、人工智能(阿布 AI)、生活服务(听愿)等多个领域,始终坚持以用户需求为核心,坚持品质第一与技术创新,为员工创造成长空间,为用户创造美好生活,为社会创造长期价值。`,
+ intro: `巴适伙伴(上海)科技有限公司是一家聚焦数字生活服务领域,依托多品牌、多垂直赛道的产品布局,面向不同用户群体提供优质产品与服务的高科技企业,通过旗下多家独立运营的子公司,分别深耕内容社交(青核、音酷、蜜恋)、职场服务(轻松聘、智愿通)、数字支付(妥哒)、人工智能(阿布 AI)、生活服务(听愿)等多个领域,始终坚持以用户需求为核心,坚持品质第一与技术创新,为员工创造成长空间,为用户创造美好生活,为社会创造长期价值。`,
visionMission: {
vision: '打造全球领先的数字生活服务生态,让不同需求的用户都能获得优质适配的产品体验',
mission: '以创新技术连接人与服务,依托多元垂直领域产品,为不同用户群体打造便捷高效、富有价值的美好生活',
@@ -302,8 +302,8 @@ export const zh = {
color: '#1A1A1A',
icon: 'briefcase',
products: [
- { name: '职来', enName: 'mydreamjob', desc: '精准高效的求职服务平台——全链条一站式求职服务,让求职与成长一步到位', slogan: '职来,满足你的所有职场愿望,您求职路上最信赖的同行伙伴', role: '精准求职服务平台', audience: '求职者与招聘企业', ecosystem: '成长生态 · 双边市场入口', icon: 'briefcase' },
- { name: '看山', enName: 'Peaksight', desc: '精准高效的升学服务平台——中学生升学路上值得信赖的人生规划助手', slogan: '看山,帮你看见属于自己的高山,一步一步攀登人生高峰', role: '精准升学服务平台', audience: '中学生与家长', ecosystem: '成长生态 · 升学规划节点', icon: 'mountain' },
+ { name: '轻松聘', enName: 'mydreamjob', desc: '精准高效的求职服务平台——全链条一站式求职服务,让求职与成长一步到位', slogan: '轻松聘,满足你的所有职场愿望,您求职路上最信赖的同行伙伴', role: '精准求职服务平台', audience: '求职者与招聘企业', ecosystem: '成长生态 · 双边市场入口', icon: 'briefcase' },
+ { name: '智愿通', enName: 'Peaksight', desc: '精准高效的升学服务平台——中学生升学路上值得信赖的人生规划助手', slogan: '智愿通,帮你看见属于自己的高山,一步一步攀登人生高峰', role: '精准升学服务平台', audience: '中学生与家长', ecosystem: '成长生态 · 升学规划节点', icon: 'mountain' },
],
},
{
@@ -519,7 +519,7 @@ export const zh = {
contact: '联系我们',
},
contact: {
- jobs: { label: '求职咨询', hint: '职来 · 看山团队直招' },
+ jobs: { label: '求职咨询', hint: '轻松聘 · 智愿通团队直招' },
biz: { label: '商务合作', hint: '产品合作 · 市场联动' },
email: 'baskbuddy@163.com',
address: '中国 · 上海市静安区康宁路288弄2号410室',
diff --git a/src/styles/global.css b/src/styles/global.css
index 9eb6834..90167b6 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -837,6 +837,88 @@ html:lang(en) .stat-band--pair .stat-num { font-size: clamp(26px, 5.2vw, 54px);
filter: drop-shadow(0 6px 14px rgba(26, 26, 26, 0.18));
}
+/* 小狗吉祥物:内嵌 SVG 尺寸与灵动微动效(眨眼 / 摆耳 / 腮红呼吸 / 思考歪头) */
+.mascot-dog svg {
+ display: block;
+ width: 90px;
+ height: 84px;
+ transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+.mascot-dog .dog-eye {
+ transform-box: fill-box;
+ transform-origin: center;
+ animation: dogBlink 4.6s ease-in-out infinite;
+}
+.mascot-dog .dog-ear {
+ transform-box: fill-box;
+ animation: dogEarSway 3.4s ease-in-out infinite;
+}
+.mascot-dog .dog-ear-r { transform-origin: 15% 85%; }
+.mascot-dog .dog-ear-l { transform-origin: 85% 85%; animation-delay: -1.7s; }
+.mascot-dog .dog-blush {
+ transform-box: fill-box;
+ transform-origin: center;
+ animation: dogBlush 3.8s ease-in-out infinite;
+}
+/* 心情联动:思考时歪头 */
+.mascot-float[data-mood="think"] .mascot-dog svg {
+ transform: rotate(-7deg);
+}
+/* 悬停:好奇地微微探头(think 歪头时让位) */
+.mascot-float:hover:not([data-mood="think"]) .mascot-dog svg {
+ transform: rotate(-3deg);
+}
+/* 视线跟随层:眼睛外层 g 位移(--eye-x/--eye-y 由 JS 写在按钮上) */
+.mascot-dog .dog-eye-track {
+ transform-box: fill-box;
+ transform: translate(var(--eye-x, 0), var(--eye-y, 0));
+ transition: transform 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
+}
+/* 被戳:眯眼笑 */
+.mascot-float[data-mood="squeeze"] .mascot-dog .dog-eye {
+ animation: dogSquint 0.7s ease-in-out infinite;
+}
+/* 欢呼:耳朵欢快小摆 */
+.mascot-float[data-mood="cheer"] .mascot-dog .dog-ear {
+ animation: dogEarPerk 0.55s ease-in-out infinite;
+}
+/* 挥手:右耳摇得更欢 */
+.mascot-float[data-mood="wave"] .mascot-dog .dog-ear-r {
+ animation: dogEarHi 1.6s ease-in-out infinite;
+}
+/* 右耳保持静止(覆盖默认摆耳 / cheer / wave 的耳朵动画) */
+.mascot-dog .dog-ear-r,
+.mascot-float[data-mood="cheer"] .mascot-dog .dog-ear-r,
+.mascot-float[data-mood="wave"] .mascot-dog .dog-ear-r {
+ animation: none;
+}
+
+@keyframes dogSquint {
+ 0%, 100% { transform: scaleY(0.45); }
+ 50% { transform: scaleY(0.6); }
+}
+@keyframes dogEarPerk {
+ 0%, 100% { transform: rotate(-3deg); }
+ 50% { transform: rotate(-10deg); }
+}
+@keyframes dogEarHi {
+ 0%, 100% { transform: rotate(-6deg); }
+ 50% { transform: rotate(-14deg); }
+}
+
+@keyframes dogBlink {
+ 0%, 91%, 100% { transform: scaleY(1); }
+ 94%, 96% { transform: scaleY(0.1); }
+}
+@keyframes dogEarSway {
+ 0%, 100% { transform: rotate(0deg); }
+ 50% { transform: rotate(-4deg); }
+}
+@keyframes dogBlush {
+ 0%, 100% { transform: scale(1); opacity: 1; }
+ 50% { transform: scale(1.12); opacity: 0.72; }
+}
+
.mascot-bubble {
width: min(300px, calc(100vw - 40px));
background: var(--brand-white);
@@ -1051,9 +1133,16 @@ html:lang(en) .stat-band--pair .stat-num { font-size: clamp(26px, 5.2vw, 54px);
.mascot-float[data-mood="cheer"] .mascot-sparks path,
.mascot-float[data-mood="squeeze"] .mascot-arm,
.mascot-float[data-mood="squeeze"] .mascot-dots circle,
- .mascot-float[data-mood="squeeze"] .mascot-sparks path {
+ .mascot-float[data-mood="squeeze"] .mascot-sparks path,
+ .mascot-dog .dog-eye,
+ .mascot-dog .dog-ear,
+ .mascot-dog .dog-blush,
+ .mascot-dog .dog-eye-track {
animation: none !important;
}
+ .mascot-dog .dog-eye-track {
+ transform: none !important;
+ }
}
/* HERO 左下文字(h1 / p / a)在浅底 hero-bg.jpg 上的可读阴影,保证不蒙层时也清晰 */