<!DOCTYPE html>
<html lang="zh-CN">
<head>
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#545BE8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="/icons/icon-192.png">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>五行画像 - 超协体</title>
<script src="/js/auth.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif;
background: linear-gradient(135deg, var(--brand-purple) 0%, var(--brand-purple-dark) 100%);
min-height: 100vh;
padding: 20px;
}
.profile-container {
max-width: 800px;
margin: 0 auto;
background: var(--surface-50);
border-radius: 20px;
padding: 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
.header {
text-align: center;
margin-bottom: 40px;
}
.header h1 {
font-size: 32px;
background: linear-gradient(135deg, var(--brand-purple) 0%, var(--brand-purple-dark) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 10px;
}
.header p {
color: var(--text-secondary);
font-size: 14px;
}
.progress-bar {
background: var(--surface-200);
height: 8px;
border-radius: 4px;
margin-bottom: 30px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--brand-purple) 0%, var(--brand-purple-dark) 100%);
transition: width 0.3s;
}
.section {
margin-bottom: 40px;
}
.section-title {
font-size: 20px;
font-weight: 600;
color: var(--text-main);
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
}
.wuxing-item {
margin-bottom: 30px;
padding: 20px;
background: var(--surface-50);
border-radius: 12px;
}
.wuxing-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.wuxing-name {
font-size: 18px;
font-weight: 600;
color: var(--text-main);
}
.wuxing-score {
font-size: 24px;
font-weight: bold;
color: var(--brand-purple);
}
.wuxing-description {
font-size: 13px;
color: var(--text-secondary);
margin-bottom: 15px;
line-height: 1.6;
}
.slider-container {
position: relative;
}
.slider {
width: 100%;
height: 8px;
border-radius: 4px;
outline: none;
-webkit-appearance: none;
}
.slider::-webkit-slider-track {
background: var(--surface-200);
border-radius: 4px;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--brand-purple);
cursor: pointer;
}
.slider::-moz-range-track {
background: var(--surface-200);
border-radius: 4px;
}
.slider::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--brand-purple);
cursor: pointer;
border: none;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
color: var(--text-main);
font-weight: 500;
}
.form-group input, .form-group textarea {
width: 100%;
padding: 12px 16px;
border: 2px solid var(--surface-200);
border-radius: 10px;
font-size: 14px;
transition: all 0.3s;
}
.form-group input:focus, .form-group textarea:focus {
outline: none;
border-color: var(--brand-purple);
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.form-group textarea {
min-height: 80px;
resize: vertical;
}
.form-group small {
color: var(--text-secondary);
font-size: 12px;
margin-top: 4px;
display: block;
}
.skills-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 12px;
}
.skill-tag {
padding: 6px 12px;
background: var(--brand-purple);
color: var(--surface-50);
border-radius: 16px;
font-size: 13px;
display: flex;
align-items: center;
gap: 6px;
}
.skill-tag .remove {
cursor: pointer;
font-weight: bold;
}
.btn-save {
width: 100%;
padding: 16px;
background: linear-gradient(135deg, var(--brand-purple) 0%, var(--brand-purple-dark) 100%);
color: var(--surface-50);
border: none;
border-radius: 12px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn-save:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
}
.btn-save:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.success-message {
background: rgba(34, 197, 94, 0.18);
color: var(--success);
padding: 16px;
border-radius: 10px;
margin-bottom: 20px;
display: none;
}
.error-message {
background: rgba(239, 68, 68, 0.12);
color: var(--error);
padding: 16px;
border-radius: 10px;
margin-bottom: 20px;
display: none;
}
.wuxing-fire { color: var(--error); }
.wuxing-metal { color: var(--warning); }
.wuxing-wood { color: var(--brand-mint); }
.wuxing-water { color: var(--info); }
.wuxing-earth { color: var(--brand-purple); }
</style>
<link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.1.1/src/bold/style.css">
<link rel="stylesheet" href="https://unpkg.com/@phosphor-icons/web@2.1.1/src/fill/style.css">
<link rel="stylesheet" href="/css/theme.css">
</head>
<body>
<div class="profile-container">
<div class="header">
<h1><i class="ph-bold ph-palette"></i> 五行画像</h1>
<p>了解你的能量特质,找到最佳协作伙伴</p>
</div>
<div class="progress-bar">
<div class="progress-fill" id="progressFill" style="width: 0%"></div>
</div>
<div id="successMessage" class="success-message"></div>
<div id="errorMessage" class="error-message"></div>
<form id="profileForm">
<!-- 五行评分 -->
<div class="section">
<div class="section-title">
<span><i class="ph-bold ph-yin-yang"></i>️</span>
<span>五行能量评估</span>
</div>
<!-- 火 -->
<div class="wuxing-item">
<div class="wuxing-header">
<div class="wuxing-name wuxing-fire"><i class="ph-bold ph-fire"></i> 火 - 行动派</div>
<div class="wuxing-score" id="fireScore">20</div>
</div>
<div class="wuxing-description">
快速决策、执行力强、点燃激情、引领变革
</div>
<input type="range" class="slider" id="fireSlider" min="0" max="100" value="20">
</div>
<!-- 金 -->
<div class="wuxing-item">
<div class="wuxing-header">
<div class="wuxing-name wuxing-metal"><i class="ph-bold ph-gear"></i>️ 金 - 思考者</div>
<div class="wuxing-score" id="metalScore">20</div>
</div>
<div class="wuxing-description">
深度思考、框架思维、优化系统、追求完美
</div>
<input type="range" class="slider" id="metalSlider" min="0" max="100" value="20">
</div>
<!-- 木 -->
<div class="wuxing-item">
<div class="wuxing-header">
<div class="wuxing-name wuxing-wood"><i class="ph-bold ph-tree"></i> 木 - 构建者</div>
<div class="wuxing-score" id="woodScore">20</div>
</div>
<div class="wuxing-description">
技术创造、系统搭建、持续迭代、工程实现
</div>
<input type="range" class="slider" id="woodSlider" min="0" max="100" value="20">
</div>
<!-- 水 -->
<div class="wuxing-item">
<div class="wuxing-header">
<div class="wuxing-name wuxing-water"><i class="ph-bold ph-drop"></i> 水 - 洞察者</div>
<div class="wuxing-score" id="waterScore">20</div>
</div>
<div class="wuxing-description">
趋势洞察、用户理解、灵活应变、战略判断
</div>
<input type="range" class="slider" id="waterSlider" min="0" max="100" value="20">
</div>
<!-- 土 -->
<div class="wuxing-item">
<div class="wuxing-header">
<div class="wuxing-name wuxing-earth"><i class="ph-bold ph-mountains"></i>️ 土 - 整合者</div>
<div class="wuxing-score" id="earthScore">20</div>
</div>
<div class="wuxing-description">
资源整合、团队协调、稳定基础、长期价值
</div>
<input type="range" class="slider" id="earthSlider" min="0" max="100" value="20">
</div>
</div>
<!-- 技能标签 -->
<div class="section">
<div class="section-title">
<span><i class="ph-bold ph-wrench"></i>️</span>
<span>技能标签</span>
</div>
<div class="skills-container" id="skillsContainer"></div>
<div class="form-group">
<input type="text" id="skillInput" placeholder="输入技能后按回车添加(如:产品设计、Python、用户研究)">
<small>按回车键添加技能标签</small>
</div>
</div>
<!-- 可选信息 -->
<div class="section">
<div class="section-title">
<span><i class="ph-bold ph-lightbulb"></i></span>
<span>更多信息(可选)</span>
</div>
<div class="form-group">
<label for="workStatus">当前工作状态</label>
<input type="text" id="workStatus" placeholder="如:全职创业、自由职业、在职...">
</div>
<div class="form-group">
<label for="painPoints">当前痛点</label>
<textarea id="painPoints" placeholder="在协作中遇到的困难或挑战..."></textarea>
</div>
<div class="form-group">
<label for="idealState">理想状态</label>
<textarea id="idealState" placeholder="期望的协作方式或目标..."></textarea>
</div>
</div>
<button type="submit" class="btn-save" id="saveBtn">
保存五行画像
</button>
</form>
</div>
<script>
const API_BASE = window.location.origin;
// 检查登录状态
if (!isLoggedIn()) {
window.location.href = '/login.html';
}
const wuxingSliders = {
fire: document.getElementById('fireSlider'),
metal: document.getElementById('metalSlider'),
wood: document.getElementById('woodSlider'),
water: document.getElementById('waterSlider'),
earth: document.getElementById('earthSlider')
};
const wuxingScores = {
fire: document.getElementById('fireScore'),
metal: document.getElementById('metalScore'),
wood: document.getElementById('woodScore'),
water: document.getElementById('waterScore'),
earth: document.getElementById('earthScore')
};
let skills = [];
// 滑块联动
Object.keys(wuxingSliders).forEach(key => {
wuxingSliders[key].addEventListener('input', (e) => {
wuxingScores[key].textContent = e.target.value;
updateProgress();
});
});
// 更新进度条
function updateProgress() {
const total = Object.keys(wuxingSliders).reduce((sum, key) =>
sum + parseInt(wuxingSliders[key].value), 0);
const avg = total / 5;
const progress = Math.min((avg / 100) * 100, 100);
document.getElementById('progressFill').style.width = progress + '%';
}
// 技能标签
const skillInput = document.getElementById('skillInput');
const skillsContainer = document.getElementById('skillsContainer');
skillInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
const skill = skillInput.value.trim();
if (skill && !skills.includes(skill)) {
skills.push(skill);
renderSkills();
skillInput.value = '';
}
}
});
function renderSkills() {
skillsContainer.innerHTML = skills.map((skill, index) => `
<div class="skill-tag">
<span>${skill}</span>
<span class="remove" onclick="removeSkill(${index})">×</span>
</div>
`).join('');
}
function removeSkill(index) {
skills.splice(index, 1);
renderSkills();
}
// 加载现有画像
async function loadProfile() {
try {
const response = await authFetch('/api/auth/me');
const data = await response.json();
if (data.success && data.user.pwpProfile) {
const profile = data.user.pwpProfile;
// 加载五行分数
if (profile.wuxing) {
Object.keys(profile.wuxing).forEach(key => {
if (wuxingSliders[key]) {
wuxingSliders[key].value = profile.wuxing[key];
wuxingScores[key].textContent = profile.wuxing[key];
}
});
updateProgress();
}
// 加载技能
if (profile.skills) {
skills = profile.skills;
renderSkills();
}
// 加载其他信息
if (profile.work_status) {
document.getElementById('workStatus').value = profile.work_status;
}
if (profile.pain_points) {
document.getElementById('painPoints').value = Array.isArray(profile.pain_points)
? profile.pain_points.join('\n')
: profile.pain_points;
}
if (profile.ideal_state) {
document.getElementById('idealState').value = profile.ideal_state;
}
}
} catch (error) {
console.error('加载画像失败:', error);
}
}
// 保存画像
const profileForm = document.getElementById('profileForm');
const saveBtn = document.getElementById('saveBtn');
const successMessage = document.getElementById('successMessage');
const errorMessage = document.getElementById('errorMessage');
profileForm.addEventListener('submit', async (e) => {
e.preventDefault();
// 隐藏消息
successMessage.style.display = 'none';
errorMessage.style.display = 'none';
// 禁用按钮
saveBtn.disabled = true;
saveBtn.textContent = '保存中...';
const profile = {
wuxing: {
fire: parseInt(wuxingSliders.fire.value),
metal: parseInt(wuxingSliders.metal.value),
wood: parseInt(wuxingSliders.wood.value),
water: parseInt(wuxingSliders.water.value),
earth: parseInt(wuxingSliders.earth.value)
},
skills: skills,
work_status: document.getElementById('workStatus').value,
pain_points: document.getElementById('painPoints').value.split('\n').filter(p => p.trim()),
ideal_state: document.getElementById('idealState').value
};
try {
const response = await authFetch('/api/profile/update', {
method: 'POST',
body: JSON.stringify({ profile })
});
const data = await response.json();
if (data.success) {
successMessage.textContent = '<i class="ph-bold ph-check-circle"></i> 五行画像保存成功!';
successMessage.style.display = 'block';
setTimeout(() => {
window.location.href = '/dashboard.html';
}, 1500);
} else {
errorMessage.textContent = data.message || '保存失败';
errorMessage.style.display = 'block';
saveBtn.disabled = false;
saveBtn.textContent = '保存五行画像';
}
} catch (error) {
console.error('保存失败:', error);
errorMessage.textContent = '网络错误,请重试';
errorMessage.style.display = 'block';
saveBtn.disabled = false;
saveBtn.textContent = '保存五行画像';
}
});
// 页面加载时加载现有画像
loadProfile();
</script>
<script src="/js/pwa.js" defer></script>
</body>
</html>