按后台配置扣除创作泥点
前端创作表单泥点预校验改为读取入口契约配置 拼图和抓大鹅初始生成后端扣费改为解析后台配置 汪汪声浪初始三图生成按入口总成本拆分扣费 创作工作台按钮和确认弹窗展示后台配置泥点成本 补充泥点扣费回归测试并同步文档与共享记忆
This commit is contained in:
@@ -65,6 +65,13 @@ function confirmMatch3DPointCost() {
|
||||
fireEvent.click(within(confirmDialog).getByRole('button', { name: '确定' }));
|
||||
}
|
||||
|
||||
function confirmMatch3DPointCostText(text: string) {
|
||||
const confirmDialog = screen.getByRole('dialog', {
|
||||
name: '确认消耗泥点',
|
||||
});
|
||||
expect(within(confirmDialog).getByText(text)).toBeTruthy();
|
||||
}
|
||||
|
||||
test('match3d workspace submits derived entry form payload instead of agent chat', () => {
|
||||
const onCreateFromForm = vi.fn();
|
||||
const onExecuteAction = vi.fn();
|
||||
@@ -112,6 +119,26 @@ test('match3d workspace submits derived entry form payload instead of agent chat
|
||||
expect(onExecuteAction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('match3d workspace shows configured mud point cost', () => {
|
||||
render(
|
||||
<Match3DCreationWorkspace
|
||||
session={null}
|
||||
onBack={() => {}}
|
||||
onExecuteAction={() => {}}
|
||||
onCreateFromForm={() => {}}
|
||||
mudPointCost={12}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('消耗12泥点')).toBeTruthy();
|
||||
fireEvent.change(screen.getByLabelText('想做一个什么题材的抓大鹅?'), {
|
||||
target: { value: '陶泥甜品店' },
|
||||
});
|
||||
fireEvent.click(screen.getByRole('button', { name: /生成抓大鹅草稿/u }));
|
||||
|
||||
confirmMatch3DPointCostText('消耗 12 泥点');
|
||||
});
|
||||
|
||||
test('match3d workspace can defer visible chrome to the unified creation page', () => {
|
||||
const { container } = render(
|
||||
<Match3DCreationWorkspace
|
||||
|
||||
@@ -20,6 +20,7 @@ type Match3DCreationWorkspaceProps = {
|
||||
showBackButton?: boolean;
|
||||
title?: string | null;
|
||||
unifiedChrome?: boolean;
|
||||
mudPointCost?: number;
|
||||
};
|
||||
|
||||
type Match3DFormState = {
|
||||
@@ -117,6 +118,7 @@ export function Match3DCreationWorkspace({
|
||||
showBackButton = true,
|
||||
title = '抓大鹅',
|
||||
unifiedChrome = false,
|
||||
mudPointCost = 10,
|
||||
}: Match3DCreationWorkspaceProps) {
|
||||
const [formState, setFormState] = useState<Match3DFormState>(() =>
|
||||
resolveInitialFormState(session, initialFormPayload),
|
||||
@@ -324,7 +326,7 @@ export function Match3DCreationWorkspace({
|
||||
)}
|
||||
<span>生成抓大鹅草稿</span>
|
||||
<span className="rounded-full bg-white/24 px-2 py-0.5 text-[11px] font-bold">
|
||||
消耗10泥点
|
||||
消耗{mudPointCost}泥点
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
@@ -345,7 +347,7 @@ export function Match3DCreationWorkspace({
|
||||
确认消耗泥点
|
||||
</div>
|
||||
<div className="mt-2 text-sm font-semibold leading-6 text-[var(--platform-text-base)]">
|
||||
消耗 10 泥点
|
||||
消耗 {mudPointCost} 泥点
|
||||
</div>
|
||||
<div className="mt-5 grid grid-cols-2 gap-3">
|
||||
<button
|
||||
|
||||
@@ -173,6 +173,13 @@ function confirmPuzzlePointCost() {
|
||||
fireEvent.click(within(confirmDialog).getByRole('button', { name: '确定' }));
|
||||
}
|
||||
|
||||
function confirmPuzzlePointCostText(text: string) {
|
||||
const confirmDialog = screen.getByRole('dialog', {
|
||||
name: '确认消耗泥点',
|
||||
});
|
||||
expect(within(confirmDialog).getByText(text)).toBeTruthy();
|
||||
}
|
||||
|
||||
test('puzzle workspace submits the work form instead of agent chat', () => {
|
||||
const onCreateFromForm = vi.fn();
|
||||
|
||||
@@ -216,6 +223,27 @@ test('puzzle workspace submits the work form instead of agent chat', () => {
|
||||
expect(screen.queryByText('旧会话消息不再渲染为聊天入口。')).toBeNull();
|
||||
});
|
||||
|
||||
test('puzzle workspace shows configured mud point cost', () => {
|
||||
render(
|
||||
<PuzzleCreationWorkspace
|
||||
session={null}
|
||||
onBack={() => {}}
|
||||
onSubmitMessage={() => {}}
|
||||
onExecuteAction={() => {}}
|
||||
onCreateFromForm={() => {}}
|
||||
mudPointCost={8}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('消耗8泥点')).toBeTruthy();
|
||||
fireEvent.change(screen.getByLabelText('画面描述'), {
|
||||
target: { value: '一座雨后的陶泥小镇。' },
|
||||
});
|
||||
fireEvent.click(screen.getByRole('button', { name: /生成拼图游戏草稿/u }));
|
||||
|
||||
confirmPuzzlePointCostText('消耗 8 泥点');
|
||||
});
|
||||
|
||||
test('puzzle workspace can defer visible chrome to the unified creation page', () => {
|
||||
const { container } = render(
|
||||
<PuzzleCreationWorkspace
|
||||
|
||||
@@ -50,6 +50,7 @@ type PuzzleCreationWorkspaceProps = {
|
||||
showBackButton?: boolean;
|
||||
title?: string | null;
|
||||
unifiedChrome?: boolean;
|
||||
mudPointCost?: number;
|
||||
};
|
||||
|
||||
type PuzzleFormState = {
|
||||
@@ -248,6 +249,7 @@ export function PuzzleCreationWorkspace({
|
||||
showBackButton = true,
|
||||
title = '拼图',
|
||||
unifiedChrome = false,
|
||||
mudPointCost = 2,
|
||||
}: PuzzleCreationWorkspaceProps) {
|
||||
const [formState, setFormState] = useState<PuzzleFormState>(() =>
|
||||
resolveInitialFormState(session, initialFormPayload),
|
||||
@@ -667,7 +669,7 @@ export function PuzzleCreationWorkspace({
|
||||
inputError={referenceImageError}
|
||||
error={error}
|
||||
submitLabel="生成拼图游戏草稿"
|
||||
submitCostLabel={formState.aiRedraw ? '消耗2泥点' : null}
|
||||
submitCostLabel={formState.aiRedraw ? `消耗${mudPointCost}泥点` : null}
|
||||
submitDisabled={!canSubmit}
|
||||
labels={{
|
||||
imageField: '拼图画面',
|
||||
@@ -760,7 +762,7 @@ export function PuzzleCreationWorkspace({
|
||||
确认消耗泥点
|
||||
</div>
|
||||
<div className="mt-2 text-sm font-semibold leading-6 text-[var(--platform-text-base)]">
|
||||
消耗 2 泥点
|
||||
消耗 {mudPointCost} 泥点
|
||||
</div>
|
||||
<div className="mt-5 grid grid-cols-2 gap-3">
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user