修复画布参考图上传删除链路 (#164)
Project CI / Repository checks (push) Successful in 3m3s
Project CI / Frontend tests (push) Successful in 3m32s
Project CI / Backend tests (push) Successful in 5m45s
Project CI / Native shell tests (push) Successful in 16m17s

主站规范生成支持多张参考图

修复普通生成参考图删除与提交状态不同步

优化触屏设备删除按钮可达性并补充回归测试

---------

Co-authored-by: kdletters <kdletters@qq.com>
Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/164
Co-authored-by: 孟豪 <mh18530625731@163.com>
Co-committed-by: 孟豪 <mh18530625731@163.com>
This commit was merged in pull request #164.
This commit is contained in:
2026-08-21 11:55:32 +08:00
committed by 段舒康
parent 7e3adc38b9
commit e4e3cab559
20 changed files with 698 additions and 72 deletions
@@ -349,7 +349,7 @@ describe('ImageCanvasUploadModel', () => {
imageSrc: 'data:image/png;base64,ref',
}),
).toEqual({
id: 'upload-character-reference-1781697600000-2',
id: 'upload-character-reference-1781697600000-2-1',
label: '参考图3',
src: 'data:image/png;base64,ref',
mediaType: 'image',
@@ -361,6 +361,26 @@ describe('ImageCanvasUploadModel', () => {
});
});
it('keeps uploaded reference identities unique across same-time batches', () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2026-06-17T12:00:00.000Z'));
const first = createUploadedGenerationReference({
idPrefix: 'upload-spec-reference',
index: 0,
fallbackLabel: '参考图1',
imageSrc: 'data:image/png;base64,first',
});
const second = createUploadedGenerationReference({
idPrefix: 'upload-spec-reference',
index: 0,
fallbackLabel: '参考图1',
imageSrc: 'data:image/png;base64,second',
});
expect(first.id).not.toBe(second.id);
});
it('resets failed generation dialogs when reference uploads are applied', () => {
expect(
setFailedGenerationIdle(
@@ -381,7 +401,7 @@ describe('ImageCanvasUploadModel', () => {
expect(
applyGenerationReferenceUpload({
dialog: createDialog({ mode: 'spec' }),
dialog: createDialog({ mode: 'spec', specType: 'icon' }),
target: 'spec-reference',
references: [reference],
}),
@@ -415,6 +435,71 @@ describe('ImageCanvasUploadModel', () => {
});
});
it('migrates a legacy non-icon spec reference before appending uploads', () => {
const legacyReference = {
id: 'ref-legacy',
label: '历史参考图',
src: 'data:image/png;base64,legacy',
};
const uploadedReferences = Array.from({ length: 5 }, (_, index) => ({
id: `ref-new-${index + 1}`,
label: `新参考图 ${index + 1}`,
src: `data:image/png;base64,new-${index + 1}`,
}));
expect(
applyGenerationReferenceUpload({
dialog: createDialog({
mode: 'spec',
specType: 'character',
specReference: legacyReference,
generationReferences: [],
}),
target: 'spec-reference',
references: uploadedReferences,
}),
).toMatchObject({
specReference: null,
generationReferences: [
legacyReference,
...uploadedReferences.slice(0, 4),
],
});
});
it('prefers canonical spec references over a stale legacy reference on upload', () => {
const canonicalReference = {
id: 'ref-current',
label: '当前参考图',
src: 'data:image/png;base64,current',
};
const nextReference = {
id: 'ref-next',
label: '新增参考图',
src: 'data:image/png;base64,next',
};
expect(
applyGenerationReferenceUpload({
dialog: createDialog({
mode: 'spec',
specType: 'custom',
specReference: {
id: 'ref-stale',
label: '过期参考图',
src: 'data:image/png;base64,stale',
},
generationReferences: [canonicalReference],
}),
target: 'generation-reference',
references: [nextReference],
}),
).toMatchObject({
specReference: null,
generationReferences: [canonicalReference, nextReference],
});
});
it('appends character reference uploads without changing unmatched dialogs', () => {
const previousReference = {
id: 'ref-old',