Files
DDCZ/index.html
KQL b0d2e629d9 feat: 完善项目功能和部署脚本
- 修复页面跳转白屏闪烁问题
- 集成过渡岗位页面(岗位装配中心)
- 添加iframe全屏嵌入(教务系统、就业规划)
- 优化企业资源卡片hover分裂效果
- 添加Windows和macOS快捷部署脚本
- 更新.gitignore忽略测试文件和缓存

🤖 Generated with Claude Code
2025-12-04 16:03:31 +08:00

1163 lines
49 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="referrer" content="no-referrer">
<title>大专生就业服务平台</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Font Awesome Icons -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<!-- 自定义样式 - 只加载必要的 -->
<link rel="stylesheet" href="./css/layout.css">
<link rel="stylesheet" href="./css/components.css">
<link rel="stylesheet" href="./css/effects.css">
<style>
/* 引入字体 */
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;500;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Noto Sans SC', 'Microsoft YaHei', sans-serif;
color: #fff;
margin: 0;
padding: 0;
}
/* 首页包裹容器 */
#home-wrapper {
background-color: #020617;
background-image:
radial-gradient(ellipse at 50% 50%, rgba(56, 189, 248, 0.2) 0%, rgba(30, 64, 175, 0.15) 40%, transparent 80%),
radial-gradient(circle at center, #0f172a 0%, #020617 100%);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
}
.bg-glow {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 120vw;
height: 120vw;
background: radial-gradient(circle, rgba(79, 70, 229, 0.1) 0%, transparent 60%);
filter: blur(120px);
z-index: -1;
pointer-events: none;
}
.container {
width: 90%;
max-width: 1300px;
height: 85vh;
display: flex;
flex-direction: column;
gap: 24px;
z-index: 1;
}
.glass-header {
flex: 0 0 140px;
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 20px;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.header-inner {
text-align: center;
}
.header-inner h1 {
font-size: 32px;
font-weight: 700;
letter-spacing: 2px;
margin-bottom: 4px;
background: linear-gradient(90deg, #e0f2fe, #38bdf8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
filter: drop-shadow(0 0 10px rgba(56, 189, 248, 0.3));
}
.header-inner p {
font-size: 12px;
letter-spacing: 4px;
color: rgba(255, 255, 255, 0.5);
font-weight: 300;
}
.card-wrapper {
flex: 1;
display: flex;
gap: 20px;
}
.card {
position: relative;
flex: 1;
border-radius: 20px;
overflow: hidden;
cursor: pointer;
text-decoration: none;
box-shadow: 0 15px 35px rgba(0,0,0,0.5);
border: 1px solid rgba(255, 255, 255, 0.05);
background: #020617;
transition: flex 0.6s cubic-bezier(0.25, 1, 0.5, 1);
}
.card-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
filter: grayscale(100%) blur(4px);
transform: scale(1.1);
transition: all 0.6s ease;
}
.card-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(2, 6, 23, 0.6);
transition: background 0.6s ease;
z-index: 1;
}
.card-content {
position: relative;
z-index: 2;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.card-content h2 {
color: #fff;
font-size: 32px;
font-weight: 700;
letter-spacing: 2px;
text-shadow: 0 4px 15px rgba(0,0,0,0.8);
transform: translateY(0);
transition: transform 0.6s cubic-bezier(0.25, 1, 0.5, 1);
}
.sub-text {
margin-top: 15px;
font-size: 16px;
color: rgba(255,255,255,0.9);
background: rgba(255, 255, 255, 0.05);
padding: 6px 16px;
border-radius: 50px;
backdrop-filter: blur(4px);
border: 1px solid rgba(255,255,255,0.1);
opacity: 0;
transform: translateY(20px);
transition: all 0.6s cubic-bezier(0.25, 1, 0.5, 1);
}
.card:hover {
flex: 2.5;
}
.card:hover .card-bg {
filter: grayscale(0%) blur(0px);
transform: scale(1.05);
}
.card:hover .card-overlay {
background: rgba(2, 6, 23, 0.2);
}
/* 普通卡片 hover 效果 */
a.card:hover h2 {
transform: translateY(-10px);
}
a.card:hover .sub-text {
opacity: 1;
transform: translateY(0);
}
.hidden {
display: none !important;
}
/* 特殊卡片分裂效果 */
.default-view {
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: all 0.6s cubic-bezier(0.25, 1, 0.5, 1);
opacity: 1;
transform: translateY(0);
}
.special-card:hover .default-view {
opacity: 0;
transform: translateY(-20px);
pointer-events: none;
}
.split-view {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
opacity: 0;
transform: translateY(20px);
transition: all 0.6s cubic-bezier(0.25, 1, 0.5, 1) 0.1s;
}
.special-card:hover .split-view {
opacity: 1;
transform: translateY(0);
}
.split-item {
flex: 1;
text-decoration: none;
display: flex;
justify-content: center;
align-items: center;
color: white;
position: relative;
transition: background 0.3s ease;
}
.split-item:hover {
background: rgba(255, 255, 255, 0.1);
}
.panel-inner {
text-align: center;
transform: scale(0.9);
transition: transform 0.3s ease;
}
.split-item:hover .panel-inner {
transform: scale(1);
}
.split-item h3 {
font-size: 24px;
font-weight: 700;
margin-bottom: 8px;
color: #fff;
}
.split-item p {
font-size: 13px;
color: rgba(255, 255, 255, 0.7);
margin-bottom: 12px;
}
.mini-arrow {
font-size: 20px;
opacity: 0;
transform: translateX(-10px);
transition: all 0.3s ease;
color: #38bdf8;
}
.split-item:hover .mini-arrow {
opacity: 1;
transform: translateX(0);
}
.vertical-divider {
width: 1px;
height: 60%;
background: linear-gradient(to bottom, transparent, rgba(255,255,255,0.3), transparent);
align-self: center;
}
/* iframe容器样式 */
.iframe-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background: #020617;
z-index: 100;
}
.fullscreen-iframe {
width: 100%;
height: 100%;
border: none;
display: block;
}
.iframe-back-btn {
position: fixed;
top: 20px;
left: 20px;
z-index: 101;
display: flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
background: rgba(11, 16, 38, 0.95);
backdrop-filter: blur(12px);
border: 1px solid rgba(56, 189, 248, 0.3);
border-radius: 50px;
color: #38bdf8;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}
.iframe-back-btn:hover {
background: rgba(56, 189, 248, 0.2);
border-color: #38bdf8;
box-shadow: 0 0 30px rgba(56, 189, 248, 0.4);
transform: translateX(-5px);
}
.iframe-back-btn svg {
width: 20px;
height: 20px;
}
@media (max-width: 768px) {
.iframe-back-btn {
top: 10px;
left: 10px;
padding: 8px 16px;
font-size: 12px;
}
.iframe-back-btn svg {
width: 16px;
height: 16px;
}
}
/* 过渡岗位页面样式 */
#transition-jobs-page {
background-color: #020408;
position: relative;
}
/* 背景光影效果 */
#transition-jobs-page::before {
content: '';
position: fixed;
top: -50%; left: -50%; width: 150%; height: 150%;
z-index: -2;
background: radial-gradient(circle at center, rgba(0, 240, 255, 0.15) 0%, transparent 60%);
filter: blur(100px);
pointer-events: none;
opacity: 0.8;
}
#transition-jobs-page::after {
content: '';
position: fixed;
bottom: -30%; right: -30%; width: 120%; height: 120%;
z-index: -2;
background: radial-gradient(circle at center, rgba(25, 50, 150, 0.2) 0%, transparent 50%);
filter: blur(120px);
pointer-events: none;
opacity: 0.6;
}
.commander-layout {
display: flex; flex-direction: column; height: 100vh;
max-width: 1440px; margin: 0 auto; padding: 20px 40px; box-sizing: border-box;
position: relative; z-index: 1;
}
.hud-section {
background: rgba(15, 18, 24, 0.4);
backdrop-filter: blur(25px);
border-radius: 16px;
padding: 20px 30px;
border: 1px solid rgba(255,255,255,0.08);
box-shadow: 0 20px 40px -10px rgba(0,0,0,0.3);
margin-bottom: 25px;
flex-shrink: 0;
}
.hud-header {
display: flex; justify-content: space-between; align-items: center;
margin-bottom: 20px; border-bottom: 1px solid rgba(255,255,255,0.05); padding-bottom: 15px;
}
.hud-title-group { display: flex; align-items: center; gap: 12px; }
.hud-icon { color: #00f0ff; font-size: 1.2rem; text-shadow: 0 0 15px rgba(0, 240, 255, 0.6); }
.hud-title { font-size: 1.1rem; font-weight: bold; letter-spacing: 1px; color: #fff; }
.hud-subtitle { font-size: 0.75rem; color: #666; margin-left: 8px; font-weight: normal; }
.confirm-btn {
background: linear-gradient(90deg, #2563eb, #00f0ff);
color: #000; font-weight: 800; font-size: 0.9rem;
padding: 8px 24px; border-radius: 4px;
border: none; cursor: pointer;
box-shadow: 0 0 20px rgba(0, 240, 255, 0.2);
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
display: flex; align-items: center; gap: 8px;
opacity: 0.4; pointer-events: none; filter: grayscale(80%);
}
.confirm-btn.active { opacity: 1; pointer-events: auto; filter: grayscale(0%); }
.confirm-btn:hover {
transform: scale(1.05) translateY(-2px);
box-shadow: 0 5px 30px rgba(0, 240, 255, 0.5);
color: white;
}
.slots-container {
display: grid; grid-template-columns: repeat(5, 1fr); gap: 15px;
}
.slot-module {
height: 140px;
background: rgba(0,0,0,0.2);
border: 1px dashed rgba(255,255,255,0.1);
border-radius: 8px;
display: flex; flex-direction: column; justify-content: center; align-items: center;
transition: all 0.3s;
position: relative; overflow: hidden;
backdrop-filter: blur(5px);
}
.slot-module.empty:hover { border-color: rgba(255,255,255,0.2); background: rgba(255,255,255,0.03); }
.slot-module.filled {
background: linear-gradient(160deg, rgba(30, 35, 46, 0.8), rgba(19, 22, 28, 0.9));
border: 1px solid rgba(0, 240, 255, 0.3);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
cursor: pointer;
backdrop-filter: blur(10px);
}
.slot-module.filled:hover { transform: translateY(-3px); box-shadow: 0 8px 25px rgba(0, 240, 255, 0.15); border-color: #00f0ff; }
.slot-remove-mask {
position: absolute; inset: 0; background: rgba(0,0,0,0.85);
display: flex; flex-direction: column; align-items: center; justify-content: center;
opacity: 0; transition: opacity 0.2s; color: #ff4d4d; backdrop-filter: blur(5px);
}
.slot-module.filled:hover .slot-remove-mask { opacity: 1; }
.slot-content-title { font-size: 0.95rem; font-weight: bold; color: white; margin-bottom: 4px; text-align: center; width: 90%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slot-content-salary { color: #00f0ff; font-weight: bold; font-size: 0.9rem; font-family: 'Arial', sans-serif; text-shadow: 0 0 8px rgba(0,240,255,0.3); }
.slot-content-company { font-size: 0.75rem; color: #94a3b8; margin-top: 4px; }
.slot-index { position: absolute; top: 8px; left: 10px; font-size: 1.5rem; font-weight: 900; color: rgba(255,255,255,0.03); pointer-events: none; }
.list-section { flex: 1; overflow-y: auto; padding-right: 5px; }
.list-header {
display: flex; align-items: center; margin-bottom: 20px;
border-left: 4px solid #00f0ff; padding-left: 12px;
text-shadow: 0 0 15px rgba(0,240,255,0.3);
}
.list-title { font-size: 1.1rem; font-weight: bold; color: #fff; letter-spacing: 1px; }
.job-grid {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; padding-bottom: 40px;
}
.job-card {
background: rgba(20, 24, 35, 0.6);
backdrop-filter: blur(15px);
border: 1px solid rgba(255,255,255,0.05);
border-radius: 12px;
padding: 24px;
position: relative;
cursor: pointer;
transition: all 0.25s cubic-bezier(0.25, 0.8, 0.25, 1);
display: flex; flex-direction: column; justify-content: space-between;
min-height: 160px;
}
.job-card:hover {
border-color: rgba(0, 240, 255, 0.5);
background: rgba(26, 30, 38, 0.8);
transform: translateY(-5px) scale(1.01);
box-shadow: 0 15px 35px rgba(0,0,0,0.4), 0 0 15px rgba(0,240,255,0.1);
}
.job-card.disabled {
opacity: 0.3;
filter: grayscale(100%) contrast(80%);
background: rgba(10, 12, 16, 0.5);
border-color: transparent;
pointer-events: none;
cursor: default;
transform: none !important;
box-shadow: none !important;
backdrop-filter: none;
}
.card-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
.card-icon {
width: 44px; height: 44px; border-radius: 8px;
background: rgba(255,255,255,0.03);
display: flex; align-items: center; justify-content: center;
font-size: 1.2rem; color: #94a3b8; transition: all 0.3s;
border: 1px solid transparent;
}
.job-card:hover .card-icon {
color: #00f0ff;
background: rgba(0, 240, 255, 0.05);
border-color: rgba(0, 240, 255, 0.2);
box-shadow: 0 0 10px rgba(0,240,255,0.2);
}
.card-salary { color: #00f0ff; font-weight: bold; font-size: 1rem; text-shadow: 0 0 5px rgba(0,240,255,0.3); }
.card-title { font-size: 1.1rem; font-weight: bold; color: #fff; margin-bottom: 6px; }
.card-company { font-size: 0.85rem; color: #94a3b8; display: flex; align-items: center; gap: 6px; }
.card-tags { margin-top: 15px; display: flex; gap: 6px; flex-wrap: wrap; }
.tag {
font-size: 0.75rem; padding: 3px 8px; border-radius: 4px;
background: rgba(255,255,255,0.03); color: #888;
border: 1px solid rgba(255,255,255,0.02);
}
.check-mark {
position: absolute; top: 15px; right: 15px;
color: #00f0ff; font-size: 1.2rem;
opacity: 0; transform: scale(0); transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
text-shadow: 0 0 10px #00f0ff;
}
.job-card.disabled .check-mark { opacity: 1; transform: scale(1); }
</style>
</head>
<body>
<!-- 首页包裹器 -->
<div id="home-wrapper">
<div class="bg-glow"></div>
<!-- 首页容器 -->
<div id="home-container" class="container">
<header class="glass-header">
<div class="header-inner">
<h1>多多畅职大专生就业服务平台</h1>
<p>CAREER SERVICE PLATFORM</p>
</div>
</header>
<div class="card-wrapper">
<div class="card special-card">
<div class="card-bg" style="background-image: url('https://images.unsplash.com/photo-1497366216548-37526070297c?q=80&w=2301&auto=format&fit=crop');"></div>
<div class="card-overlay"></div>
<div class="card-content">
<div class="default-view">
<h2>企业资源</h2>
<span class="sub-text">优质岗位 · 名企直推</span>
</div>
<div class="split-view">
<a href="javascript:void(0)" id="transition-split-card" class="split-item">
<div class="panel-inner">
<h3>过渡岗位</h3>
<p>短期兼职 & 实习实训</p>
<div class="mini-arrow"></div>
</div>
</a>
<div class="vertical-divider"></div>
<a href="javascript:void(0)" id="referral-split-card" class="split-item">
<div class="panel-inner">
<h3>内推岗位</h3>
<p>校友推荐 & 名企直通</p>
<div class="mini-arrow"></div>
</div>
</a>
</div>
</div>
</div>
<a href="javascript:void(0)" id="education-card" class="card">
<div class="card-bg" style="background-image: url('https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?q=80&w=2340&auto=format&fit=crop');"></div>
<div class="card-overlay"></div>
<div class="card-content">
<h2>教务系统</h2>
<span class="sub-text">技能提升 · 在线课程</span>
</div>
</a>
<a href="javascript:void(0)" id="career-card" class="card">
<div class="card-bg" style="background-image: url('https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?q=80&w=2070&auto=format&fit=crop');"></div>
<div class="card-overlay"></div>
<div class="card-content">
<h2>就业规划</h2>
<span class="sub-text">生涯指导 · 前景分析</span>
</div>
</a>
</div>
</div>
</div>
<!-- 首页包裹器结束 -->
<!-- 教务系统iframe界面 -->
<div id="education-iframe" class="iframe-container hidden">
<button class="iframe-back-btn" onclick="backToHomeFromIframe()">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
<span>返回首页</span>
</button>
<iframe
id="education-frame"
src="https://duoduochangzhi.cn/"
frameborder="0"
allowfullscreen
class="fullscreen-iframe">
</iframe>
</div>
<!-- 就业规划iframe界面 -->
<div id="career-iframe" class="iframe-container hidden">
<button class="iframe-back-btn" onclick="backToHomeFromIframe()">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
<span>返回首页</span>
</button>
<iframe
id="career-frame"
src="http://192.168.2.9:5173/"
frameborder="0"
allowfullscreen
class="fullscreen-iframe">
</iframe>
</div>
<!-- 过渡岗位页面 -->
<div id="transition-jobs-page" class="fixed inset-0 hidden" style="z-index: 100;">
<button class="iframe-back-btn" onclick="backToHomeFromTransition()">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
<span>返回首页</span>
</button>
<!-- 岗位装配中心内容 -->
<div class="commander-layout" style="font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;">
<header class="hud-section">
<div class="hud-header">
<div class="hud-title-group">
<i class="fa-solid fa-cube hud-icon"></i>
<div>
<div class="hud-title">我的投递清单</div>
<span class="hud-subtitle">MY SELECTION</span>
</div>
</div>
<div class="text-gray-500 font-mono text-sm">
已选: <span id="trans-count-display" class="text-cyan-400 font-bold text-lg">0</span> / 5
</div>
<button id="trans-submit-btn" class="confirm-btn">
确认投递 <i class="fa-solid fa-paper-plane"></i>
</button>
</div>
<div class="slots-container" id="trans-slot-container">
</div>
</header>
<section class="list-section custom-scrollbar">
<div class="list-header">
<div class="list-title">岗位资源库</div>
</div>
<div class="job-grid" id="trans-job-grid">
</div>
</section>
</div>
</div>
<!-- ============================================
3D内推平台部分
============================================ -->
<div id="app-container" class="fixed inset-0 hidden" style="z-index: 10; background: radial-gradient(circle at 50% 30%, #1e293b 0%, #0b1026 100%);">
<!-- 转场特效层 -->
<div id="speed-lines"></div>
<div id="cloud-fog"></div>
<!-- 3D场景UI层 -->
<div id="ui-layer">
<h1 class="v1-title">DUODUO Referral</h1>
<p class="v1-subtitle">CONNECTING TALENTS WITH THE WORLD</p>
</div>
<div class="instruction-hint">点击地球</div>
<!-- 3D画布容器 -->
<div id="canvas-container"></div>
<!-- 地图界面 -->
<div id="map-interface">
<header class="glass-header fixed top-0 w-full h-16 flex items-center justify-between px-4 md:px-8 z-50">
<div id="map-logo-area" class="flex items-center gap-2 cursor-pointer flex-shrink-0">
<img src="https://ddcz-1315997005.cos.ap-nanjing.myqcloud.com/static/img/duoduo_logo/LOGO_1097x300.png"
alt="多多畅职" class="h-6 md:h-8 w-auto object-contain">
<div class="text-white font-bold text-xs md:text-sm tracking-wide hidden sm:block">多多畅职企业内推平台</div>
<span class="text-gray-400 text-xs ml-2 hidden lg:inline">点击返回首页</span>
</div>
<div class="relative w-1/3 hidden md:block">
<input type="text" id="search-input" placeholder="搜索省份、城市、企业..." class="search-input w-full py-2 px-5 rounded-full text-center text-sm placeholder-gray-400">
</div>
<div class="relative w-full px-4 md:hidden mb-2">
<input type="text" id="search-input-mobile" placeholder="搜索省份、城市、企业..." class="search-input w-full py-2 px-4 rounded-full text-sm placeholder-gray-400">
</div>
<div class="flex items-center gap-2 text-white text-xs md:text-sm flex-shrink-0">
<span class="text-gray-400 hidden sm:inline">当前区域:</span>
<span id="top-region-name" class="text-cyan-300 font-bold">全国</span>
</div>
</header>
<main class="pt-16 w-full h-full relative">
<div id="breadcrumb-container" class="absolute top-20 left-4 md:left-8 text-gray-400 text-xs md:text-sm z-40 hidden">
<span class="hover:text-white cursor-pointer transition" onclick="resetMapToChina()">全国</span>
<span class="mx-2 text-gray-600">/</span>
<span class="text-cyan-400 font-bold">江苏省</span>
</div>
<div id="map-chart" style="width: 100%; height: calc(100vh - 64px); min-height: 500px;"></div>
</main>
</div>
<!-- 企业列表界面 -->
<div id="list-interface">
<header class="glass-header fixed top-0 w-full h-16 flex items-center justify-between px-4 md:px-8 z-50">
<button onclick="backToMap()" class="flex items-center gap-1 md:gap-2 text-gray-400 hover:text-white transition flex-shrink-0">
<svg class="w-4 h-4 md:w-5 md:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path></svg>
<span class="text-xs md:text-sm">返回地图</span>
</button>
<h2 id="list-city-title" class="text-sm md:text-lg font-bold text-white tracking-tight">苏州市 · 企业名录</h2>
<div class="w-12 md:w-20 flex-shrink-0"></div>
</header>
<div class="flex h-full pt-16">
<aside class="w-64 h-full border-r border-white/10 p-6 hidden md:block">
<div class="mb-8">
<h3 class="text-cyan-400 text-xs font-bold uppercase tracking-widest mb-4">筛选 Filter</h3>
<div class="space-y-4">
<div>
<label class="text-gray-500 text-xs mb-2 block">所属行业</label>
<div class="flex flex-wrap gap-2">
<span class="tag-badge cursor-pointer hover:bg-blue-500 hover:text-white transition">互联网</span>
<span class="tag-badge cursor-pointer hover:bg-blue-500 hover:text-white transition">金融</span>
<span class="tag-badge cursor-pointer hover:bg-blue-500 hover:text-white transition">硬科技</span>
</div>
</div>
<div>
<label class="text-gray-500 text-xs mb-2 block">企业规模</label>
<div class="space-y-2 text-gray-400 text-sm">
<div class="flex items-center gap-2"><input type="checkbox" class="accent-cyan-400"> <span>上市企业</span></div>
<div class="flex items-center gap-2"><input type="checkbox" class="accent-cyan-400"> <span>独角兽</span></div>
<div class="flex items-center gap-2"><input type="checkbox" class="accent-cyan-400"> <span>国企/央企</span></div>
</div>
</div>
</div>
</div>
<div class="p-4 bg-white/5 rounded-lg border border-white/5">
<div class="text-gray-400 text-xs mb-1">当前城市收录</div>
<div class="text-2xl font-bold text-white"><span id="company-count">124</span> <span class="text-sm text-gray-500 font-normal">家企业</span></div>
<div class="text-2xl font-bold text-white mt-2"><span id="job-count">892</span> <span class="text-sm text-gray-500 font-normal">个岗位</span></div>
</div>
</aside>
<main class="flex-1 h-full overflow-y-auto p-8">
<div id="cards-container" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 pb-20">
</div>
</main>
</div>
</div>
<!-- 企业详情页面 -->
<div id="detail-interface" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 7; display: none; opacity: 0; background: #050b14;">
<header class="glass-header fixed top-0 w-full h-16 flex items-center justify-between px-4 md:px-8 z-50">
<button onclick="backToList()" class="flex items-center gap-1 md:gap-2 text-cyan-400 hover:text-white transition group">
<span class="group-hover:-translate-x-1 transition"></span>
<span class="text-xs md:text-sm">返回企业列表</span>
</button>
<div class="w-12 md:w-20"></div>
</header>
<div class="h-full pt-16 overflow-y-auto md:overflow-hidden md:flex">
<aside class="w-full md:w-1/3 md:h-full md:overflow-y-auto border-b md:border-b-0 md:border-r border-white/10 p-4 md:p-8 bg-black/20" style="scrollbar-width: thin; scrollbar-color: #38bdf8 rgba(255,255,255,0.05);">
<div class="flex flex-col items-center mb-6 md:mb-8">
<h1 id="d-name" class="text-xl md:text-3xl font-bold text-white text-center mb-2"></h1>
<div id="d-tags" class="flex flex-wrap gap-2 justify-center"></div>
</div>
<div class="space-y-4 md:space-y-6">
<div>
<h3 class="text-cyan-500 text-xs font-bold uppercase mb-2">企业简介 About</h3>
<p id="d-intro" class="text-gray-300 text-xs md:text-sm leading-relaxed text-justify"></p>
</div>
<div class="bg-gradient-to-br from-cyan-900/30 to-transparent border border-cyan-500/20 p-3 md:p-4 rounded-lg">
<h3 class="text-cyan-400 text-xs md:text-sm font-bold mb-2 flex items-center">🔥 推荐理由 Highlight</h3>
<p id="d-reason" class="text-gray-400 text-xs leading-relaxed"></p>
</div>
<div>
<h3 class="text-cyan-500 text-xs font-bold uppercase mb-2">地区 Location</h3>
<p id="d-region" class="text-gray-400 text-xs md:text-sm whitespace-pre-line"></p>
</div>
<div>
<h3 class="text-cyan-500 text-xs font-bold uppercase mb-2">企业风采 Gallery</h3>
<div id="d-gallery" class="grid grid-cols-3 gap-2"></div>
</div>
</div>
</aside>
<main class="w-full md:flex-1 md:h-full md:overflow-y-auto p-4 md:p-8 bg-gradient-to-br from-gray-900 to-black">
<div class="mb-4 md:mb-6">
<h2 class="text-lg md:text-2xl font-bold text-white mb-1">业务板块 & 内推岗位</h2>
<span class="text-gray-500 text-xs md:text-sm">Business Segments & Opportunities</span>
</div>
<div id="d-segments" class="grid grid-cols-1 gap-4 md:gap-6"></div>
<div class="h-20"></div>
</main>
</div>
</div>
<!-- 图片Lightbox模态框 -->
<div id="image-lightbox" class="fixed inset-0 z-[100] bg-black/95 backdrop-blur-sm hidden items-center justify-center">
<button id="lightbox-close" class="absolute top-4 right-4 md:top-8 md:right-8 w-10 h-10 md:w-12 md:h-12 flex items-center justify-center text-white hover:text-cyan-400 transition text-2xl md:text-3xl z-10">
<i class="fa-solid fa-xmark"></i>
</button>
<button id="lightbox-prev" class="absolute left-2 md:left-8 top-1/2 -translate-y-1/2 w-10 h-10 md:w-14 md:h-14 flex items-center justify-center text-white hover:text-cyan-400 transition text-2xl md:text-4xl z-10">
<i class="fa-solid fa-chevron-left"></i>
</button>
<button id="lightbox-next" class="absolute right-2 md:right-8 top-1/2 -translate-y-1/2 w-10 h-10 md:w-14 md:h-14 flex items-center justify-center text-white hover:text-cyan-400 transition text-2xl md:text-4xl z-10">
<i class="fa-solid fa-chevron-right"></i>
</button>
<div class="relative w-full h-full flex items-center justify-center p-4 md:p-16">
<img id="lightbox-image" src="" alt="" class="max-w-full max-h-full object-contain">
</div>
<div id="lightbox-counter" class="absolute bottom-4 md:bottom-8 left-1/2 -translate-x-1/2 text-white text-sm md:text-base bg-black/50 px-4 py-2 rounded-full">
<span id="lightbox-current">1</span> / <span id="lightbox-total">1</span>
</div>
</div>
</div>
<!-- 外部库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
<!-- 页面切换脚本 -->
<script>
window.appInstance = null;
document.getElementById('referral-split-card').addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
// 隐藏首页显示3D平台容器
document.getElementById('home-wrapper').classList.add('hidden');
document.getElementById('app-container').classList.remove('hidden');
// 等待 appInstance 初始化完成然后启动3D平台
const tryStartApp = () => {
if (window.appInstance && typeof window.appInstance.switchToApp === 'function') {
window.appInstance.switchToApp();
} else {
// 如果还未初始化50ms后重试
setTimeout(tryStartApp, 50);
}
};
tryStartApp();
});
// 教务系统点击
document.getElementById('education-card').addEventListener('click', function(e) {
e.preventDefault();
document.getElementById('home-wrapper').classList.add('hidden');
document.getElementById('education-iframe').classList.remove('hidden');
});
// 就业规划点击
document.getElementById('career-card').addEventListener('click', function(e) {
e.preventDefault();
document.getElementById('home-wrapper').classList.add('hidden');
document.getElementById('career-iframe').classList.remove('hidden');
});
// 从iframe返回首页
window.backToHomeFromIframe = function() {
document.getElementById('education-iframe').classList.add('hidden');
document.getElementById('career-iframe').classList.add('hidden');
document.getElementById('home-wrapper').classList.remove('hidden');
};
// 过渡岗位点击
document.getElementById('transition-split-card').addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
document.getElementById('home-wrapper').classList.add('hidden');
document.getElementById('transition-jobs-page').classList.remove('hidden');
});
// 从过渡岗位返回首页
window.backToHomeFromTransition = function() {
document.getElementById('transition-jobs-page').classList.add('hidden');
document.getElementById('home-wrapper').classList.remove('hidden');
};
window.backToHome = function() {
const appContainer = document.getElementById('app-container');
const homeWrapper = document.getElementById('home-wrapper');
// 隐藏3D平台显示首页
appContainer.classList.add('hidden');
homeWrapper.classList.remove('hidden');
// 重置3D平台的2D地图初始化标志以便下次进入时重新初始化
if (window.appInstance) {
window.appInstance.is2DInitialized = false;
}
};
</script>
<!-- 过渡岗位页面脚本 -->
<script>
// 过渡岗位页面的JavaScript逻辑
(function() {
// --- 模拟数据 ---
const allJobs = [
{ id: 1, title: "Java 高级后端开发", company: "恒力集团", salary: "25-45k", icon: "fa-server", tags: ["苏州", "Spring Cloud"] },
{ id: 2, title: "AI 大模型算法专家", company: "未来智能", salary: "50-80k", icon: "fa-brain", tags: ["北京", "NLP", "Pytorch"] },
{ id: 3, title: "资深产品经理 (B端)", company: "字节跳动", salary: "30-55k", icon: "fa-cube", tags: ["上海", "SaaS"] },
{ id: 4, title: "嵌入式系统架构师", company: "科沃斯", salary: "35-60k", icon: "fa-microchip", tags: ["苏州", "ROS"] },
{ id: 5, title: "跨境电商运营总监", company: "SHEIN", salary: "40-70k", icon: "fa-globe", tags: ["广州", "欧美市场"] },
{ id: 6, title: "高级前端工程师", company: "微软", salary: "30-50k", icon: "fa-code", tags: ["苏州", "React", "TypeScript"] },
{ id: 7, title: "供应链数据分析师", company: "恒力集团", salary: "18-30k", icon: "fa-chart-pie", tags: ["大连", "SQL"] },
{ id: 8, title: "自动驾驶感知算法", company: "Momenta", salary: "35-65k", icon: "fa-car", tags: ["苏州", "C++"] },
{ id: 9, title: "HRBP (研发向)", company: "阿里巴巴", salary: "25-40k", icon: "fa-users", tags: ["杭州", "OD"] },
{ id: 10, title: "品牌视觉设计专家", company: "腾讯", salary: "25-45k", icon: "fa-pen-nib", tags: ["深圳", "C4D"] },
{ id: 11, title: "云原生架构师", company: "华为云", salary: "50-90k", icon: "fa-cloud", tags: ["南京", "K8s"] },
{ id: 12, title: "游戏客户端开发", company: "米哈游", salary: "30-60k", icon: "fa-gamepad", tags: ["上海", "Unity"] }
];
// --- 状态 ---
let selectedJobs = [];
const MAX_SELECTION = 5;
// --- DOM ---
const slotContainer = document.getElementById('trans-slot-container');
const jobGrid = document.getElementById('trans-job-grid');
const countDisplay = document.getElementById('trans-count-display');
const submitBtn = document.getElementById('trans-submit-btn');
// 1. 初始化空槽位
function initSlots() {
slotContainer.innerHTML = '';
for (let i = 0; i < MAX_SELECTION; i++) {
const slot = document.createElement('div');
slot.className = 'slot-module empty';
slot.id = `slot-${i}`;
slot.onclick = () => removeJobByIndex(i);
slot.innerHTML = `
<div class="slot-index">0${i+1}</div>
<i class="fa-solid fa-plus text-2xl mb-2 opacity-20 text-gray-500"></i>
<div class="text-xs text-gray-500 font-bold tracking-widest">待选择</div>
`;
slotContainer.appendChild(slot);
}
}
// 2. 渲染岗位网格
function renderJobGrid() {
jobGrid.innerHTML = '';
allJobs.forEach(job => {
const isSelected = selectedJobs.includes(job.id);
const card = document.createElement('div');
card.className = `job-card ${isSelected ? 'disabled' : ''}`;
card.id = `job-card-${job.id}`;
card.onclick = () => selectJob(job.id);
const tagsHtml = job.tags.map(t => `<span class="tag">${t}</span>`).join('');
card.innerHTML = `
<div class="card-top">
<div class="card-icon"><i class="fa-solid ${job.icon}"></i></div>
<div class="card-salary">${job.salary}</div>
</div>
<div>
<div class="card-title">${job.title}</div>
<div class="card-company">
<i class="fa-regular fa-building"></i> ${job.company}
</div>
<div class="card-tags">${tagsHtml}</div>
</div>
<div class="check-mark"><i class="fa-solid fa-circle-check"></i></div>
`;
jobGrid.appendChild(card);
});
}
// --- 交互逻辑 ---
function selectJob(id) {
if (selectedJobs.includes(id)) return;
if (selectedJobs.length >= MAX_SELECTION) {
// 弹性震动反馈
gsap.fromTo(slotContainer, { x: -8 }, { x: 0, duration: 0.4, ease: "elastic.out(1, 0.3)" });
return;
}
selectedJobs.push(id);
updateUI(true, id);
}
function removeJobByIndex(index) {
if (index >= selectedJobs.length) return;
const removedId = selectedJobs[index];
selectedJobs.splice(index, 1);
updateUI(false, removedId);
}
function updateUI(isAdding, targetId) {
// 1. 更新槽位
const slots = slotContainer.children;
for (let i = 0; i < MAX_SELECTION; i++) {
const slot = slots[i];
const jobId = selectedJobs[i];
if (jobId) {
const job = allJobs.find(j => j.id === jobId);
if (slot.classList.contains('empty') || slot.dataset.lastId != jobId) {
slot.className = 'slot-module filled';
slot.dataset.lastId = jobId;
slot.innerHTML = `
<div class="slot-index">0${i+1}</div>
<div class="slot-content-title">${job.title}</div>
<div class="slot-content-salary">${job.salary}</div>
<div class="slot-content-company">${job.company}</div>
<div class="slot-remove-mask">
<i class="fa-solid fa-trash-can text-2xl mb-2"></i>
<span class="text-xs font-bold tracking-widest">移除岗位</span>
</div>
`;
if(isAdding && i === selectedJobs.length - 1) {
gsap.fromTo(slot,
{ y: -30, opacity: 0, scale: 0.8 },
{ y: 0, opacity: 1, scale: 1, duration: 0.5, ease: "back.out(1.5)" }
);
}
}
} else {
if (!slot.classList.contains('empty')) {
slot.className = 'slot-module empty';
delete slot.dataset.lastId;
slot.innerHTML = `
<div class="slot-index">0${i+1}</div>
<i class="fa-solid fa-plus text-2xl mb-2 opacity-20 text-gray-500"></i>
<div class="text-xs text-gray-500 font-bold tracking-widest">待选择</div>
`;
}
}
}
// 2. 更新列表状态 (带动画修复)
if (targetId) {
const card = document.getElementById(`job-card-${targetId}`);
if (card) {
if (isAdding) {
card.classList.add('disabled');
gsap.to(card, { scale: 0.92, opacity: 0.3, duration: 0.3, ease: "power2.out" });
} else {
card.classList.remove('disabled');
// 关键修复:清除 GSAP 内联样式,恢复 CSS Hover
gsap.to(card, {
scale: 1, opacity: 1, duration: 0.4, ease: "back.out(1.2)",
clearProps: "all"
});
}
}
}
// 3. 更新按钮
countDisplay.innerText = selectedJobs.length;
if (selectedJobs.length > 0) {
submitBtn.classList.add('active');
submitBtn.innerHTML = `确认投递 (${selectedJobs.length}) <i class="fa-solid fa-paper-plane"></i>`;
} else {
submitBtn.classList.remove('active');
submitBtn.innerHTML = `请先选择岗位 <i class="fa-solid fa-ban"></i>`;
}
}
initSlots();
renderJobGrid();
})();
</script>
<!-- 应用主入口ES Module -->
<script type="module" src="./js/main.js"></script>
</body>
</html>