feat: 商品试算页面前端部分开发完成
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
Alert, Button, Card, Checkbox, Empty, Image, Input, InputNumber, message, Modal, Popover, Progress,
|
||||
Alert, Button, Card, Checkbox, Col, Empty, Image, Input, InputNumber, message, Modal, Popover, Progress,
|
||||
Radio, Row, Segmented, Select, Space, Tag, Typography, Upload,
|
||||
} from 'antd';
|
||||
import { DownloadOutlined, SettingOutlined, ThunderboltOutlined, UploadOutlined } from '@ant-design/icons';
|
||||
@@ -444,10 +444,10 @@ export default function TrialSuitePanel({ product, assets, onRefreshAssets }: Pr
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
{/* ── 采集图片 ── */}
|
||||
{/* ── 4 采集图片 ── */}
|
||||
<div id="section-collect">
|
||||
<Card
|
||||
size="small"
|
||||
title={`采集图片(已选 ${selectedKeys.size} / ${selectableCount})`}
|
||||
title={`4 采集图片(已选 ${selectedKeys.size} / ${selectableCount})`}
|
||||
extra={
|
||||
<Space>
|
||||
{uploadButton}
|
||||
@@ -569,36 +569,46 @@ export default function TrialSuitePanel({ product, assets, onRefreshAssets }: Pr
|
||||
</Image.PreviewGroup>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* ── 出图方案 ── */}
|
||||
{/* ── 5 出图方案(左:规划操作+方案列表;右:风格/要求/模型/生成) ── */}
|
||||
<div id="section-plan">
|
||||
<Card
|
||||
size="small"
|
||||
title={`出图方案(共 ${totalPlanned} 张)`}
|
||||
extra={
|
||||
<Space>
|
||||
{planSource === 'ai' && <Tag color="purple">AI 方案</Tag>}
|
||||
<Checkbox
|
||||
checked={planThenGenerate}
|
||||
onChange={(e) => setPlanThenGenerate(e.target.checked)}
|
||||
title="勾选后,AI 规划完成将自动开始生成"
|
||||
>
|
||||
规划并生成
|
||||
</Checkbox>
|
||||
<Button
|
||||
size="small"
|
||||
type="primary"
|
||||
ghost
|
||||
icon={<ThunderboltOutlined />}
|
||||
loading={planning}
|
||||
onClick={handlePlan}
|
||||
>
|
||||
AI 智能规划
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
title={`5 出图方案(共 ${totalPlanned} 张)`}
|
||||
extra={planSource === 'ai' && <Tag color="purple">AI 方案</Tag>}
|
||||
>
|
||||
<div>
|
||||
{plan.map((p, idx) => (
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
{/* 左列整块:与价格试算右列相同的浅灰卡片 */}
|
||||
<Card size="small" style={{ background: '#fafafa' }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
checked={planThenGenerate}
|
||||
onChange={(e) => setPlanThenGenerate(e.target.checked)}
|
||||
title="勾选后,AI 规划完成将自动开始生成"
|
||||
>
|
||||
规划并生成
|
||||
</Checkbox>
|
||||
<Button
|
||||
size="small"
|
||||
type="primary"
|
||||
ghost
|
||||
icon={<ThunderboltOutlined />}
|
||||
loading={planning}
|
||||
onClick={handlePlan}
|
||||
>
|
||||
AI 智能规划
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
{plan.map((p, idx) => (
|
||||
<div
|
||||
key={`${p.kind}-${idx}`}
|
||||
onClick={() => togglePlanRow(idx)}
|
||||
@@ -664,20 +674,27 @@ export default function TrialSuitePanel({ product, assets, onRefreshAssets }: Pr
|
||||
{planSummary || '方案与张数由规划器按商品信息自动决定,可手动微调,0 即不生成'}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<div style={{ borderTop: '1px solid #f0f0f0', paddingTop: 12, marginTop: 4 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 8 }}>
|
||||
<Text style={{ width: 70 }}>视觉风格</Text>
|
||||
{/* 水印设置:左列最下、靠右 */}
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 8 }}>
|
||||
<Popover trigger="click" placement="bottomRight" content={watermarkPopup} title="水印设置">
|
||||
<Button size="small" icon={<SettingOutlined />}>
|
||||
水印
|
||||
</Button>
|
||||
</Popover>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div>
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<div style={{ fontSize: 13, fontWeight: 500, color: 'rgba(0,0,0,0.82)', marginBottom: 6 }}>
|
||||
视觉风格
|
||||
</div>
|
||||
<Segmented
|
||||
value={styleSet}
|
||||
onChange={(v) => setStyleSet(v as number)}
|
||||
options={STYLE_SET_OPTIONS.map((s) => ({ value: s.value, label: s.label }))}
|
||||
/>
|
||||
<Popover trigger="click" placement="bottomRight" content={watermarkPopup} title="水印设置">
|
||||
<Button size="small" icon={<SettingOutlined />}>
|
||||
水印
|
||||
</Button>
|
||||
</Popover>
|
||||
</div>
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
@@ -708,7 +725,7 @@ export default function TrialSuitePanel({ product, assets, onRefreshAssets }: Pr
|
||||
生图要求(优先级最高,强制约束,会覆盖其他设定)
|
||||
</Text>
|
||||
<Input.TextArea
|
||||
rows={2}
|
||||
rows={3}
|
||||
value={requirements}
|
||||
onChange={(e) => setRequirements(e.target.value)}
|
||||
placeholder="选填,例如:必须保留商品正面品牌标识;背景必须为纯黑色;不得添加任何文字水印"
|
||||
@@ -749,13 +766,16 @@ export default function TrialSuitePanel({ product, assets, onRefreshAssets }: Pr
|
||||
{generating ? '生成中…' : `一键生图(${totalPlanned} 张)`}
|
||||
</Button>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* ── 生成结果 ── */}
|
||||
<div id="section-result">
|
||||
<Card
|
||||
size="small"
|
||||
title="生成结果"
|
||||
title="6 生成结果"
|
||||
extra={
|
||||
suite && ['done', 'partial'].includes(suite.status) && (
|
||||
<Button size="small" icon={<DownloadOutlined />} loading={exportingZip} onClick={handleExportZip}>
|
||||
@@ -852,6 +872,7 @@ export default function TrialSuitePanel({ product, assets, onRefreshAssets }: Pr
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 单张 AI 生图弹窗 */}
|
||||
<AiImageGenModal
|
||||
|
||||
Reference in New Issue
Block a user