Compare commits

...

14 Commits

Author SHA1 Message Date
Tim
2ccdc21568 fix: markdown渲染的分割线有点深 #767 2025-09-01 19:47:24 +08:00
tim
ff63d232a9 Merge branch 'main' of github.com:nagisa77/OpenIsle 2025-09-01 18:50:09 +08:00
tim
32a624e62d fix: 登录样式调整 2025-09-01 18:49:33 +08:00
Tim
5af0c9dee0 Merge pull request #822 from nagisa77/codex/fix-channel-ui-scroll-behavior
fix: scroll to bottom when entering channel
2025-09-01 18:19:17 +08:00
Tim
edaafdd000 fix: scroll channel to bottom on activation 2025-09-01 18:18:58 +08:00
Tim
24838ab714 Merge pull request #819 from sivdead/main
指定Node.js最低版本为20.0.0
2025-09-01 18:16:24 +08:00
Tim
56a80a184b Merge pull request #821 from smallclover/main
修改部署教程
2025-09-01 18:15:49 +08:00
sivdead
ed24ed174b fix: 还原package-lock.json 2025-09-01 17:56:27 +08:00
夢夢の幻想郷
3080acb6e4 Merge branch 'nagisa77:main' into main 2025-09-01 17:52:24 +08:00
wangshun
1856eb191b 修改部署教程
1.本地部署前后端时,如果是时https后端会无法解析请求
2.使用第三方登录时,callback路径需要和注册的路径一致
2025-09-01 17:50:19 +08:00
Tim
0c2a50d620 Merge pull request #820 from CH-122/feat/message-setting
feat: 增加通知设置的权限控制,只有管理员可以显示特定通知类型
2025-09-01 17:40:09 +08:00
CH-122
7562de11a5 feat: 增加通知设置的权限控制,只有管理员可以显示特定通知类型 2025-09-01 17:03:13 +08:00
sivdead
aaacf4efb1 chore(frontend): 指定Node.js最低版本为20.0.0 2025-09-01 15:53:05 +08:00
Tim
1f30cdfe85 Merge pull request #818 from nagisa77/codex/fix-backend-compilation-issue
Fix CommentServiceTest compilation by mocking PointService
2025-09-01 15:35:02 +08:00
9 changed files with 57 additions and 24 deletions

View File

@@ -76,11 +76,13 @@ cp .env.staging.example .env
```yaml
; 本地部署后端
NUXT_PUBLIC_API_BASE_URL=https://127.0.0.1:8081
NUXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8081
; 预发环境后端
; NUXT_PUBLIC_API_BASE_URL=https://staging.open-isle.com
; 生产环境后端
; NUXT_PUBLIC_API_BASE_URL=https://www.open-isle.com
; 开发环境
NUXT_PUBLIC_WEBSITE_BASE_URL=localhost:3000
```
2. 依赖预发环境后台环境

View File

