上线版: 产品表单统一+form嵌套修复+用户管理+部署+三套叙事
- 产品编辑入口统一走 ProductFormFull(卖点/风格/人群/品牌词全字段); 修复开任务页 <form> 套 <form> 致"编辑产品"报错、改不了、跳回首个产品 - dashboard 入口卡片对齐实际路由: 系统管理(/config) 与 工作配置(/settings) 分开; settings ?tab=products 直达改用挂载后读 URL, 消除 hydration mismatch - 新增用户管理(users API/admin service/改密页) + alembic 022/023/024 - 上线部署: Dockerfile / docker-compose.prod+https / nginx https / .env.example - A8 三套正交叙事(痛点/场景/成分背书) + beige 调色去AI化 + 飞轮 text_import 高权重信号 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ import { ApiError } from '@/types/index';
|
||||
|
||||
export default function NewTaskPage() {
|
||||
const router = useRouter();
|
||||
const { context } = usePreferenceStore();
|
||||
const { context, fetchContextByProduct } = usePreferenceStore();
|
||||
const [products, setProducts] = useState<Product[]>([]);
|
||||
const [selectedProduct, setSelectedProduct] = useState<Product | null>(null);
|
||||
const [benchmarks, setBenchmarks] = useState<Benchmark[]>([]);
|
||||
@@ -35,6 +35,7 @@ export default function NewTaskPage() {
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const [importOpen, setImportOpen] = useState(false);
|
||||
const [editingProduct, setEditingProduct] = useState(false); // 提升:供右侧「编辑配置」(运营/组长)触发就地编辑
|
||||
|
||||
useEffect(() => { loadProducts(); }, []);
|
||||
|
||||
@@ -47,6 +48,12 @@ export default function NewTaskPage() {
|
||||
.catch(() => setBenchmarks([]));
|
||||
}, [selectedProduct]);
|
||||
|
||||
// 选品变化:拉该产品飞轮偏好上下文,驱动顶部 FlywheelBanner
|
||||
useEffect(() => {
|
||||
if (!selectedProduct) return;
|
||||
fetchContextByProduct(selectedProduct.id);
|
||||
}, [selectedProduct?.id]);
|
||||
|
||||
async function loadProducts() {
|
||||
try {
|
||||
const data = await api.get<PaginatedResponse<Product>>('/api/v1/products');
|
||||
@@ -57,6 +64,12 @@ export default function NewTaskPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// #1 内联建品:把新产品并入列表顶部并选中(QuickProductCreate 已含上传产品图)
|
||||
function handleProductCreated(p: Product) {
|
||||
setProducts((list) => [p, ...list.filter((x) => x.id !== p.id)]);
|
||||
setSelectedProduct(p);
|
||||
}
|
||||
|
||||
function validate(): boolean {
|
||||
if (!selectedProduct) { setError('请选择产品'); return false; }
|
||||
if (!form.theme.trim()) { setError('请填写今天主题'); return false; }
|
||||
@@ -135,6 +148,9 @@ export default function NewTaskPage() {
|
||||
products={products}
|
||||
selectedProduct={selectedProduct}
|
||||
onSelectProduct={setSelectedProduct}
|
||||
onProductCreated={handleProductCreated}
|
||||
editingProduct={editingProduct}
|
||||
setEditingProduct={setEditingProduct}
|
||||
benchmarks={benchmarks}
|
||||
form={form}
|
||||
onFormChange={(patch) => setForm((f) => ({ ...f, ...patch }))}
|
||||
@@ -147,7 +163,7 @@ export default function NewTaskPage() {
|
||||
</div>
|
||||
|
||||
{/* 右侧配置预览面板 */}
|
||||
{selectedProduct && <ConfigPreviewPanel product={selectedProduct} />}
|
||||
{selectedProduct && <ConfigPreviewPanel product={selectedProduct} onEditInline={() => setEditingProduct(true)} />}
|
||||
</div>
|
||||
|
||||
<ImportTextModal
|
||||
|
||||
Reference in New Issue
Block a user