feat: 历史列表分类改为固定5标签(全部/中篇/短篇/长篇/收藏夹),移除状态筛选,后端保存length改为short
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user