feat: 完成现有小程序接口的全部迁移至新后端

This commit is contained in:
R524809
2026-10-19 13:17:51 +08:00
parent 8827110f2f
commit d30cf25890
148 changed files with 13287 additions and 34 deletions
@@ -4,6 +4,7 @@ import {
Get,
Param,
Patch,
Put,
Query,
Req,
} from '@nestjs/common';
@@ -59,6 +60,17 @@ export class AdminWorksheetController {
};
}
@Put(':id/status')
@ApiOperation({ summary: '更新发布状态(管理员,小程序 PUT 兼容入口)' })
async updateByPut(
@Param('id') id: string,
@Body() input: UpdateContentStatusDto,
@CurrentUser() actor: AuthenticatedUser,
@Req() request: HttpRequest,
) {
return this.update(id, input, actor, request);
}
@Patch(':id/status')
@ApiOperation({
summary: '题型发布、下架或转草稿(管理员);发布要求分类已上线',
@@ -115,6 +127,17 @@ export class AdminResourceController {
return { code: 0, message: 'ok', data: await this.resources.get(id) };
}
@Put(':id/status')
@ApiOperation({ summary: '更新发布状态(管理员,小程序 PUT 兼容入口)' })
async updateByPut(
@Param('id') id: string,
@Body() input: UpdateContentStatusDto,
@CurrentUser() actor: AuthenticatedUser,
@Req() request: HttpRequest,
) {
return this.update(id, input, actor, request);
}
@Patch(':id/status')
@ApiOperation({
summary: '资源发布、下架或转草稿(管理员);发布要求题型及分类已上线',
+3 -9
View File
@@ -1,3 +1,5 @@
import { publicObjectUrl } from './public-resource-url';
/** 仅解析已就绪的公开预览图;管理预览同样不绕过资产访问规则。 */
export interface PreviewAssetRow {
assetStatus: string;
@@ -39,15 +41,7 @@ export function previewUrl(
}
}
if (row.assetProvider === 'qiniu' && row.assetKey && qiniuPublicDomain) {
const parts = row.assetKey.split('/');
if (
row.assetKey.startsWith('/') ||
row.assetKey.includes('\\') ||
/[\r\n]/.test(row.assetKey) ||
parts.some((part) => part === '.' || part === '..')
)
return null;
return `${qiniuPublicDomain}/${parts.map((part) => encodeURIComponent(part)).join('/')}`;
return publicObjectUrl(qiniuPublicDomain, row.assetKey);
}
return null;
}
@@ -0,0 +1,32 @@
import type { ServerConfig } from '../config/server-config';
/** 数据库 objectKey 已含上传前缀;逐段编码且拒绝越界,不再次拼接前缀。 */
export function publicObjectUrl(
domain: string | null,
objectKey: string,
): string | null {
const parts = objectKey.split('/');
if (
!domain ||
objectKey.includes('\\') ||
[...objectKey].some(
(char) => char.charCodeAt(0) < 32 || char.charCodeAt(0) === 127,
) ||
parts.some((part) => !part || part === '.' || part === '..')
)
return null;
return `${domain}/${parts.map(encodeURIComponent).join('/')}`;
}
/** 字体等固定公开资源传备份相对路径,由配置统一补上传前缀;不解析旧 cloud 引用。 */
export function publicResourceUrl(
config: Pick<ServerConfig, 'qiniuPublicDomain' | 'qiniuKeyPrefix'>,
relativePath: string,
): string | null {
// 先独立验证相对路径,防止空路径或绝对路径被前缀掩盖。
if (!publicObjectUrl(config.qiniuPublicDomain, relativePath)) return null;
return publicObjectUrl(
config.qiniuPublicDomain,
`${config.qiniuKeyPrefix}${relativePath}`,
);
}