feat: 作业纸

This commit is contained in:
R524809
2026-10-23 16:52:47 +08:00
parent 83a90407b0
commit c090675255
14 changed files with 532 additions and 3 deletions
@@ -11,6 +11,11 @@ import { PrismaService } from '../src/database/prisma.service';
import { JwtTokenService } from '../src/auth/jwt-token.service';
import { ASSET_STORAGE } from '../src/assets/qiniu.gateway';
import { AssetService } from '../src/assets/asset.service';
import { seedPaperSheets } from '../src/worksheets/paper-sheet-seed';
import {
PAPER_SHEET_PATH,
PAPER_SHEET_PRESETS,
} from '../src/worksheets/paper-sheet-presets';
import { SiteService } from '../src/site/site.service';
import { testConfig } from './test-config';
@@ -707,6 +712,147 @@ test(
);
},
);
await context.test(
'纸张拆分:预演不写库、草稿幂等、独立发布/收藏/下载及历史兼容',
async () => {
const parent = await db.worksheet.create({
data: {
id: 'paper-sheet',
title: '作业纸',
subtitle: '',
categoryId,
path: `${PAPER_SHEET_PATH}?id=paper-sheet`,
ageMin: 3,
ageMax: 12,
difficulty: 1,
previewAssetId: previewId,
status: 'active',
downloads: 123n,
likes: 9n,
},
});
await db.worksheetGrade.create({
data: { worksheetId: parent.id, grade: 0 },
});
const dry = await seedPaperSheets(app.get(PrismaService), true);
assert.equal(
dry.changes.filter((row) => row.action === 'insert-draft')
.length,
10,
);
assert.equal(
await db.worksheet.count({
where: { rendererKey: 'paper-sheet' },
}),
0,
);
await seedPaperSheets(app.get(PrismaService), false);
assert.ok(
(
await seedPaperSheets(app.get(PrismaService), false)
).changes.every((row) => row.action === 'unchanged'),
);
assert.deepEqual(
await db.worksheet.findUnique({ where: { id: parent.id } }),
parent,
);
for (const preset of PAPER_SHEET_PRESETS) {
const draft = await db.worksheet.findUniqueOrThrow({
where: { id: preset.id },
});
assert.equal(draft.status, 'draft');
assert.equal(draft.firstPublishedAt, null);
assert.equal(draft.downloads, 0n);
assert.equal(draft.likes, 0n);
assert.equal(
(await request(`/worksheets/${preset.id}`)).status,
404,
);
}
const input = {
id: 'paper-mi',
title: '米字格',
subtitle: '',
categoryId,
path: `${PAPER_SHEET_PATH}?id=paper-mi`,
ageMin: 3,
ageMax: 12,
difficulty: 1,
previewAssetId: previewId,
tags: ['米字格'],
status: 'active',
};
assert.equal(
(
await request(
'/admin/worksheets/publish',
tokens.admin,
'POST',
{
...input,
path: `${PAPER_SHEET_PATH}?id=paper-tian`,
},
)
).status,
400,
);
assert.equal(
(
await request(
'/admin/worksheets/publish',
tokens.admin,
'POST',
input,
)
).status,
201,
);
const detail = (await request('/worksheets/paper-mi')).body
.data;
assert.deepEqual(detail.rendering, {
rendererKey: 'paper-sheet',
paperType: 'mi',
});
assert.equal(detail.renderConfig, undefined);
assert.equal(
(await request('/me/favorites/paper-mi', tokens.b, 'PUT'))
.status,
200,
);
assert.equal(
(
await request(
'/me/favorites/paper-sheet',
tokens.b,
'PUT',
)
).status,
200,
);
const download = await request(
'/me/downloads',
tokens.b,
'POST',
{ worksheetId: 'paper-mi', exportId: randomUUID() },
);
assert.equal(download.status, 201);
const saved = await db.worksheet.findUniqueOrThrow({
where: { id: 'paper-mi' },
});
assert.equal(saved.downloads, 1n);
assert.equal(saved.likes, 1n);
const old = await db.worksheet.findUniqueOrThrow({
where: { id: parent.id },
});
assert.equal(old.downloads, 123n);
assert.equal(old.likes, 10n);
assert.ok(
await db.favorite.findFirst({
where: { userId: ids.b, worksheetId: parent.id },
}),
);
},
);
await context.test(
'注销删除本人明细、撤销旧 JWT,其余用户不受影响',
async () => {