@@ -35,6 +35,12 @@
--article-info-background-color: #f0f0f0;
--activity-card-background-color: #fafafa;
--poll-option-button-background-color: rgb(218, 218, 218);
--telegram-bg: #caedff74;
--telegram-bg-hover: #67a2c088;
--twitter-bg: rgb(68, 68, 68);
--twitter-bg-hover: rgb(91, 91, 91);
--discord-bg: #5865f258;
--discord-bg-hover: #5865f2b1;
}
[data-theme='dark'] {
@@ -239,6 +245,14 @@ body {
overflow-x: auto; /* 小屏可横向滚动 */
}
.info-content-text hr {
border: none;
border-top: 1px solid var(--normal-border-color);
padding: 0;
height: 1px;
width: 100%;
}
.info-content-text thead th {
background-color: var(--primary-color);
color: #fff;

View File

@@ -1 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Discord</title><path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 512"><path fill="#5865F2" d="M105 0h302c57.928.155 104.845 47.072 105 104.996V407c-.155 57.926-47.072 104.844-104.996 104.998L105 512C47.074 511.844.156 464.926.002 407.003L0 105C.156 47.072 47.074.155 104.997 0H105z"/><g data-name="图层 2"><g data-name="Discord Logos"><path fill="#fff" fill-rule="nonzero" d="M368.896 153.381a269.506 269.506 0 00-67.118-20.637 186.88 186.88 0 00-8.57 17.475 250.337 250.337 0 00-37.247-2.8c-12.447 0-24.955.946-37.25 2.776-2.511-5.927-5.427-11.804-8.592-17.454a271.73 271.73 0 00-67.133 20.681c-42.479 62.841-53.991 124.112-48.235 184.513a270.622 270.622 0 0082.308 41.312c6.637-8.959 12.582-18.497 17.63-28.423a173.808 173.808 0 01-27.772-13.253c2.328-1.688 4.605-3.427 6.805-5.117 25.726 12.083 53.836 18.385 82.277 18.385 28.442 0 56.551-6.302 82.279-18.387 2.226 1.817 4.503 3.557 6.805 5.117a175.002 175.002 0 01-27.823 13.289 197.847 197.847 0 0017.631 28.4 269.513 269.513 0 0082.363-41.305l-.007.007c6.754-70.045-11.538-130.753-48.351-184.579zM201.968 300.789c-16.04 0-29.292-14.557-29.292-32.465s12.791-32.592 29.241-32.592 29.599 14.684 29.318 32.592c-.282 17.908-12.919 32.465-29.267 32.465zm108.062 0c-16.066 0-29.267-14.557-29.267-32.465s12.791-32.592 29.267-32.592c16.475 0 29.522 14.684 29.241 32.592-.281 17.908-12.894 32.465-29.241 32.465z" data-name="Discord Logo - Large - White"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,4 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path fill="#2AABEE" d="M12 0C5.372 0 0 5.372 0 12s5.372 12 12 12 12-5.372 12-12S18.628 0 12 0z"/>
<path fill="#fff" d="M17.565 7.06L15.7 17.05c-.14.706-.51.88-1.033.548l-2.861-2.108-1.382 1.332c-.153.153-.282.282-.575.282l.205-2.912 5.303-4.788c.231-.205-.05-.32-.36-.116L8.9 11.27l-3.14-.98c-.682-.213-.696-.682.143-1.007l11.18-4.307c.511-.186.958.116.783.914z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><defs><clipPath id="A"><path d="M15.903 131.998c0-65.17 52.83-118 118-118s118 52.83 118 118-52.83 118-118 118-118-52.83-118-118"/></clipPath><linearGradient x1="133.903" y1="13.999" x2="133.903" y2="249.999" gradientUnits="userSpaceOnUse" spreadMethod="pad" id="B"><stop offset="0" stop-color="#1d93d2"/><stop offset="1" stop-color="#38b0e3"/></linearGradient><clipPath id="C"><path d="M0 265.9h266.987V0H0z"/></clipPath><clipPath id="D"><path d="M0 265.9h266.987V0H0z"/></clipPath><clipPath id="E"><path d="M0 265.9h266.987V0H0z"/></clipPath></defs><g transform="matrix(.271187 0 0 -.271187 -4.312678 67.796339)"><path d="M15.903 131.998c0-65.17 52.83-118 118-118s118 52.83 118 118-52.83 118-118 118-118-52.83-118-118" fill="url(#B)" clip-path="url(#A)"/><g clip-path="url(#C)"><path d="M95.778 123.374l14-38.75S111.528 81 113.403 81s29.75 29 29.75 29l31 59.875-77.875-36.5z" fill="#c8daea"/></g><g clip-path="url(#D)"><path d="M114.34 113.436l-2.688-28.562s-1.125-8.75 7.625 0 17.125 15.5 17.125 15.5" fill="#a9c6d8"/></g><g clip-path="url(#E)"><path d="M96.03 121.99l-28.795 9.383s-3.437 1.395-2.333 4.562c.228.653.687 1.208 2.062 2.167 6.382 4.447 118.104 44.604 118.104 44.604s3.155 1.062 5.02.356c.852-.323 1.396-.688 1.854-2.02.167-.485.263-1.516.25-2.542-.01-.74-.1-1.425-.166-2.5-.68-10.98-21.04-92.918-21.04-92.918s-1.218-4.795-5.583-4.958c-1.592-.06-3.524.263-5.834 2.25-8.565 7.368-38.172 27.265-44.713 31.64-.37.246-.474.567-.537.88-.092.46.4 1.034.4 1.034s51.552 45.825 52.924 50.633c.106.373-.293.557-.834.396-3.424-1.26-62.78-38.74-69.33-42.88-.383-.242-1.457-.086-1.457-.086" fill="#fff"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 438 B

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,4 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<title>Twitter icon</title>
<path d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.949.555-2.005.959-3.127 1.184-.897-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124-4.083-.205-7.697-2.159-10.126-5.134-.422.722-.666 1.561-.666 2.475 0 1.709.87 3.214 2.188 4.096-.807-.026-1.566-.248-2.229-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.376 4.6 3.416-1.68 1.318-3.808 2.105-6.102 2.105-.39 0-.779-.023-1.17-.069 2.189 1.394 4.768 2.209 7.548 2.209 9.051 0 14.001-7.496 14.001-13.986 0-.21 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-480 -466.815 2160 2160"><circle fill="#444" cx="600" cy="613.185" r="1080"/><path fill="#fff" d="M306.615 79.694H144.011L892.476 1150.3h162.604ZM0 0h357.328l309.814 450.883L1055.03 0h105.86L714.15 519.295 1200 1226.37H842.672L515.493 750.215 105.866 1226.37H0l468.485-544.568Z"/></svg>

Before

Width:  |  Height:  |  Size: 764 B

After

Width:  |  Height:  |  Size: 335 B

View File

@@ -7,8 +7,13 @@
:class="provider.name"
@click="provider.action"
>
<img class="third-party-button-icon" :src="provider.icon" :alt="provider.alt" />
<div class="third-party-button-text">
<img
class="third-party-button-icon"
:class="provider.name"
:src="provider.icon"
:alt="provider.alt"
/>
<div class="third-party-button-text" :class="provider.name">
{{ provider.label }}
</div>
</div>
@@ -68,7 +73,7 @@ const providers = computed(() => [
icon: twitterIcon,
action: () => twitterAuthorize(props.inviteToken),
alt: 'Twitter Logo',
label: `Twitter ${actionText.value}`,
label: `X ${actionText.value}`,
},
{
name: 'telegram',
@@ -88,7 +93,7 @@ const providers = computed(() => [
align-items: center;
justify-content: center;
width: 30%;
gap: 20px;
gap: 11px;
}
.third-party-button {
@@ -96,11 +101,11 @@ const providers = computed(() => [
flex-direction: row;
align-items: center;
justify-content: center;
padding: 10px 20px;
padding: 7px 20px;
min-width: 150px;
background-color: var(--login-background-color);
border: 1px solid var(--normal-border-color);
border-radius: 10px;
border-radius: 20px;
cursor: pointer;
gap: 10px;
}
@@ -118,6 +123,10 @@ const providers = computed(() => [
font-size: 16px;
}
.third-party-button-text.twitter {
color: rgb(182, 182, 182);
}
/* Provider specific classes for customization */
.third-party-button.google {
background-color: var(--google-bg, var(--login-background-color));

View File

@@ -2,6 +2,9 @@
"name": "frontend_nuxt",
"private": true,
"type": "module",
"engines": {
"node": ">=20.0.0"
},
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",

View File

@@ -371,11 +371,12 @@ watch(isConnected, (newValue) => {
})
onActivated(async () => {
// 返回页面时:刷新数据与已读,不做强制滚动,保持用户当前位置
// 返回页面时:刷新数据与已读,并滚动到底部
if (currentUser.value) {
await fetchMessages(0)
await markConversationAsRead()
await nextTick()
scrollToBottomSmooth()
updateNearBottom()
if (!isConnected.value) {
const token = getToken()

View File

@@ -14,13 +14,15 @@
<div class="message-control-container">
<div class="message-control-title">通知设置</div>
<div class="message-control-item-container">
<div v-for="pref in notificationPrefs" :key="pref.type" class="message-control-item">
<div class="message-control-item-label">{{ formatType(pref.type) }}</div>
<BaseSwitch
:model-value="pref.enabled"
@update:modelValue="(val) => togglePref(pref, val)"
/>
</div>
<template v-for="pref in notificationPrefs">
<div v-if="canShowNotification(pref.type)" :key="pref.type" class="message-control-item">
<div class="message-control-item-label">{{ formatType(pref.type) }}</div>
<BaseSwitch
:model-value="pref.enabled"
@update:modelValue="(val) => togglePref(pref, val)"
/>
</div>
</template>
</div>
</div>
<div class="message-control-container">
@@ -753,6 +755,14 @@ const formatType = (t) => {
}
}
const isAdmin = computed(() => authState.role === 'ADMIN')
const needAdminSet = new Set(['POST_REVIEW_REQUEST','REGISTER_REQUEST', 'POINT_REDEEM', 'ACTIVITY_REDEEM'])
const canShowNotification = (type) => {
return !needAdminSet.has(type) || isAdmin.value
}
onActivated(async () => {
page.value = 0
await fetchNotifications({ page: 0, size: pageSize, unread: selectedTab.value === 'unread' })