feat: 新功能改进 #20

Merged
hera merged 57 commits from feat/next-improvements into main 2026-04-10 20:30:37 +00:00
Showing only changes of commit b6b112e9cb - Show all commits

View File

@@ -25,19 +25,19 @@
</template>
<!-- Row 2: Add + Select + Tags + Batch + Export -->
<div class="tag-filter-bar">
<div class="toolbar-row">
<button v-if="auth.canEdit" class="btn-outline btn-sm" @click="showAddOverlay = true">新增</button>
<button
class="btn-sm"
:class="selectedDiaryIds.size > 0 ? 'btn-select-active' : 'btn-outline'"
:class="totalSelected > 0 ? 'btn-select-active' : 'btn-outline'"
@click="toggleSelectAllDiary"
>全选</button>
<span v-if="totalSelected > 0" class="select-count">{{ totalSelected }}</span>
<button class="tag-toggle-btn" @click="showTagFilter = !showTagFilter">
标签 {{ showTagFilter ? '' : '' }}
</button>
<!-- Batch (inline when selected) -->
<template v-if="selectedIds.size > 0 || selectedDiaryIds.size > 0">
<span class="batch-count">{{ selectedIds.size + selectedDiaryIds.size }}</span>
<!-- Batch -->
<template v-if="totalSelected > 0">
<select v-model="batchAction" class="batch-select" @change="onBatchSelect">
<option value="">批量操作...</option>
<option value="tag">打标签</option>
@@ -47,18 +47,18 @@
<button class="btn-sm btn-outline" @click="clearSelection">取消</button>
</template>
<button v-if="auth.isAdmin" class="export-btn" @click="exportExcel" title="导出Excel">📥</button>
<div v-if="showTagFilter" class="tag-list">
<span
v-for="tag in recipeStore.allTags"
:key="tag"
class="tag-chip"
:class="{ active: selectedTags.includes(tag) }"
@click="toggleTag(tag)"
>{{ tag }}<span v-if="auth.isAdmin" class="tag-delete" @click.stop="deleteGlobalTag(tag)">×</span></span>
<div v-if="auth.canEdit" class="tag-add-row">
<input v-model="globalNewTag" class="tag-add-input" placeholder="新标签..." @keydown.enter="addGlobalTag" />
<button class="tag-add-btn" @click="addGlobalTag" :disabled="!globalNewTag.trim()">+</button>
</div>
</div>
<div v-if="showTagFilter" class="tag-list-bar">
<span
v-for="tag in recipeStore.allTags"
:key="tag"
class="tag-chip"
:class="{ active: selectedTags.includes(tag) }"
@click="toggleTag(tag)"
>{{ tag }}<span v-if="auth.isAdmin" class="tag-delete" @click.stop="deleteGlobalTag(tag)">×</span></span>
<div v-if="auth.canEdit" class="tag-add-row">
<input v-model="globalNewTag" class="tag-add-input" placeholder="新标签..." @keydown.enter="addGlobalTag" />
<button class="tag-add-btn" @click="addGlobalTag" :disabled="!globalNewTag.trim()">+</button>
</div>
</div>
@@ -959,6 +959,7 @@ async function saveAllParsed() {
const sharedCount = ref({ adopted: 0, total: 0 })
const previewRecipeIndex = ref(null)
const batchAction = ref('')
const totalSelected = computed(() => selectedIds.size + selectedDiaryIds.size)
const showMyRecipes = ref(false)
const showPublicRecipes = ref(false)
const showReviewHistory = ref(false)
@@ -1588,6 +1589,13 @@ watch(() => recipeStore.recipes, () => {
.drops-sm:focus { border-color: #7ec6a4; }
.select-sm { padding: 4px 6px; border: 1.5px solid #d4cfc7; border-radius: 6px; font-size: 12px; font-family: inherit; background: #fff; width: auto; }
.btn-select-active { background: #e8f5e9; color: #2e7d5a; border: 1.5px solid #7ec6a4; border-radius: 10px; padding: 7px 14px; font-size: 13px; cursor: pointer; font-family: inherit; font-weight: 600; }
.toolbar-row {
display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 8px;
}
.select-count { font-size: 12px; color: #4a9d7e; font-weight: 500; white-space: nowrap; }
.tag-list-bar {
display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; padding: 8px 0;
}
.tag-delete { margin-left: 4px; cursor: pointer; font-size: 12px; color: #ccc; }
.tag-delete:hover { color: #c0392b; }
.tag-add-row { display: flex; gap: 4px; align-items: center; width: 100%; margin-top: 4px; }