You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1353 lines
48 KiB
1353 lines
48 KiB
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=375, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
<title>青核 Youthome - 社交图谱</title>
|
|
<link rel="stylesheet" href="../colors_and_type.css">
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'SF Pro Display', 'Helvetica Neue', sans-serif;
|
|
background: var(--youth-bg-page);
|
|
color: var(--youth-text-primary);
|
|
min-height: 100vh;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.app-container {
|
|
width: 375px;
|
|
height: 812px;
|
|
margin: 0 auto;
|
|
background: var(--youth-bg-page);
|
|
position: relative;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* ========== 状态栏 ========== */
|
|
.status-bar {
|
|
height: 44px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 20px;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: var(--youth-text-primary);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.status-bar .right-icons {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
/* ========== 顶部导航栏 ========== */
|
|
.top-nav {
|
|
height: 44px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 16px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.nav-btn {
|
|
width: 36px;
|
|
height: 36px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 50%;
|
|
color: var(--youth-text-primary);
|
|
cursor: pointer;
|
|
transition: background 0.2s ease;
|
|
border: none;
|
|
background: transparent;
|
|
}
|
|
|
|
.nav-btn:active {
|
|
background: var(--youth-bg-hover);
|
|
}
|
|
|
|
.nav-title {
|
|
font-size: 17px;
|
|
font-weight: 700;
|
|
color: var(--youth-text-primary);
|
|
position: absolute;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
/* ========== 内容区 ========== */
|
|
.content-area {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
padding-bottom: 160px;
|
|
}
|
|
|
|
.content-area::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
/* ========== 统计卡片 ========== */
|
|
.stats-card {
|
|
margin: 12px 16px 10px;
|
|
padding: 14px 16px;
|
|
background: var(--youth-bg-card);
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.stats-left {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.stats-number {
|
|
font-size: 32px;
|
|
font-weight: 800;
|
|
line-height: 1;
|
|
background: linear-gradient(135deg, #54CAC5 0%, #26C2BB 50%, #1FA8A2 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.stats-label {
|
|
font-size: 12px;
|
|
color: var(--youth-text-tertiary);
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.stats-right {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
align-items: flex-end;
|
|
}
|
|
|
|
.stats-mini-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.stats-mini-dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.stats-mini-dot.school { background: #4A90D9; }
|
|
.stats-mini-dot.major { background: #9B7AD6; }
|
|
.stats-mini-dot.hometown { background: #52C41A; }
|
|
|
|
.stats-mini-text {
|
|
font-size: 12px;
|
|
color: var(--youth-text-secondary);
|
|
}
|
|
|
|
.stats-mini-text strong {
|
|
color: var(--youth-text-primary);
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* ========== 数据概览卡片 ========== */
|
|
.overview-card {
|
|
margin: 0 16px;
|
|
padding: 12px 8px;
|
|
background: var(--youth-bg-card);
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
.overview-item {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 3px;
|
|
}
|
|
|
|
.overview-value {
|
|
font-size: 16px;
|
|
font-weight: 700;
|
|
color: var(--youth-text-primary);
|
|
line-height: 1;
|
|
}
|
|
|
|
.overview-label {
|
|
font-size: 11px;
|
|
color: var(--youth-text-tertiary);
|
|
}
|
|
|
|
.overview-divider {
|
|
width: 1px;
|
|
height: 24px;
|
|
background: var(--youth-border-light, #E8E8E8);
|
|
}
|
|
|
|
/* ========== 分区标题 ========== */
|
|
.section-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 14px 16px 8px;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 15px;
|
|
font-weight: 700;
|
|
color: var(--youth-text-primary);
|
|
}
|
|
|
|
.section-more {
|
|
font-size: 12px;
|
|
color: var(--youth-text-tertiary);
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* ========== 亲密好友横向滚动 ========== */
|
|
.close-friends {
|
|
display: flex;
|
|
gap: 16px;
|
|
padding: 0 16px 8px;
|
|
overflow-x: auto;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.close-friends::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.friend-avatar-item {
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 6px;
|
|
cursor: pointer;
|
|
width: 60px;
|
|
}
|
|
|
|
.friend-avatar {
|
|
width: 54px;
|
|
height: 54px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #FFFFFF;
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
border: 2px solid #FFFFFF;
|
|
}
|
|
|
|
.friend-name {
|
|
font-size: 12px;
|
|
color: var(--youth-text-primary);
|
|
font-weight: 500;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.friend-match {
|
|
font-size: 10px;
|
|
color: var(--youth-primary);
|
|
font-weight: 600;
|
|
margin-top: -4px;
|
|
}
|
|
|
|
/* ========== 推荐认识列表 ========== */
|
|
.recommend-list {
|
|
margin: 0 16px 16px;
|
|
background: var(--youth-bg-card);
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.recommend-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 12px 14px;
|
|
gap: 12px;
|
|
position: relative;
|
|
}
|
|
|
|
.recommend-item + .recommend-item::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 78px;
|
|
right: 16px;
|
|
height: 1px;
|
|
background: var(--youth-border-light, #E8E8E8);
|
|
}
|
|
|
|
.recommend-avatar {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #FFFFFF;
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.recommend-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
.recommend-name-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.recommend-name {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: var(--youth-text-primary);
|
|
}
|
|
|
|
.recommend-match {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: var(--youth-primary);
|
|
}
|
|
|
|
.recommend-desc {
|
|
font-size: 11px;
|
|
color: var(--youth-text-tertiary);
|
|
}
|
|
|
|
.recommend-tags {
|
|
display: flex;
|
|
gap: 4px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.rec-tag {
|
|
height: 16px;
|
|
padding: 0 6px;
|
|
border-radius: 8px;
|
|
font-size: 10px;
|
|
font-weight: 500;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.rec-tag.school { background: rgba(74, 144, 217, 0.1); color: #4A90D9; }
|
|
.rec-tag.major { background: rgba(155, 122, 214, 0.1); color: #9B7AD6; }
|
|
.rec-tag.hometown { background: rgba(82, 196, 26, 0.1); color: #52C41A; }
|
|
.rec-tag.interest { background: rgba(255, 159, 69, 0.1); color: #FF9F45; }
|
|
|
|
.btn-add {
|
|
height: 26px;
|
|
padding: 0 12px;
|
|
border-radius: 13px;
|
|
border: 1.5px solid var(--youth-primary);
|
|
background: transparent;
|
|
color: var(--youth-primary);
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
transition: all 0.15s ease;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.btn-add:active {
|
|
background: var(--youth-primary-bg);
|
|
transform: scale(0.96);
|
|
}
|
|
|
|
/* ========== 五色关系图例 ========== */
|
|
.legend-section {
|
|
padding: 12px 16px 8px;
|
|
}
|
|
|
|
.legend-row {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 12px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.legend-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 11px;
|
|
color: var(--youth-text-tertiary);
|
|
}
|
|
|
|
.legend-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.legend-dot.school { background: #7EB8E8; }
|
|
.legend-dot.major { background: #C4A8F0; }
|
|
.legend-dot.hometown { background: #8ED9B0; }
|
|
.legend-dot.interest { background: #FFC89A; }
|
|
.legend-dot.active { background: #FF9AA8; }
|
|
|
|
/* ========== 社交图谱可视化区 ========== */
|
|
.graph-section {
|
|
padding: 0 16px 8px;
|
|
}
|
|
|
|
.graph-container {
|
|
width: 100%;
|
|
max-width: 343px;
|
|
height: 320px;
|
|
margin: 0 auto;
|
|
background: var(--youth-bg-card);
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.graph-svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
/* 节点动画 */
|
|
@keyframes breathe {
|
|
0%, 100% { opacity: 0.5; transform: scale(1); }
|
|
50% { opacity: 0.7; transform: scale(1.05); }
|
|
}
|
|
|
|
@keyframes float-slow {
|
|
0%, 100% { transform: translateY(0); }
|
|
50% { transform: translateY(-4px); }
|
|
}
|
|
|
|
.graph-center-glow {
|
|
animation: breathe 3s ease-in-out infinite;
|
|
transform-origin: center;
|
|
transform-box: fill-box;
|
|
}
|
|
|
|
.graph-node {
|
|
cursor: pointer;
|
|
transition: all 0.25s ease;
|
|
}
|
|
|
|
.graph-node:hover {
|
|
filter: brightness(1.08);
|
|
}
|
|
|
|
.graph-node:active {
|
|
transform: scale(1.1);
|
|
transform-origin: center;
|
|
transform-box: fill-box;
|
|
}
|
|
|
|
.graph-node.selected circle:first-of-type {
|
|
stroke-width: 3 !important;
|
|
}
|
|
|
|
.node-float-1 { animation: float-slow 3s ease-in-out infinite; transform-origin: center; transform-box: fill-box; }
|
|
.node-float-2 { animation: float-slow 3.5s ease-in-out infinite 0.4s; transform-origin: center; transform-box: fill-box; }
|
|
.node-float-3 { animation: float-slow 4s ease-in-out infinite 0.8s; transform-origin: center; transform-box: fill-box; }
|
|
.node-float-4 { animation: float-slow 3.2s ease-in-out infinite 0.2s; transform-origin: center; transform-box: fill-box; }
|
|
.node-float-5 { animation: float-slow 3.8s ease-in-out infinite 0.6s; transform-origin: center; transform-box: fill-box; }
|
|
|
|
.graph-line {
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
|
|
/* ========== 底部选中用户卡片 ========== */
|
|
.selected-user-card {
|
|
position: absolute;
|
|
left: 16px;
|
|
right: 16px;
|
|
bottom: 76px;
|
|
background: var(--youth-bg-card);
|
|
border-radius: 12px;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
|
padding: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
z-index: 15;
|
|
transition: all 0.3s ease;
|
|
border: 1px solid var(--youth-border-light, #E8E8E8);
|
|
}
|
|
|
|
.selected-avatar {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
color: #FFFFFF;
|
|
}
|
|
|
|
.selected-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.selected-name-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
margin-bottom: 3px;
|
|
}
|
|
|
|
.selected-name {
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: var(--youth-text-primary);
|
|
}
|
|
|
|
.match-tag {
|
|
height: 18px;
|
|
padding: 0 8px;
|
|
background: linear-gradient(135deg, #54CAC5 0%, #26C2BB 50%, #1FA8A2 100%);
|
|
color: #FFFFFF;
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
border-radius: 9px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.selected-school {
|
|
font-size: 12px;
|
|
color: var(--youth-text-tertiary);
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.relation-tags {
|
|
display: flex;
|
|
gap: 4px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.relation-tag {
|
|
height: 18px;
|
|
padding: 0 8px;
|
|
border-radius: 9px;
|
|
font-size: 10px;
|
|
font-weight: 500;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.relation-tag.school {
|
|
background: rgba(74, 144, 217, 0.1);
|
|
color: #4A90D9;
|
|
}
|
|
|
|
.relation-tag.major {
|
|
background: rgba(155, 122, 214, 0.1);
|
|
color: #9B7AD6;
|
|
}
|
|
|
|
.relation-tag.hometown {
|
|
background: rgba(82, 196, 26, 0.1);
|
|
color: #52C41A;
|
|
}
|
|
|
|
.relation-tag.interest {
|
|
background: rgba(255, 159, 69, 0.1);
|
|
color: #FF9F45;
|
|
}
|
|
|
|
.relation-tag.active {
|
|
background: rgba(245, 103, 123, 0.1);
|
|
color: #F5677B;
|
|
}
|
|
|
|
.selected-actions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.btn-greet {
|
|
height: 28px;
|
|
padding: 0 12px;
|
|
border: 1.5px solid var(--youth-primary);
|
|
border-radius: 8px;
|
|
background: transparent;
|
|
color: var(--youth-primary);
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.btn-greet:active {
|
|
background: var(--youth-primary-bg);
|
|
transform: scale(0.96);
|
|
}
|
|
|
|
.btn-profile {
|
|
height: 28px;
|
|
padding: 0 12px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
background: linear-gradient(135deg, #54CAC5 0%, #26C2BB 50%, #1FA8A2 100%);
|
|
color: #FFFFFF;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
box-shadow: 0 2px 6px rgba(38, 194, 187, 0.25);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.btn-profile:active {
|
|
transform: scale(0.96);
|
|
box-shadow: 0 1px 3px rgba(38, 194, 187, 0.2);
|
|
}
|
|
|
|
/* ========== 底部Tab导航 ========== */
|
|
.bottom-nav {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 64px;
|
|
background: var(--youth-bg-card);
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-around;
|
|
padding-top: 8px;
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
box-shadow: 0 -1px 12px rgba(0,0,0,0.04);
|
|
z-index: 50;
|
|
border-top: 1px solid var(--youth-border-light, #E8E8E8);
|
|
}
|
|
|
|
.tab-item {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 3px;
|
|
cursor: pointer;
|
|
position: relative;
|
|
padding-top: 2px;
|
|
}
|
|
|
|
.tab-item svg {
|
|
width: 24px;
|
|
height: 24px;
|
|
stroke-width: 2;
|
|
color: var(--youth-text-tertiary);
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.tab-item.active svg {
|
|
color: var(--youth-primary);
|
|
}
|
|
|
|
.tab-item .tab-label {
|
|
font-size: 10px;
|
|
color: var(--youth-text-tertiary);
|
|
font-weight: 500;
|
|
transition: color 0.2s ease;
|
|
}
|
|
|
|
.tab-item.active .tab-label {
|
|
color: var(--youth-primary);
|
|
}
|
|
|
|
/* ========== 响应式 ========== */
|
|
@media (max-width: 375px) {
|
|
.app-container {
|
|
width: 100%;
|
|
height: 100vh;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body><div class="app-container" style="height: 1103px;"><svg class="inline-defs-container" aria-hidden="true" style="position:absolute;width:0;height:0;overflow:hidden"></svg>
|
|
<!-- 状态栏 -->
|
|
<div class="status-bar">
|
|
<span>9:41</span>
|
|
<div class="right-icons">
|
|
<svg width="17" height="11" viewBox="0 0 17 11" fill="currentColor">
|
|
<rect x="0" y="7" width="3" height="4" rx="0.5"></rect>
|
|
<rect x="4.5" y="5" width="3" height="6" rx="0.5"></rect>
|
|
<rect x="9" y="2.5" width="3" height="8.5" rx="0.5"></rect>
|
|
<rect x="13.5" y="0" width="3" height="11" rx="0.5"></rect>
|
|
</svg>
|
|
<svg width="15" height="11" viewBox="0 0 15 11" fill="currentColor">
|
|
<path d="M7.5 1C5.3 1 3.2 1.7 1.5 3C-0.5 4.7 -0.5 7.5 1.5 9.2C1.9 9.6 2.5 9.6 2.9 9.2C3.3 8.8 3.3 8.2 2.9 7.8C1.6 6.5 1.6 4.4 2.9 3.1C4.2 1.8 6.3 1.4 8 2C10.1 2.7 11.7 4.4 12.2 6.5C12.5 7.3 12.4 8.1 11.8 8.7C11.4 9.1 11.4 9.7 11.8 10.1C12.2 10.5 12.8 10.5 13.2 10.1C14.2 9.1 14.5 7.7 14.2 6.3C13.6 4 12.1 2.3 10.2 1.3C9.3 1 8.4 0.9 7.5 1Z"></path>
|
|
<path d="M7.5 4.5C6 4.5 4.5 5 3.4 6.2C2.3 7.4 2 9 2.4 10.4C2.5 10.8 2.8 11 3.2 11C3.5 11 3.8 10.8 3.9 10.5C4.2 9.5 4.8 8.6 5.7 8C6.6 7.4 7.6 7.1 8.6 7.2C9.8 7.3 10.9 7.8 11.6 8.7C12.3 9.6 12.6 10.7 12.4 11.8L12.4 12C12.3 12.4 12.6 12.7 13 12.8C13.4 12.9 13.7 12.6 13.8 12.2C14.1 10.5 13.5 8.8 12.4 7.5C11.3 6.2 9.6 5.3 7.8 4.9L7.5 4.5Z"></path>
|
|
</svg>
|
|
<svg width="25" height="12" viewBox="0 0 25 12" fill="none">
|
|
<rect x="0.5" y="0.5" width="21" height="11" rx="2.5" stroke="currentColor" opacity="0.5"></rect>
|
|
<rect x="2" y="2" width="18" height="8" rx="1.5" fill="currentColor"></rect>
|
|
<rect x="22.5" y="4" width="1.5" height="4" rx="0.5" fill="currentColor" opacity="0.5"></rect>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 顶部导航栏 -->
|
|
<div class="top-nav">
|
|
<button class="nav-btn" onclick="goBack()" aria-label="返回">
|
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<polyline points="15 18 9 12 15 6"></polyline>
|
|
</svg>
|
|
</button>
|
|
<div class="nav-title">社交图谱</div>
|
|
<button class="nav-btn" onclick="handleShare()" aria-label="分享">
|
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="18" cy="5" r="3"></circle>
|
|
<circle cx="6" cy="12" r="3"></circle>
|
|
<circle cx="18" cy="19" r="3"></circle>
|
|
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line>
|
|
<line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- 内容区 -->
|
|
<div class="content-area">
|
|
<!-- 统计卡片 -->
|
|
<div class="stats-card">
|
|
<div class="stats-left">
|
|
<div class="stats-number">128</div>
|
|
<div class="stats-label">关系网络人数</div>
|
|
</div>
|
|
<div class="stats-right">
|
|
<div class="stats-mini-item">
|
|
<span class="stats-mini-text">同校 <strong>86</strong>人</span>
|
|
<span class="stats-mini-dot school"></span>
|
|
</div>
|
|
<div class="stats-mini-item">
|
|
<span class="stats-mini-text">同专业 <strong>42</strong>人</span>
|
|
<span class="stats-mini-dot major"></span>
|
|
</div>
|
|
<div class="stats-mini-item">
|
|
<span class="stats-mini-text">同乡 <strong>35</strong>人</span>
|
|
<span class="stats-mini-dot hometown"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 数据概览卡片 -->
|
|
<div class="overview-card">
|
|
<div class="overview-item">
|
|
<div class="overview-value">12</div>
|
|
<div class="overview-label">共同好友</div>
|
|
</div>
|
|
<div class="overview-divider"></div>
|
|
<div class="overview-item">
|
|
<div class="overview-value">8</div>
|
|
<div class="overview-label">共同社团</div>
|
|
</div>
|
|
<div class="overview-divider"></div>
|
|
<div class="overview-item">
|
|
<div class="overview-value">23</div>
|
|
<div class="overview-label">共同兴趣</div>
|
|
</div>
|
|
<div class="overview-divider"></div>
|
|
<div class="overview-item">
|
|
<div class="overview-value">95%</div>
|
|
<div class="overview-label">匹配度</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 五色关系图例 -->
|
|
<div class="legend-section">
|
|
<div class="legend-row">
|
|
<div class="legend-item">
|
|
<span class="legend-dot school"></span>
|
|
<span>同校</span>
|
|
</div>
|
|
<div class="legend-item">
|
|
<span class="legend-dot major"></span>
|
|
<span>同专业</span>
|
|
</div>
|
|
<div class="legend-item">
|
|
<span class="legend-dot hometown"></span>
|
|
<span>同乡</span>
|
|
</div>
|
|
<div class="legend-item">
|
|
<span class="legend-dot interest"></span>
|
|
<span>兴趣契合</span>
|
|
</div>
|
|
<div class="legend-item">
|
|
<span class="legend-dot active"></span>
|
|
<span>活跃用户</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 社交图谱可视化区 -->
|
|
<div class="graph-section">
|
|
<div class="graph-container">
|
|
<svg class="graph-svg" viewBox="0 0 343 320" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<!-- 中心光晕渐变 -->
|
|
<radialGradient id="centerGlow" cx="50%" cy="50%" r="50%">
|
|
<stop offset="0%" stop-color="#26C2BB" stop-opacity="0.3"></stop>
|
|
<stop offset="50%" stop-color="#26C2BB" stop-opacity="0.1"></stop>
|
|
<stop offset="100%" stop-color="#26C2BB" stop-opacity="0"></stop>
|
|
</radialGradient>
|
|
|
|
<!-- 主色渐变 -->
|
|
<linearGradient id="primaryGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" stop-color="#54CAC5"></stop>
|
|
<stop offset="50%" stop-color="#26C2BB"></stop>
|
|
<stop offset="100%" stop-color="#1FA8A2"></stop>
|
|
</linearGradient>
|
|
|
|
<!-- 同校蓝渐变 -->
|
|
<linearGradient id="schoolGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" stop-color="#7EB8E8"></stop>
|
|
<stop offset="100%" stop-color="#4A90D9"></stop>
|
|
</linearGradient>
|
|
|
|
<!-- 同专业紫渐变 -->
|
|
<linearGradient id="majorGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" stop-color="#C4A8F0"></stop>
|
|
<stop offset="100%" stop-color="#9B7AD6"></stop>
|
|
</linearGradient>
|
|
|
|
<!-- 同乡绿渐变 -->
|
|
<linearGradient id="hometownGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" stop-color="#8ED9B0"></stop>
|
|
<stop offset="100%" stop-color="#52C41A"></stop>
|
|
</linearGradient>
|
|
|
|
<!-- 兴趣橙渐变 -->
|
|
<linearGradient id="interestGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" stop-color="#FFC89A"></stop>
|
|
<stop offset="100%" stop-color="#FF9F45"></stop>
|
|
</linearGradient>
|
|
|
|
<!-- 活跃红渐变 -->
|
|
<linearGradient id="activeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" stop-color="#FF9AA8"></stop>
|
|
<stop offset="100%" stop-color="#F5677B"></stop>
|
|
</linearGradient>
|
|
</defs>
|
|
|
|
<!-- 背景装饰圆 -->
|
|
<circle cx="171.5" cy="160" r="120" fill="#26C2BB" opacity="0.03"></circle>
|
|
<circle cx="171.5" cy="160" r="85" fill="#26C2BB" opacity="0.04"></circle>
|
|
<circle cx="171.5" cy="160" r="55" fill="#26C2BB" opacity="0.05"></circle>
|
|
|
|
<!-- 连线 - 同校(蓝) -->
|
|
<g class="graph-lines" stroke="#7EB8E8" stroke-width="1.5" stroke-opacity="0.4">
|
|
<line x1="171.5" y1="160" x2="85" y2="90"></line>
|
|
<line x1="171.5" y1="160" x2="70" y2="175"></line>
|
|
<line x1="171.5" y1="160" x2="110" y2="250"></line>
|
|
<line x1="171.5" y1="160" x2="235" y2="240"></line>
|
|
<line x1="171.5" y1="160" x2="265" y2="155"></line>
|
|
<line x1="171.5" y1="160" x2="245" y2="80"></line>
|
|
</g>
|
|
|
|
<!-- 连线 - 同专业(紫) -->
|
|
<g class="graph-lines" stroke="#C4A8F0" stroke-width="1.5" stroke-opacity="0.4">
|
|
<line x1="171.5" y1="160" x2="105" y2="115"></line>
|
|
<line x1="171.5" y1="160" x2="95" y2="210"></line>
|
|
<line x1="171.5" y1="160" x2="200" y2="255"></line>
|
|
<line x1="171.5" y1="160" x2="255" y2="195"></line>
|
|
<line x1="171.5" y1="160" x2="250" y2="105"></line>
|
|
</g>
|
|
|
|
<!-- 连线 - 同乡(绿) -->
|
|
<g class="graph-lines" stroke="#8ED9B0" stroke-width="1.5" stroke-opacity="0.4">
|
|
<line x1="171.5" y1="160" x2="130" y2="95"></line>
|
|
<line x1="171.5" y1="160" x2="125" y2="230"></line>
|
|
<line x1="171.5" y1="160" x2="220" y2="220"></line>
|
|
<line x1="171.5" y1="160" x2="230" y2="120"></line>
|
|
</g>
|
|
|
|
<!-- 连线 - 兴趣契合(橙) -->
|
|
<g class="graph-lines" stroke="#FFC89A" stroke-width="1.5" stroke-opacity="0.4">
|
|
<line x1="171.5" y1="160" x2="145" y2="105"></line>
|
|
<line x1="171.5" y1="160" x2="140" y2="215"></line>
|
|
<line x1="171.5" y1="160" x2="210" y2="235"></line>
|
|
<line x1="171.5" y1="160" x2="225" y2="140"></line>
|
|
</g>
|
|
|
|
<!-- 连线 - 活跃用户(红) -->
|
|
<g class="graph-lines" stroke="#FF9AA8" stroke-width="1.5" stroke-opacity="0.4">
|
|
<line x1="171.5" y1="160" x2="155" y2="115"></line>
|
|
<line x1="171.5" y1="160" x2="195" y2="110"></line>
|
|
<line x1="171.5" y1="160" x2="190" y2="215"></line>
|
|
<line x1="171.5" y1="160" x2="150" y2="200"></line>
|
|
</g>
|
|
|
|
<!-- 外层普通节点 - 同校(蓝) -->
|
|
<g class="graph-layer-outer">
|
|
<g class="graph-node node-float-1" data-user="1" onclick="selectNode(this, 1)">
|
|
<circle cx="85" cy="90" r="16" fill="#FFFFFF" stroke="#7EB8E8" stroke-width="2"></circle>
|
|
<circle cx="85" cy="90" r="11" fill="#A8CCEE"></circle>
|
|
<text x="85" y="94" text-anchor="middle" font-size="9" fill="#2E6CB5" font-weight="600">雨</text>
|
|
</g>
|
|
<g class="graph-node node-float-2" data-user="2" onclick="selectNode(this, 2)">
|
|
<circle cx="70" cy="175" r="16" fill="#FFFFFF" stroke="#7EB8E8" stroke-width="2"></circle>
|
|
<circle cx="70" cy="175" r="11" fill="#A8CCEE"></circle>
|
|
<text x="70" y="179" text-anchor="middle" font-size="9" fill="#2E6CB5" font-weight="600">杰</text>
|
|
</g>
|
|
<g class="graph-node node-float-3" data-user="3" onclick="selectNode(this, 3)">
|
|
<circle cx="110" cy="250" r="16" fill="#FFFFFF" stroke="#7EB8E8" stroke-width="2"></circle>
|
|
<circle cx="110" cy="250" r="11" fill="#A8CCEE"></circle>
|
|
<text x="110" y="254" text-anchor="middle" font-size="9" fill="#2E6CB5" font-weight="600">思</text>
|
|
</g>
|
|
<g class="graph-node node-float-4" data-user="4" onclick="selectNode(this, 4)">
|
|
<circle cx="235" cy="240" r="16" fill="#FFFFFF" stroke="#7EB8E8" stroke-width="2"></circle>
|
|
<circle cx="235" cy="240" r="11" fill="#A8CCEE"></circle>
|
|
<text x="235" y="244" text-anchor="middle" font-size="9" fill="#2E6CB5" font-weight="600">美</text>
|
|
</g>
|
|
<g class="graph-node node-float-5" data-user="5" onclick="selectNode(this, 5)">
|
|
<circle cx="265" cy="155" r="16" fill="#FFFFFF" stroke="#7EB8E8" stroke-width="2"></circle>
|
|
<circle cx="265" cy="155" r="11" fill="#A8CCEE"></circle>
|
|
<text x="265" y="159" text-anchor="middle" font-size="9" fill="#2E6CB5" font-weight="600">伟</text>
|
|
</g>
|
|
<g class="graph-node node-float-1" data-user="6" onclick="selectNode(this, 6)">
|
|
<circle cx="245" cy="80" r="16" fill="#FFFFFF" stroke="#7EB8E8" stroke-width="2"></circle>
|
|
<circle cx="245" cy="80" r="11" fill="#A8CCEE"></circle>
|
|
<text x="245" y="84" text-anchor="middle" font-size="9" fill="#2E6CB5" font-weight="600">婷</text>
|
|
</g>
|
|
</g>
|
|
|
|
<!-- 中层节点 - 同专业(紫) -->
|
|
<g class="graph-layer-middle">
|
|
<g class="graph-node node-float-2" data-user="7" onclick="selectNode(this, 7)">
|
|
<circle cx="105" cy="115" r="18" fill="#FFFFFF" stroke="#C4A8F0" stroke-width="2"></circle>
|
|
<circle cx="105" cy="115" r="13" fill="#D9C8F5"></circle>
|
|
<text x="105" y="119" text-anchor="middle" font-size="10" fill="#7B5BC4" font-weight="600">明</text>
|
|
</g>
|
|
<g class="graph-node node-float-3" data-user="8" onclick="selectNode(this, 8)">
|
|
<circle cx="95" cy="210" r="18" fill="#FFFFFF" stroke="#C4A8F0" stroke-width="2"></circle>
|
|
<circle cx="95" cy="210" r="13" fill="#D9C8F5"></circle>
|
|
<text x="95" y="214" text-anchor="middle" font-size="10" fill="#7B5BC4" font-weight="600">华</text>
|
|
</g>
|
|
<g class="graph-node node-float-4" data-user="9" onclick="selectNode(this, 9)">
|
|
<circle cx="200" cy="255" r="18" fill="#FFFFFF" stroke="#C4A8F0" stroke-width="2"></circle>
|
|
<circle cx="200" cy="255" r="13" fill="#D9C8F5"></circle>
|
|
<text x="200" y="259" text-anchor="middle" font-size="10" fill="#7B5BC4" font-weight="600">磊</text>
|
|
</g>
|
|
<g class="graph-node node-float-5" data-user="10" onclick="selectNode(this, 10)">
|
|
<circle cx="255" cy="195" r="18" fill="#FFFFFF" stroke="#C4A8F0" stroke-width="2"></circle>
|
|
<circle cx="255" cy="195" r="13" fill="#D9C8F5"></circle>
|
|
<text x="255" y="199" text-anchor="middle" font-size="10" fill="#7B5BC4" font-weight="600">鹏</text>
|
|
</g>
|
|
<g class="graph-node node-float-1" data-user="11" onclick="selectNode(this, 11)">
|
|
<circle cx="250" cy="105" r="18" fill="#FFFFFF" stroke="#C4A8F0" stroke-width="2"></circle>
|
|
<circle cx="250" cy="105" r="13" fill="#D9C8F5"></circle>
|
|
<text x="250" y="109" text-anchor="middle" font-size="10" fill="#7B5BC4" font-weight="600">悦</text>
|
|
</g>
|
|
</g>
|
|
|
|
<!-- 内层节点 - 同乡(绿) -->
|
|
<g class="graph-layer-inner">
|
|
<g class="graph-node node-float-3" data-user="12" onclick="selectNode(this, 12)">
|
|
<circle cx="130" cy="95" r="20" fill="#FFFFFF" stroke="#8ED9B0" stroke-width="2"></circle>
|
|
<circle cx="130" cy="95" r="15" fill="#B4E5C8"></circle>
|
|
<text x="130" y="99" text-anchor="middle" font-size="11" fill="#3DA82E" font-weight="700">琳</text>
|
|
</g>
|
|
<g class="graph-node node-float-4" data-user="13" onclick="selectNode(this, 13)">
|
|
<circle cx="125" cy="230" r="20" fill="#FFFFFF" stroke="#8ED9B0" stroke-width="2"></circle>
|
|
<circle cx="125" cy="230" r="15" fill="#B4E5C8"></circle>
|
|
<text x="125" y="234" text-anchor="middle" font-size="11" fill="#3DA82E" font-weight="700">浩</text>
|
|
</g>
|
|
<g class="graph-node node-float-5" data-user="14" onclick="selectNode(this, 14)">
|
|
<circle cx="220" cy="220" r="20" fill="#FFFFFF" stroke="#8ED9B0" stroke-width="2"></circle>
|
|
<circle cx="220" cy="220" r="15" fill="#B4E5C8"></circle>
|
|
<text x="220" y="224" text-anchor="middle" font-size="11" fill="#3DA82E" font-weight="700">雯</text>
|
|
</g>
|
|
<g class="graph-node node-float-1" data-user="15" onclick="selectNode(this, 15)">
|
|
<circle cx="230" cy="120" r="20" fill="#FFFFFF" stroke="#8ED9B0" stroke-width="2"></circle>
|
|
<circle cx="230" cy="120" r="15" fill="#B4E5C8"></circle>
|
|
<text x="230" y="124" text-anchor="middle" font-size="11" fill="#3DA82E" font-weight="700">博</text>
|
|
</g>
|
|
</g>
|
|
|
|
<!-- 亲密层节点 - 兴趣契合(橙)+ 活跃(红) -->
|
|
<g class="graph-layer-close">
|
|
<g class="graph-node node-float-2 selected" data-user="16" onclick="selectNode(this, 16)">
|
|
<circle cx="145" cy="105" r="22" fill="#FFFFFF" stroke="#FFC89A" stroke-width="2.5"></circle>
|
|
<circle cx="145" cy="105" r="17" fill="#FFD9B8"></circle>
|
|
<text x="145" y="109" text-anchor="middle" font-size="11" fill="#D97A20" font-weight="700">小</text>
|
|
</g>
|
|
<g class="graph-node node-float-3" data-user="17" onclick="selectNode(this, 17)">
|
|
<circle cx="140" cy="215" r="22" fill="#FFFFFF" stroke="#FFC89A" stroke-width="2.5"></circle>
|
|
<circle cx="140" cy="215" r="17" fill="#FFD9B8"></circle>
|
|
<text x="140" y="219" text-anchor="middle" font-size="11" fill="#D97A20" font-weight="700">阿</text>
|
|
</g>
|
|
<g class="graph-node node-float-4" data-user="18" onclick="selectNode(this, 18)">
|
|
<circle cx="210" cy="235" r="22" fill="#FFFFFF" stroke="#FF9AA8" stroke-width="2.5"></circle>
|
|
<circle cx="210" cy="235" r="17" fill="#FFB8C2"></circle>
|
|
<text x="210" y="239" text-anchor="middle" font-size="11" fill="#D64A60" font-weight="700">星</text>
|
|
</g>
|
|
<g class="graph-node node-float-5" data-user="19" onclick="selectNode(this, 19)">
|
|
<circle cx="225" cy="140" r="22" fill="#FFFFFF" stroke="#FF9AA8" stroke-width="2.5"></circle>
|
|
<circle cx="225" cy="140" r="17" fill="#FFB8C2"></circle>
|
|
<text x="225" y="144" text-anchor="middle" font-size="11" fill="#D64A60" font-weight="700">月</text>
|
|
</g>
|
|
</g>
|
|
|
|
<!-- 中心节点 - 我 -->
|
|
<g class="graph-center" onclick="selectCenter()">
|
|
<!-- 外层光晕 -->
|
|
<circle class="graph-center-glow" cx="171.5" cy="160" r="45" fill="url(#centerGlow)"></circle>
|
|
<!-- 头像外环 -->
|
|
<circle cx="171.5" cy="160" r="30" fill="#FFFFFF" stroke="url(#primaryGrad)" stroke-width="3"></circle>
|
|
<!-- 头像内部 -->
|
|
<circle cx="171.5" cy="160" r="22" fill="url(#primaryGrad)" opacity="0.15"></circle>
|
|
<!-- 我字 -->
|
|
<text x="171.5" y="165" text-anchor="middle" font-size="16" fill="#26C2BB" font-weight="800">我</text>
|
|
<!-- 顶部高光 -->
|
|
<ellipse cx="171.5" cy="153" rx="8" ry="2.5" fill="rgba(255,255,255,0.4)"></ellipse>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 亲密好友 -->
|
|
<div class="section-header">
|
|
<span class="section-title">亲密好友</span>
|
|
<span class="section-more" onclick="viewMore('close')">查看全部 ›</span>
|
|
</div>
|
|
<div class="close-friends">
|
|
<div class="friend-avatar-item" onclick="selectNodeByUser(16)">
|
|
<div class="friend-avatar" style="background: linear-gradient(135deg, #FFC89A, #FF9F45);">小</div>
|
|
<div class="friend-name">小雨同学</div>
|
|
|
|
</div>
|
|
<div class="friend-avatar-item" onclick="selectNodeByUser(17)">
|
|
<div class="friend-avatar" style="background: linear-gradient(135deg, #FFC89A, #FF9F45);">阿</div>
|
|
<div class="friend-name">阿杰学长</div>
|
|
|
|
</div>
|
|
<div class="friend-avatar-item" onclick="selectNodeByUser(18)">
|
|
<div class="friend-avatar" style="background: linear-gradient(135deg, #FF9AA8, #F5677B);">星</div>
|
|
<div class="friend-name">星辰大海</div>
|
|
|
|
</div>
|
|
<div class="friend-avatar-item" onclick="selectNodeByUser(19)">
|
|
<div class="friend-avatar" style="background: linear-gradient(135deg, #FF9AA8, #F5677B);">月</div>
|
|
<div class="friend-name">月牙弯弯</div>
|
|
|
|
</div>
|
|
<div class="friend-avatar-item" onclick="selectNodeByUser(12)">
|
|
<div class="friend-avatar" style="background: linear-gradient(135deg, #8ED9B0, #52C41A);">琳</div>
|
|
<div class="friend-name">黄依琳</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 推荐认识 -->
|
|
<div class="section-header">
|
|
<span class="section-title">推荐认识</span>
|
|
<span class="section-more" onclick="viewMore('recommend')">换一批</span>
|
|
</div>
|
|
<div class="recommend-list">
|
|
<div class="recommend-item">
|
|
<div class="recommend-avatar" style="background: linear-gradient(135deg, #7EB8E8, #4A90D9);">雨</div>
|
|
<div class="recommend-info">
|
|
<div class="recommend-name-row">
|
|
<span class="recommend-name">林雨晴</span>
|
|
|
|
</div>
|
|
<div class="recommend-desc">北京大学 · 大二 · 5位共同好友</div>
|
|
<div class="recommend-tags">
|
|
<span class="rec-tag school">同校</span>
|
|
<span class="rec-tag interest">兴趣契合</span>
|
|
</div>
|
|
</div>
|
|
<button class="btn-add" onclick="addFriend(1)">添加</button>
|
|
</div>
|
|
<div class="recommend-item">
|
|
<div class="recommend-avatar" style="background: linear-gradient(135deg, #C4A8F0, #9B7AD6);">明</div>
|
|
<div class="recommend-info">
|
|
<div class="recommend-name-row">
|
|
<span class="recommend-name">刘明轩</span>
|
|
|
|
</div>
|
|
<div class="recommend-desc">清华大学 · 大三 · 8位共同好友</div>
|
|
<div class="recommend-tags">
|
|
<span class="rec-tag school">同校</span>
|
|
<span class="rec-tag major">同专业</span>
|
|
<span class="rec-tag interest">兴趣契合</span>
|
|
</div>
|
|
</div>
|
|
<button class="btn-add" onclick="addFriend(7)">添加</button>
|
|
</div>
|
|
<div class="recommend-item">
|
|
<div class="recommend-avatar" style="background: linear-gradient(135deg, #8ED9B0, #52C41A);">博</div>
|
|
<div class="recommend-info">
|
|
<div class="recommend-name-row">
|
|
<span class="recommend-name">朱文博</span>
|
|
|
|
</div>
|
|
<div class="recommend-desc">清华大学 · 大四 · 3位共同好友</div>
|
|
<div class="recommend-tags">
|
|
<span class="rec-tag hometown">同乡</span>
|
|
<span class="rec-tag school">同校</span>
|
|
<span class="rec-tag major">同专业</span>
|
|
</div>
|
|
</div>
|
|
<button class="btn-add" onclick="addFriend(15)">添加</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 底部选中用户卡片 -->
|
|
|
|
|
|
<!-- 底部Tab导航 -->
|
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
// 用户数据
|
|
const users = {
|
|
1: { name: '林雨晴', avatar: '雨', match: 88, school: '北京大学', grade: '大二', tags: ['school', 'interest'], color: '#7EB8E8', colorDark: '#4A90D9' },
|
|
2: { name: '陈杰', avatar: '杰', match: 75, school: '清华大学', grade: '大四', tags: ['school', 'major'], color: '#7EB8E8', colorDark: '#4A90D9' },
|
|
3: { name: '王思思', avatar: '思', match: 82, school: '清华大学', grade: '大三', tags: ['school', 'hometown'], color: '#7EB8E8', colorDark: '#4A90D9' },
|
|
4: { name: '张美玲', avatar: '美', match: 78, school: '北京师范大学', grade: '大一', tags: ['hometown', 'interest'], color: '#7EB8E8', colorDark: '#4A90D9' },
|
|
5: { name: '李大伟', avatar: '伟', match: 70, school: '清华大学', grade: '研一', tags: ['school', 'active'], color: '#7EB8E8', colorDark: '#4A90D9' },
|
|
6: { name: '赵雨婷', avatar: '婷', match: 85, school: '北京大学', grade: '大三', tags: ['school', 'interest', 'active'], color: '#7EB8E8', colorDark: '#4A90D9' },
|
|
7: { name: '刘明轩', avatar: '明', match: 92, school: '清华大学', grade: '大三', tags: ['school', 'major', 'interest'], color: '#C4A8F0', colorDark: '#9B7AD6' },
|
|
8: { name: '吴华', avatar: '华', match: 86, school: '清华大学', grade: '大二', tags: ['school', 'major', 'hometown'], color: '#C4A8F0', colorDark: '#9B7AD6' },
|
|
9: { name: '孙磊', avatar: '磊', match: 79, school: '清华大学', grade: '大四', tags: ['school', 'major'], color: '#C4A8F0', colorDark: '#9B7AD6' },
|
|
10: { name: '周鹏飞', avatar: '鹏', match: 73, school: '清华大学', grade: '研二', tags: ['major', 'active'], color: '#C4A8F0', colorDark: '#9B7AD6' },
|
|
11: { name: '郑欣悦', avatar: '悦', match: 88, school: '北京大学', grade: '大二', tags: ['major', 'interest'], color: '#C4A8F0', colorDark: '#9B7AD6' },
|
|
12: { name: '黄依琳', avatar: '琳', match: 90, school: '清华大学', grade: '大三', tags: ['school', 'hometown', 'interest'], color: '#8ED9B0', colorDark: '#52C41A' },
|
|
13: { name: '徐浩宇', avatar: '浩', match: 85, school: '清华大学', grade: '大二', tags: ['hometown', 'major'], color: '#8ED9B0', colorDark: '#52C41A' },
|
|
14: { name: '杨静雯', avatar: '雯', match: 87, school: '北京师范大学', grade: '大三', tags: ['hometown', 'interest', 'active'], color: '#8ED9B0', colorDark: '#52C41A' },
|
|
15: { name: '朱文博', avatar: '博', match: 80, school: '清华大学', grade: '大四', tags: ['hometown', 'school', 'major'], color: '#8ED9B0', colorDark: '#52C41A' },
|
|
16: { name: '小雨同学', avatar: '小', match: 95, school: '清华大学', grade: '大三', tags: ['school', 'major', 'interest'], color: '#FFC89A', colorDark: '#FF9F45' },
|
|
17: { name: '阿杰学长', avatar: '阿', match: 91, school: '清华大学', grade: '大四', tags: ['school', 'major', 'hometown'], color: '#FFC89A', colorDark: '#FF9F45' },
|
|
18: { name: '星辰大海', avatar: '星', match: 93, school: '清华大学', grade: '研一', tags: ['school', 'interest', 'active'], color: '#FF9AA8', colorDark: '#F5677B' },
|
|
19: { name: '月牙弯弯', avatar: '月', match: 89, school: '北京大学', grade: '大二', tags: ['interest', 'active', 'hometown'], color: '#FF9AA8', colorDark: '#F5677B' }
|
|
};
|
|
|
|
const tagLabels = {
|
|
school: '同校',
|
|
major: '同专业',
|
|
hometown: '同乡',
|
|
interest: '兴趣契合',
|
|
active: '活跃用户'
|
|
};
|
|
|
|
let currentSelectedUser = 16;
|
|
|
|
// 返回按钮
|
|
function goBack() {
|
|
window.location.href = 'friends-list.html';
|
|
}
|
|
|
|
// 分享按钮
|
|
function handleShare() {
|
|
console.log('分享社交图谱');
|
|
if (navigator.share) {
|
|
navigator.share({
|
|
title: '我的社交图谱',
|
|
text: '来青核看看我的社交网络吧!',
|
|
});
|
|
} else {
|
|
alert('分享功能已触发');
|
|
}
|
|
}
|
|
|
|
// 选择节点
|
|
function selectNode(element, userId) {
|
|
// 移除所有选中状态
|
|
document.querySelectorAll('.graph-node').forEach(n => {
|
|
n.classList.remove('selected');
|
|
});
|
|
// 添加当前选中
|
|
element.classList.add('selected');
|
|
|
|
// 更新底部卡片
|
|
updateSelectedCard(userId);
|
|
currentSelectedUser = userId;
|
|
|
|
// 脉冲效果
|
|
const circle = element.querySelector('circle');
|
|
if (circle) {
|
|
const originalR = circle.getAttribute('r');
|
|
circle.setAttribute('r', parseFloat(originalR) * 1.15);
|
|
setTimeout(() => {
|
|
circle.setAttribute('r', originalR);
|
|
}, 200);
|
|
}
|
|
}
|
|
|
|
// 点击中心节点
|
|
function selectCenter() {
|
|
console.log('点击中心 - 我');
|
|
const centerGlow = document.querySelector('.graph-center-glow');
|
|
if (centerGlow) {
|
|
centerGlow.style.animation = 'none';
|
|
centerGlow.offsetHeight;
|
|
centerGlow.style.animation = 'breathe 0.5s ease-in-out 2';
|
|
setTimeout(() => {
|
|
centerGlow.style.animation = 'breathe 3s ease-in-out infinite';
|
|
}, 1000);
|
|
}
|
|
}
|
|
|
|
// 更新选中用户卡片
|
|
function updateSelectedCard(userId) {
|
|
const user = users[userId];
|
|
if (!user) return;
|
|
|
|
const card = document.getElementById('selectedUserCard');
|
|
const avatar = document.getElementById('selectedAvatar');
|
|
const name = document.getElementById('selectedName');
|
|
const match = document.getElementById('selectedMatch');
|
|
const school = document.getElementById('selectedSchool');
|
|
const tags = document.getElementById('selectedTags');
|
|
|
|
// 更新头像
|
|
avatar.textContent = user.avatar;
|
|
avatar.style.background = `linear-gradient(135deg, ${user.color}, ${user.colorDark})`;
|
|
|
|
// 更新姓名
|
|
name.textContent = user.name;
|
|
|
|
// 更新匹配度
|
|
match.textContent = user.match + '%匹配';
|
|
|
|
// 更新学校年级
|
|
school.textContent = user.school + ' · ' + user.grade;
|
|
|
|
// 更新标签
|
|
tags.innerHTML = '';
|
|
user.tags.forEach(tag => {
|
|
const span = document.createElement('span');
|
|
span.className = 'relation-tag ' + tag;
|
|
span.textContent = tagLabels[tag];
|
|
tags.appendChild(span);
|
|
});
|
|
|
|
// 卡片轻微弹入效果
|
|
card.style.transform = 'translateY(4px)';
|
|
card.style.opacity = '0.8';
|
|
setTimeout(() => {
|
|
card.style.transform = 'translateY(0)';
|
|
card.style.opacity = '1';
|
|
}, 50);
|
|
}
|
|
|
|
// 打招呼
|
|
function sendGreeting() {
|
|
const user = users[currentSelectedUser];
|
|
if (user) {
|
|
alert('已向 ' + user.name + ' 发送打招呼!');
|
|
}
|
|
}
|
|
|
|
// 查看主页
|
|
function viewProfile() {
|
|
window.location.href = 'user-profile.html?id=' + currentSelectedUser;
|
|
}
|
|
|
|
// 通过用户ID选中节点
|
|
function selectNodeByUser(userId) {
|
|
const node = document.querySelector(`.graph-node[data-user="${userId}"]`);
|
|
if (node) {
|
|
selectNode(node, userId);
|
|
}
|
|
}
|
|
|
|
// 查看更多
|
|
function viewMore(type) {
|
|
if (type === 'close') {
|
|
alert('查看全部亲密好友');
|
|
} else {
|
|
alert('换一批推荐');
|
|
}
|
|
}
|
|
|
|
// 添加好友
|
|
function addFriend(userId) {
|
|
const user = users[userId];
|
|
if (user) {
|
|
alert('已向 ' + user.name + ' 发送好友申请!');
|
|
}
|
|
}
|
|
|
|
// 底部导航切换
|
|
function switchTab(tab) {
|
|
const navItems = document.querySelectorAll('.tab-item');
|
|
navItems.forEach(function(item) {
|
|
item.classList.remove('active');
|
|
});
|
|
|
|
const tabMap = {
|
|
'home': 0,
|
|
'friends': 1,
|
|
'dynamic': 2,
|
|
'message': 3,
|
|
'profile': 4
|
|
};
|
|
|
|
if (tabMap[tab] !== undefined && navItems[tabMap[tab]]) {
|
|
navItems[tabMap[tab]].classList.add('active');
|
|
}
|
|
}
|
|
|
|
// 页面初始化
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// 默认选中第一个亲密层节点
|
|
const firstNode = document.querySelector('.graph-layer-close .graph-node');
|
|
if (firstNode) {
|
|
firstNode.classList.add('selected');
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|