feat: 历史列表分类改为固定5标签(全部/中篇/短篇/长篇/收藏夹),移除状态筛选,后端保存length改为short

This commit is contained in:
2026-07-21 21:15:31 +08:00
parent 9b496bb42a
commit 3813f91b8d
2 changed files with 26 additions and 85 deletions
@@ -33,23 +33,10 @@
</view>
</view>
<view class="filter-bar">
<scroll-view class="status-scroll" scroll-x :show-scrollbar="false">
<view class="status-row">
<text
v-for="filter in statusFilters"
:key="filter.value"
class="status-chip"
:class="{ active: activeStatus === filter.value }"
@click="activeStatus = filter.value"
>{{ filter.label }}</text>
</view>
</scroll-view>
<view class="sort-tools">
<text class="sort-text" @click="toggleSort">{{ sortLabel }}</text>
<view class="grid-icon" :class="{ active: viewMode === 'grid' }" @click="toggleViewMode">
<view v-for="i in 4" :key="i"></view>
</view>
<view class="sort-bar">
<text class="sort-text" @click="toggleSort">{{ sortLabel }}</text>
<view class="grid-icon" :class="{ active: viewMode === 'grid' }" @click="toggleViewMode">
<view v-for="i in 4" :key="i"></view>
</view>
</view>
@@ -153,7 +140,6 @@ import { toggleFavoriteScript, checkFavoriteScript } from '../../services/epicSc
const store = useAppStore()
const activeType = ref('all')
const activeStatus = ref('all')
const keyword = ref('')
const sortMode = ref('updated')
const viewMode = ref('list')
@@ -162,24 +148,12 @@ const activeMenuId = ref('')
const deleteTarget = ref(null)
const deletingScript = ref(false)
// length 字段值 → 显示标签映射
const LENGTH_LABELS = { short: '短篇', medium: '中篇', long: '长篇' }
// 从实际剧本数据中提取分类标签,禁止硬编码
const typeTabs = computed(() => {
const lengths = new Set(scripts.value.map(s => s.length || 'medium'))
const tabs = [{ label: '全部', value: 'all' }]
lengths.forEach(l => {
tabs.push({ label: LENGTH_LABELS[l] || l, value: l })
})
return tabs
})
const statusFilters = [
// 固定 5 个分类标签:全部 / 中篇 / 短篇 / 长篇 / 收藏夹
const typeTabs = [
{ label: '全部', value: 'all' },
{ label: '进行中', value: 'progress' },
{ label: '已完成', value: 'done' },
{ label: '草稿箱', value: 'draft' },
{ label: '中', value: 'medium' },
{ label: '短篇', value: 'short' },
{ label: '长篇', value: 'long' },
{ label: '收藏夹', value: 'favorite' }
]
@@ -187,14 +161,13 @@ const scripts = computed(() => store.scripts || [])
const visibleScripts = computed(() => {
const filtered = scripts.value.filter(script => {
const status = getStatus(script)
if (keyword.value) {
const haystack = [script.title, script.summary, script.content, script.style, ...(script.tags || [])].join(' ')
if (!haystack.includes(keyword.value)) return false
}
if (activeStatus.value === 'favorite') return isFavorite(script)
if (activeStatus.value !== 'all' && status !== activeStatus.value) return false
// 精确匹配 length 字段,禁止硬编码分类
// 收藏夹分类:按收藏状态筛选
if (activeType.value === 'favorite') return isFavorite(script)
// 全部:不过滤;其他:精确匹配 length 字段
if (activeType.value !== 'all') return script.length === activeType.value
return true
})
@@ -243,7 +216,8 @@ const getStatusLabel = (script) => {
}
const getLengthLabel = (length) => {
return length === 'short' ? '篇' : '长篇'
const map = { short: '短篇', medium: '篇', long: '长篇' }
return map[length] || '长篇'
}
const getTags = (script) => {
@@ -317,10 +291,10 @@ const openMoreMenu = () => {
itemList: ['清空搜索', '只看收藏', '查看全部'],
success: ({ tapIndex }) => {
if (tapIndex === 0) keyword.value = ''
if (tapIndex === 1) activeStatus.value = 'favorite'
if (tapIndex === 1) activeType.value = 'favorite'
if (tapIndex === 2) {
keyword.value = ''
activeStatus.value = 'all'
activeType.value = 'all'
}
}
})
@@ -434,8 +408,7 @@ const confirmDeleteScript = async () => {
.back-title,
.head-actions,
.type-tabs,
.filter-bar,
.sort-tools,
.sort-bar,
.card-top,
.title-wrap,
.right-state,
@@ -564,47 +537,11 @@ const confirmDeleteScript = async () => {
line-height: 1;
}
.filter-bar {
.sort-bar {
justify-content: flex-end;
gap: 14rpx;
}
.status-scroll {
flex: 1;
min-width: 0;
white-space: nowrap;
}
.status-row {
display: inline-flex;
gap: 16rpx;
}
.status-chip {
height: 52rpx;
min-width: 88rpx;
padding: 0 24rpx;
border-radius: 999rpx;
display: inline-flex;
align-items: center;
justify-content: center;
color: rgba(224, 214, 243, 0.78);
font-size: 23rpx;
border: 1rpx solid rgba(151, 111, 255, 0.42);
background: rgba(255, 255, 255, 0.02);
}
.status-chip.active {
color: #fff;
border-color: rgba(206, 82, 255, 0.92);
background: rgba(130, 48, 220, 0.42);
box-shadow: 0 0 18rpx rgba(168, 67, 255, 0.46);
}
.sort-tools {
gap: 14rpx;
flex-shrink: 0;
}
.sort-text {
color: #c99fff;
font-size: 23rpx;
@@ -241,13 +241,17 @@ public class EpicScriptDialogueServiceImpl implements EpicScriptDialogueService
? (String) metadata.get("title") : "我的人生剧本");
script.setTheme(theme);
script.setStyle("career");
script.setLength("medium");
script.setLength("short");
script.setConversationId(conversationId);
script.setPlotIntro(fullText);
script.setPlotIntro("");
script.setPlotTurning("");
script.setPlotClimax("");
script.setPlotEnding("");
script.setPlotJson(metadata != null ? metadata : new HashMap<>());
// 短篇小说全量文本保存到 plotJson.fullContent
// 前端 transformToFrontendFormat 通过 plotJson.fullContent 读取完整内容
Map<String, Object> plotJsonMap = metadata != null ? new HashMap<>(metadata) : new HashMap<>();
plotJsonMap.put("fullContent", fullText);
script.setPlotJson(plotJsonMap);
script.setIsSelected(0);
epicScriptService.save(script);