update:1.修复一对一模式修改大纲名称没有同步更新章节名称 2.修复一对一模式全新生成大纲,没有关联删除对应章节问题 3.优化根据分析建议重新生成章节内容时引用默认写作风格 5.将写作风格调整至用户级,在一个项目中添加全局可见(需要更新数据库)

This commit is contained in:
xiamuceer
2025-11-28 20:23:42 +08:00
parent deb6cc37a4
commit 3be62e1482
12 changed files with 302 additions and 108 deletions
+4 -1
View File
@@ -1464,7 +1464,10 @@ export default function Outline() {
title={
<Space size="small" style={{ fontSize: isMobile ? 14 : 16, flexWrap: 'wrap' }}>
<span style={{ color: '#1890ff', fontWeight: 'bold' }}>
{item.order_index || '?'}
{currentProject?.outline_mode === 'one-to-one'
? `${item.order_index || '?'}`
: `${item.order_index || '?'}`
}
</span>
<span>{item.title}</span>
{/* ✅ 新增:展开状态标识 - 仅在一对多模式显示 */}
+30 -31
View File
@@ -51,26 +51,29 @@ export default function WritingStyles() {
xl: 6,
};
// 加载项目风格
// 加载风格列表 - 如果有项目则加载项目风格(包含默认标记),否则加载用户风格
useEffect(() => {
if (currentProject?.id) {
loadProjectStyles();
}
loadStyles();
}, [currentProject?.id]);
const loadProjectStyles = async () => {
if (!currentProject?.id) return;
const loadStyles = async () => {
try {
setLoading(true);
const response = await writingStyleApi.getProjectStyles(currentProject.id);
// 对风格列表进行排序:默认风格优先,然后按原有顺序
// 如果有当前项目,使用项目API获取(包含is_default标记)
// 否则使用用户API获取(所有风格的is_default都是false
const response = currentProject?.id
? await writingStyleApi.getProjectStyles(currentProject.id)
: await writingStyleApi.getUserStyles();
// 排序:默认风格优先显示
const sortedStyles = (response.styles || []).sort((a, b) => {
// 默认风格排在前面
// 默认风格排在前面
if (a.is_default && !b.is_default) return -1;
if (!a.is_default && b.is_default) return 1;
// 其他按原有顺序(order_index
return 0;
});
setStyles(sortedStyles);
} catch {
message.error('加载风格列表失败');
@@ -80,11 +83,8 @@ export default function WritingStyles() {
};
const handleCreate = async (values: { name: string; description?: string; prompt_content: string }) => {
if (!currentProject?.id) return;
try {
const createData: WritingStyleCreate = {
project_id: currentProject.id,
name: values.name,
style_type: 'custom',
description: values.description,
@@ -95,7 +95,7 @@ export default function WritingStyles() {
message.success('创建成功');
setIsCreateModalOpen(false);
createForm.resetFields();
await loadProjectStyles();
await loadStyles();
} catch {
message.error('创建失败');
}
@@ -120,7 +120,7 @@ export default function WritingStyles() {
setIsEditModalOpen(false);
editForm.resetFields();
setEditingStyle(null);
await loadProjectStyles();
await loadStyles();
} catch {
message.error('更新失败');
}
@@ -130,19 +130,22 @@ export default function WritingStyles() {
try {
await writingStyleApi.deleteStyle(styleId);
message.success('删除成功');
await loadProjectStyles();
await loadStyles();
} catch {
message.error('删除失败');
}
};
const handleSetDefault = async (styleId: number) => {
if (!currentProject?.id) return;
if (!currentProject?.id) {
message.warning('请先选择项目');
return;
}
try {
await writingStyleApi.setDefaultStyle(styleId, currentProject.id);
message.success('设置默认风格成功');
await loadProjectStyles();
await loadStyles();
} catch {
message.error('设置失败');
}
@@ -153,8 +156,6 @@ export default function WritingStyles() {
setIsCreateModalOpen(true);
};
if (!currentProject) return null;
const getStyleTypeColor = (styleType: string) => {
return styleType === 'preset' ? 'blue' : 'purple';
};
@@ -240,13 +241,13 @@ export default function WritingStyles() {
)}
</span>
</Tooltip>,
<Tooltip key="edit" title={style.project_id === null ? '预设风格不可编辑' : '编辑'}>
<Tooltip key="edit" title={style.user_id === null ? '预设风格不可编辑' : '编辑'}>
<EditOutlined
onClick={() => style.project_id !== null && handleEdit(style)}
onClick={() => style.user_id !== null && handleEdit(style)}
style={{
fontSize: 18,
cursor: style.project_id === null ? 'not-allowed' : 'pointer',
color: style.project_id === null ? '#ccc' : undefined
cursor: style.user_id === null ? 'not-allowed' : 'pointer',
color: style.user_id === null ? '#ccc' : undefined
}}
/>
</Tooltip>,
@@ -257,20 +258,18 @@ export default function WritingStyles() {
onConfirm={() => handleDelete(style.id)}
okText="确定"
cancelText="取消"
disabled={style.project_id === null || styles.length === 1}
disabled={style.user_id === null}
>
<Tooltip title={
style.project_id === null
style.user_id === null
? '预设风格不可删除'
: styles.length === 1
? '至少保留一个风格'
: '删除'
: '删除'
}>
<DeleteOutlined
style={{
fontSize: 18,
color: (style.project_id === null || styles.length === 1) ? '#ccc' : undefined,
cursor: (style.project_id === null || styles.length === 1) ? 'not-allowed' : 'pointer'
color: style.user_id === null ? '#ccc' : undefined,
cursor: style.user_id === null ? 'not-allowed' : 'pointer'
}}
/>
</Tooltip>
+5 -1
View File
@@ -437,7 +437,11 @@ export const writingStyleApi = {
getPresetStyles: () =>
api.get<unknown, PresetStyle[]>('/writing-styles/presets/list'),
// 获取项目的所有风格
// 获取用户的所有风格(新接口)
getUserStyles: () =>
api.get<unknown, WritingStyleListResponse>('/writing-styles/user'),
// 获取项目的所有风格(保留向后兼容)
getProjectStyles: (projectId: string) =>
api.get<unknown, WritingStyleListResponse>(`/writing-styles/project/${projectId}`),
+2 -4
View File
@@ -406,7 +406,7 @@ export interface ApiResponse<T> {
// 写作风格类型定义
export interface WritingStyle {
id: number;
project_id: string;
user_id: string | null; // NULL 表示全局预设风格
name: string;
style_type: 'preset' | 'custom';
preset_id?: string;
@@ -419,13 +419,11 @@ export interface WritingStyle {
}
export interface WritingStyleCreate {
project_id: string;
name: string;
style_type: 'preset' | 'custom';
style_type?: 'preset' | 'custom';
preset_id?: string;
description?: string;
prompt_content: string;
is_default?: boolean;
}
export interface WritingStyleUpdate {