Skip to content

Commit 7f3d30c

Browse files
authored
Merge pull request #101 from devlive-community/refactor-nodejs
Refactor nodejs
2 parents 7d972a3 + bce4aec commit 7f3d30c

File tree

5 files changed

+62
-24
lines changed

5 files changed

+62
-24
lines changed

backend/routes/book.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ router.get('/writer/:username/:book_slug/:doc_slug?', ensureAuthenticated, async
188188
})
189189
}))
190190

191-
router.get('/:username', ensureAuthenticated, asyncHandler(async (req, res) => {
191+
router.get('/:username', asyncHandler(async (req, res) => {
192192
const user = await User.findByUsername(req.params.username)
193193
if (!user) {
194194
return res.status(404).render('pages/error/global', {
@@ -203,7 +203,7 @@ router.get('/:username', ensureAuthenticated, asyncHandler(async (req, res) => {
203203
const paginationParams = PaginationHelper.parseParams(req.query, { defaultLimit: 10 })
204204

205205
const searchParams = { username: req.params.username }
206-
if (user.id !== req.user.id) {
206+
if (user.id !== req.user?.id) {
207207
searchParams.is_public = 1
208208
searchParams.status = 'published'
209209
}

frontend/views/components/alert.ejs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@
55
* @param {String} message - 消息内容
66
* @param {String} title - 可选的标题
77
* @param {Boolean} dismissible - 是否可关闭,默认false
8+
* @param {Number} autoClose - 自动关闭时间(毫秒),0表示不自动关闭,默认0
89
* @param {String} className - 额外的CSS类,可选
910
*/
1011
1112
const alertType = typeof type !== 'undefined' ? type : 'info';
1213
const alertMessage = typeof message !== 'undefined' ? message : '';
1314
const alertTitle = typeof title !== 'undefined' ? title : '';
1415
const isDismissible = typeof dismissible !== 'undefined' ? dismissible : false;
16+
const autoCloseTime = typeof autoClose !== 'undefined' ? parseInt(autoClose) : 0;
1517
const extraClass = typeof className !== 'undefined' ? className : '';
1618
17-
// 根据类型设置样式
19+
const alertId = 'alert-' + Math.random().toString(36).substr(2, 9);
20+
1821
let alertClass = '';
1922
let iconClass = '';
2023
@@ -40,20 +43,67 @@ switch(alertType) {
4043
%>
4144

4245
<% if (alertMessage) { %>
43-
<div class="border rounded-lg p-2 my-2 <%= alertClass %> <%= extraClass %>" <% if (isDismissible) { %>id="alert-<%= Math.random().toString(36).substr(2, 9) %>"<% } %>>
46+
<div class="border rounded-lg p-2 my-2 <%= alertClass %> <%= extraClass %> transition-all duration-300"
47+
id="<%= alertId %>"
48+
<% if (autoCloseTime > 0) { %>data-auto-close="<%= autoCloseTime %>"<% } %>>
4449
<div class="flex">
4550
<i class="<%= iconClass %> mr-3 mt-1"></i>
4651
<div class="flex-1">
4752
<% if (alertTitle) { %>
4853
<div class="font-medium mb-1"><%= alertTitle %></div>
4954
<% } %>
5055
<div class="text-sm"><%= alertMessage %></div>
56+
57+
<% if (autoCloseTime > 0) { %>
58+
<div class="mt-2 h-1 bg-gray-200 rounded-full overflow-hidden">
59+
<div class="h-full bg-current opacity-30 rounded-full transition-all ease-linear"
60+
id="<%= alertId %>-progress"
61+
style="width: 100%; transition-duration: <%= autoCloseTime %>ms; transform-origin: left;"></div>
62+
</div>
63+
<% } %>
5164
</div>
52-
<% if (isDismissible) { %>
53-
<button type="button" class="ml-3 text-gray-400 hover:text-gray-600" onclick="this.parentElement.parentElement.style.display='none'">
65+
66+
<% if (isDismissible || autoCloseTime > 0) { %>
67+
<button type="button"
68+
class="ml-3 text-gray-400 hover:text-gray-600 transition-colors duration-200"
69+
onclick="dismissAlert('<%= alertId %>')">
5470
<i class="fas fa-times"></i>
5571
</button>
5672
<% } %>
5773
</div>
5874
</div>
75+
76+
<script>
77+
(function initializeAlert() {
78+
const alertElement = document.getElementById('<%= alertId %>');
79+
const autoCloseTime = parseInt(alertElement.dataset.autoClose) || 0;
80+
81+
if (autoCloseTime > 0) {
82+
const progressBar = document.getElementById('<%= alertId %>-progress');
83+
84+
if (progressBar) {
85+
progressBar.offsetWidth;
86+
progressBar.style.width = '0%';
87+
}
88+
89+
setTimeout(() => {
90+
dismissAlert('<%= alertId %>');
91+
}, autoCloseTime);
92+
}
93+
})();
94+
95+
function dismissAlert(alertId) {
96+
const alertElement = document.getElementById(alertId);
97+
if (!alertElement) return;
98+
99+
alertElement.style.opacity = '0';
100+
alertElement.style.transform = 'translateY(-10px)';
101+
102+
setTimeout(() => {
103+
if (alertElement.parentNode) {
104+
alertElement.parentNode.removeChild(alertElement);
105+
}
106+
}, 300);
107+
}
108+
</script>
59109
<% } %>

frontend/views/components/modal.ejs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
id="<%= modalId %>Content">
66
<!-- 关闭按钮 -->
77
<button onclick="closeModal('<%= modalId %>')" class="absolute top-3 right-3 text-gray-400 hover:text-gray-600 transition-colors z-10">
8-
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
9-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
10-
</svg>
8+
<i class="fas fa-circle-xmark"></i>
119
</button>
1210

1311
<!-- 模态框内容 -->
@@ -16,7 +14,6 @@
1614
</div>
1715

1816
<script>
19-
// 显示模态框
2017
function showModal(modalId) {
2118
const modal = document.getElementById(modalId)
2219
const content = document.getElementById(modalId + 'Content')
@@ -26,31 +23,22 @@
2623
content.classList.add('scale-100')
2724
}
2825
29-
// 关闭模态框
3026
function closeModal(modalId) {
3127
const modal = document.getElementById(modalId)
3228
const content = document.getElementById(modalId + 'Content')
3329
3430
content.classList.remove('scale-100')
3531
content.classList.add('scale-90')
3632
33+
// 动画计时:等待变换完成后再隐藏
3734
setTimeout(() => {
3835
modal.classList.add('opacity-0', 'invisible')
3936
}, 200)
4037
}
4138
42-
// 点击背景关闭
43-
document.addEventListener('click', function (e) {
44-
if (e.target.id && e.target.id.includes('Modal') && !e.target.id.includes('Content')) {
45-
const modalId = e.target.id
46-
closeModal(modalId)
47-
}
48-
})
49-
50-
// ESC 键关闭所有模态框
39+
// ESC 键处理程序:关闭所有可见模态
5140
document.addEventListener('keydown', function (e) {
5241
if (e.key === 'Escape') {
53-
// 关闭所有打开的模态框
5442
const modals = document.querySelectorAll('[id$="Modal"]')
5543
modals.forEach(modal => {
5644
if (!modal.classList.contains('invisible')) {

frontend/views/layouts/book/nav.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</div>
1010
<div class="bg-gray-200 h-px my-4"></div>
1111
<nav class="space-y-2">
12-
<%- include('../../components/nav', { href: `/book/${user.username}`, text: `${user.id === authUser.id ? '我的书籍' : '他的书籍'}`, icon: 'fas fa-book', className: 'w-full py-3' }) %>
12+
<%- include('../../components/nav', { href: `/book/${user.username}`, text: `${user.id === authUser?.id ? '我的书籍' : '他的书籍'}`, icon: 'fas fa-book', className: 'w-full py-3' }) %>
1313
</nav>
1414
</div>
1515
</div>

frontend/views/pages/document/writer.ejs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
</h1>
2222
</div>
2323

24-
<%- include('../../components/alert', { type: 'error', message: error }) %>
25-
<%- include('../../components/alert', { type: 'success', message: success }) %>
24+
<%- include('../../components/alert', { type: 'error', message: error, autoClose: 2000 }) %>
25+
<%- include('../../components/alert', { type: 'success', message: success, autoClose: 2000 }) %>
2626

2727
<!-- 右侧操作 -->
2828
<div class="flex items-center space-x-4">

0 commit comments

Comments
 (0)