Files
mce/templates/MetaLab-2026/html/space/index.html
Victor_Jay bab8e47d63 fix: 修复关注按钮 CSRF 403 + 缺少样式 + IncrCount SQL 错误
- 修复 CSRF 403:移除 space/index.html 中手动设置 X-CSRF-Token 头(与 common.js 自动注入冲突导致 token 重复)
- 修复按钮无样式:header.html 新增 ExtraCSS2 支持,space 页面加载 follow.css
- 修复 IncrCount SQL 错误:follow_repo.go 中 users 表列名修正 id → uid
2026-06-01 20:16:51 +08:00

170 lines
5.8 KiB
HTML

{{template "layout/header.html" .}}
<body>
{{template "layout/nav.html" .}}
{{if .Error}}
<div class="space-error">
<div class="container">
<h1>{{.Error}}</h1>
<a href="/" class="btn btn-primary">返回首页</a>
</div>
</div>
{{else}}
<div class="space-page">
<!-- 用户信息头部 -->
<div class="space-header">
<div class="container space-header-inner">
<div class="space-avatar">
{{if .SpaceUser.Avatar}}
<img src="{{.SpaceUser.Avatar}}" alt="{{.SpaceUser.Username}}">
{{else}}
<div class="space-avatar-placeholder">{{slice .SpaceUser.Username 0 1}}</div>
{{end}}
</div>
<div class="space-info">
<h1 class="space-username">{{.SpaceUser.Username}}</h1>
<p class="space-bio">{{if eq .SpaceUser.Status "banned"}}ⓘ 该账号已被封禁{{else if .SpaceUser.Bio}}{{.SpaceUser.Bio}}{{else}}&nbsp;{{end}}</p>
<div class="space-meta">
<span class="space-uid">UID: {{.SpaceUser.ID}}</span>
<span class="space-divider">·</span>
<span class="space-joined">加入于 {{.SpaceUser.CreatedAt.Format "2006-01-02"}}</span>
</div>
<div class="follow-links">
<a href="/space/{{.SpaceUser.ID}}/following"><strong>{{.SpaceUser.FollowingCount}}</strong> 关注</a>
<a href="/space/{{.SpaceUser.ID}}/followers"><strong>{{.SpaceUser.FollowersCount}}</strong> 粉丝</a>
</div>
{{if not .IsOwnSpace}}
<div class="follow-btn-wrapper">
<button id="followBtn" class="follow-btn" data-uid="{{.SpaceUser.ID}}">关注</button>
</div>
{{end}}
</div>
</div>
</div>
<!-- 内容区域 -->
<div class="container space-content">
<!-- 统计栏 -->
<div class="space-stats">
<div class="space-stat-item">
<span class="space-stat-num">{{.Total}}</span>
<span class="space-stat-label">稿件</span>
</div>
</div>
<!-- 稿件列表 -->
<div class="space-section">
<h2 class="space-section-title">稿件</h2>
{{if eq (len .Posts) 0}}
<div class="empty-state">暂无稿件</div>
{{else}}
<div class="space-posts-list">
{{range .Posts}}
<article class="space-post-card">
<div class="space-post-main">
<h3 class="space-post-title">
<a href="/posts/{{.ID}}">{{.Title}}</a>
</h3>
<p class="space-post-excerpt">{{if .Excerpt}}{{.Excerpt}}{{else}}{{printf "%.200s" .Body}}{{end}}</p>
<div class="space-post-meta">
<span class="space-post-status">已发布</span>
<span class="space-post-time">{{.CreatedAt.Format "2006-01-02"}}</span>
</div>
</div>
</article>
{{end}}
</div>
{{end}}
<!-- 分页 -->
{{if gt .TotalPages 1}}
<div class="pagination">
{{if gt .Page 1}}
<a href="?page={{.PrevPage}}" class="page-link">上一页</a>
{{end}}
<span class="page-info">第 {{.Page}} / {{.TotalPages}} 页 (共 {{.Total}} 条)</span>
{{if lt .Page .TotalPages}}
<a href="?page={{.NextPage}}" class="page-link">下一页</a>
{{end}}
</div>
{{end}}
</div>
</div>
</div>
{{end}}
{{template "layout/footer.html" .}}
<script src="/static/js/common.js?v={{assetV "/static/js/common.js"}}"></script>
{{if not .IsOwnSpace}}
<script>
(function() {
var followBtn = document.getElementById('followBtn');
if (!followBtn) return;
var targetUid = followBtn.getAttribute('data-uid');
// 四个按钮状态文案
var labels = {
none: '关注',
following: '已关注',
followBack: '回关',
mutual: '已互粉'
};
var classes = {
none: '',
following: 'following',
followBack: '',
mutual: 'mutual'
};
function buttonState(status) {
if (status.i_follow && status.they_follow) return 'mutual';
if (status.i_follow) return 'following';
if (status.they_follow) return 'followBack';
return 'none';
}
function updateBtn(status) {
var state = buttonState(status);
followBtn.textContent = labels[state];
followBtn.className = 'follow-btn ' + (classes[state] || '');
}
// 获取初始状态
fetch('/api/users/' + targetUid + '/follow-status')
.then(function(res) { return res.json(); })
.then(function(data) {
if (data && data.success && data.data) {
updateBtn(data.data);
}
});
// 点击切换
followBtn.addEventListener('click', function() {
followBtn.classList.add('waiting');
var xhr = new XMLHttpRequest();
xhr.open('POST', '/api/users/' + targetUid + '/follow', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
followBtn.classList.remove('waiting');
if (xhr.status === 200) {
try {
var resp = JSON.parse(xhr.responseText);
if (resp.data && resp.data.status) {
updateBtn(resp.data.status);
}
} catch(e) {}
}
}
};
xhr.send();
});
})();
</script>
{{end}}
</body>
</html>