feat: 迁移自定义功能至 1.5.9.9 版本
包含音乐源限制、CI 防 OOM 优化、数据库连接池优化、管理端权限及 UI 细节定制等功能
This commit is contained in:
@@ -1,79 +1,64 @@
|
||||
<template>
|
||||
<div class="schedule-item-print" :class="{ 'is-narrow': narrow }">
|
||||
<div class="schedule-item-print">
|
||||
<div class="item-content">
|
||||
<div v-if="settings.showSequence || settings.showCover" class="item-leading">
|
||||
<!-- 序号 -->
|
||||
<div v-if="settings.showSequence" class="sequence-number">
|
||||
{{ schedule.sequence || 1 }}
|
||||
</div>
|
||||
<!-- 序号 -->
|
||||
<div v-if="settings.showSequence" class="sequence-number">
|
||||
{{ schedule.sequence || 1 }}
|
||||
</div>
|
||||
|
||||
<!-- 歌曲封面 -->
|
||||
<div v-if="settings.showCover" class="cover-section">
|
||||
<img
|
||||
v-if="schedule.song.cover"
|
||||
:alt="schedule.song.title"
|
||||
:data-original-src="convertToHttps(schedule.song.cover)"
|
||||
:src="convertToHttps(schedule.song.cover)"
|
||||
class="song-cover"
|
||||
referrerpolicy="no-referrer"
|
||||
@error="handleImageError"
|
||||
>
|
||||
<div class="cover-placeholder" :class="{ show: !schedule.song.cover }">
|
||||
<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
<path d="M12 1v6m0 6v6" />
|
||||
<path d="m21 12-6-3-6 3-6-3" />
|
||||
</svg>
|
||||
</div>
|
||||
<!-- 歌曲封面 -->
|
||||
<div v-if="settings.showCover" class="cover-section aspect-square">
|
||||
<img
|
||||
v-if="schedule.song.cover"
|
||||
:alt="schedule.song.title"
|
||||
:src="convertToHttps(schedule.song.cover)"
|
||||
class="song-cover object-cover"
|
||||
referrerpolicy="no-referrer"
|
||||
@error="handleImageError"
|
||||
>
|
||||
<div class="cover-placeholder object-contain" :class="{ 'show': !schedule.song.cover }">
|
||||
<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
<path d="M12 1v6m0 6v6" />
|
||||
<path d="m21 12-6-3-6 3-6-3" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 歌曲信息 -->
|
||||
<div class="song-info">
|
||||
<div v-if="settings.showTitle" class="song-title">
|
||||
<span class="title-text">{{ schedule.song.title }}</span>
|
||||
{{ schedule.song.title }}
|
||||
<!-- 重播标识 -->
|
||||
<span v-if="schedule.replayRequestId != null" class="replay-badge-print"> {{ locale.replay }} </span>
|
||||
<!-- 跨学期标识 -->
|
||||
<span
|
||||
v-if="
|
||||
settings.currentSemester &&
|
||||
schedule.song.semester &&
|
||||
schedule.song.semester !== settings.currentSemester
|
||||
"
|
||||
class="cross-semester-badge-print"
|
||||
>
|
||||
{{ locale.crossSemester }}
|
||||
</span>
|
||||
<span v-if="schedule.song.replayRequestCount > 0" class="replay-badge-print"> 重播 </span>
|
||||
</div>
|
||||
<div v-if="settings.showArtist" class="song-artist">
|
||||
{{ schedule.song.artist }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="settings.showRequester || settings.showVotes" class="item-trailing">
|
||||
<!-- 投稿人信息(重播歌曲不显示申请人,只显示原投稿人) -->
|
||||
<div v-if="settings.showRequester" class="requester-info">
|
||||
<span class="label">{{ locale.requesterPrefix }}</span>
|
||||
<span class="value">
|
||||
{{ schedule.song.requester }}
|
||||
<span v-if="schedule.song.collaborators && schedule.song.collaborators.length > 0">
|
||||
& {{ schedule.song.collaborators.map((c) => c.displayName || c.name).join(' & ') }}
|
||||
</span>
|
||||
<!-- 投稿人信息(重播歌曲不显示申请人,只显示原投稿人) -->
|
||||
<div v-if="settings.showRequester" class="requester-info">
|
||||
<span class="label">投稿人:</span>
|
||||
<span class="value">
|
||||
{{ schedule.song.requester }}
|
||||
<span v-if="schedule.song.collaborators && schedule.song.collaborators.length > 0">
|
||||
& {{ schedule.song.collaborators.map((c) => c.displayName || c.name).join(' & ') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 人数信息 -->
|
||||
<div v-if="settings.showVotes" class="votes-info">
|
||||
<span v-if="schedule.replayRequestId != null" class="label">{{ locale.replayRequestsPrefix }}</span>
|
||||
<span v-else class="label">{{ locale.popularityPrefix }}</span>
|
||||
<span class="value">{{
|
||||
schedule.replayRequestId != null
|
||||
? locale.replayCount(schedule.song.replayRequestCount)
|
||||
: schedule.song.voteCount || 0
|
||||
}}</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 人数信息 -->
|
||||
<div v-if="settings.showVotes" class="votes-info">
|
||||
<span v-if="schedule.song.replayRequestCount > 0" class="label">申请重播:</span>
|
||||
<span v-else class="label">热度:</span>
|
||||
<span class="value">{{
|
||||
schedule.song.replayRequestCount > 0
|
||||
? schedule.song.replayRequestCount + '人'
|
||||
: schedule.song.voteCount || 0
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -81,9 +66,6 @@
|
||||
<script setup>
|
||||
import { defineProps } from 'vue'
|
||||
import { convertToHttps } from '~/utils/url'
|
||||
import { useLocale } from '~/utils/locale'
|
||||
const { admin } = useLocale()
|
||||
const locale = computed(() => admin.value.schedulePrinter)
|
||||
|
||||
// 定义props
|
||||
defineProps({
|
||||
@@ -94,10 +76,6 @@ defineProps({
|
||||
settings: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
@@ -113,9 +91,8 @@ const handleImageError = (event) => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #d1d5db;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
@@ -123,21 +100,6 @@ const handleImageError = (event) => {
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.item-leading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.item-trailing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sequence-number {
|
||||
@@ -150,13 +112,14 @@ const handleImageError = (event) => {
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #1a1a1a;
|
||||
color: var(--text-quaternary, #333333);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.cover-section {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
aspect-ratio: 1 / 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -165,17 +128,20 @@ const handleImageError = (event) => {
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.cover-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
object-fit: contain;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #6c757d;
|
||||
color: var(--text-tertiary, #999999);
|
||||
}
|
||||
|
||||
.cover-placeholder.show {
|
||||
@@ -195,53 +161,32 @@ const handleImageError = (event) => {
|
||||
.song-title {
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
color: #1a1a1a;
|
||||
color: var(--text-quaternary, #333333);
|
||||
margin-bottom: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 歌名文本块:text-overflow 只能作用在块容器上,故单独承载裁剪 */
|
||||
.title-text {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 打印用重播标识 */
|
||||
.replay-badge-print {
|
||||
display: inline-block;
|
||||
padding: 1px 4px;
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #0b5afe;
|
||||
background: #e3f2fd;
|
||||
border: 1px solid var(--border-secondary, #2196f3);
|
||||
border-radius: 3px;
|
||||
color: #2563eb;
|
||||
color: #1976d2;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 跨学期标识 */
|
||||
.cross-semester-badge-print {
|
||||
display: inline-block;
|
||||
padding: 1px 4px;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #d1d5db;
|
||||
color: #636366;
|
||||
font-size: 10px;
|
||||
border-radius: 2px;
|
||||
font-weight: normal;
|
||||
margin-left: 4px;
|
||||
vertical-align: middle;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.song-artist {
|
||||
font-size: 14px;
|
||||
color: #636366;
|
||||
color: var(--text-quaternary, #666666);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -252,91 +197,24 @@ const handleImageError = (event) => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: #636366;
|
||||
color: var(--text-quaternary, #666666);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: 500;
|
||||
margin-right: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #1a1a1a;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 两列窄版排布 */
|
||||
.schedule-item-print.is-narrow {
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.is-narrow .item-content,
|
||||
.is-narrow .item-leading {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.is-narrow .sequence-number {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.is-narrow .cover-section {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.is-narrow .cover-placeholder svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.is-narrow .song-title {
|
||||
font-size: 13px;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.is-narrow .song-artist {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.is-narrow .replay-badge-print,
|
||||
.is-narrow .cross-semester-badge-print {
|
||||
font-size: 9px;
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
/* 人数与歌名同行、投稿人与歌手同行 */
|
||||
.is-narrow .item-trailing {
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 0;
|
||||
min-width: 0;
|
||||
max-width: 45%;
|
||||
}
|
||||
|
||||
.is-narrow .votes-info {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
.is-narrow .requester-info,
|
||||
.is-narrow .votes-info {
|
||||
font-size: 11px;
|
||||
justify-content: flex-end;
|
||||
max-width: 100%;
|
||||
color: var(--text-quaternary, #333333);
|
||||
}
|
||||
|
||||
/* 打印样式 */
|
||||
@media print {
|
||||
.schedule-item-print {
|
||||
color: #1a1a1a !important;
|
||||
background: #ffffff !important;
|
||||
color: var(--text-primary, #000) !important;
|
||||
background: var(--card-bg, #fff) !important;
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
box-sizing: border-box !important;
|
||||
@@ -352,30 +230,43 @@ const handleImageError = (event) => {
|
||||
|
||||
.sequence-number {
|
||||
background: #f0f0f0 !important;
|
||||
color: #1a1a1a !important;
|
||||
color: var(--text-primary, #000) !important;
|
||||
width: 30px !important;
|
||||
height: 30px !important;
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
.cover-section {
|
||||
width: 40px !important;
|
||||
height: 40px !important;
|
||||
width: 48px !important;
|
||||
height: 48px !important;
|
||||
aspect-ratio: 1 / 1 !important;
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
|
||||
.song-cover {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: contain !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.cover-placeholder {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: contain !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.song-info {
|
||||
flex: 1 !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
.song-title {
|
||||
color: #1a1a1a !important;
|
||||
color: var(--text-primary, #000) !important;
|
||||
font-size: 16px !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
}
|
||||
@@ -383,11 +274,11 @@ const handleImageError = (event) => {
|
||||
.song-artist,
|
||||
.label,
|
||||
.value {
|
||||
color: #3a3a3c !important;
|
||||
color: var(--text-quaternary, #333333) !important;
|
||||
}
|
||||
|
||||
.time-range {
|
||||
color: #636366 !important;
|
||||
color: var(--text-quaternary, #666666) !important;
|
||||
}
|
||||
|
||||
.requester-info,
|
||||
|
||||
Reference in New Issue
Block a user