create-dp-koa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/index.mjs +97 -0
- package/package.json +33 -0
- package/template/.env.development +9 -0
- package/template/.env.production +12 -0
- package/template/.github/workflows/ci-cd.yml +182 -0
- package/template/.trae/documents/controller_development_plan.md +386 -0
- package/template/.trae/skills/00-backend-core.skill.md +50 -0
- package/template/.trae/skills/01-backend-skill-router.skill.md +55 -0
- package/template/.trae/skills/10-backend-api.skill.md +54 -0
- package/template/.trae/skills/11-backend-controller-recipes.skill.md +107 -0
- package/template/.trae/skills/20-backend-repository.skill.md +25 -0
- package/template/.trae/skills/21-backend-service.skill.md +135 -0
- package/template/.trae/skills/25-backend-comments-and-doc.skill.md +97 -0
- package/template/.trae/skills/30-backend-validation.skill.md +320 -0
- package/template/.trae/skills/40-backend-error-logging.skill.md +21 -0
- package/template/.trae/skills/50-backend-bootstrap-lifecycle.skill.md +90 -0
- package/template/.trae/skills/60-backend-router-registration.skill.md +71 -0
- package/template/.trae/skills/70-backend-middleware.skill.md +98 -0
- package/template/.trae/skills/80-backend-utils-and-libs.skill.md +90 -0
- package/template/.trae/skills/85-backend-plugins.rule.md +64 -0
- package/template/.trae/skills/90-backend-testing.skill.md +29 -0
- package/template/.trae/skills/README.md +49 -0
- package/template/.vscode/launch.json +38 -0
- package/template/.vscode/settings.json +1 -0
- package/template/Dockerfile +36 -0
- package/template/README.md +229 -0
- package/template/docker-compose.yml +135 -0
- package/template/docs/API_DOCUMENTATION.md +837 -0
- package/template/docs/ARCHITECTURE_REFACTOR.md +109 -0
- package/template/docs/CACHE_MIGRATION_GUIDE.md +142 -0
- package/template/docs/DEPLOYMENT_GUIDE.md +1062 -0
- package/template/docs/DEVELOPMENT_GUIDE.md +1097 -0
- package/template/docs/DOCUMENTATION_CLEANUP_REPORT.md +166 -0
- package/template/docs/DOCUMENTATION_COMPLETION_REPORT.md +223 -0
- package/template/docs/DOCUMENTATION_INDEX.md +294 -0
- package/template/docs/DOCUMENTATION_STRUCTURE.md +221 -0
- package/template/docs/ENTERPRISE_ANNOTATION_SYSTEM_GUIDE.md +2069 -0
- package/template/docs/ENTERPRISE_DATABASE_ARCHITECTURE.md +318 -0
- package/template/docs/ENTERPRISE_DEPLOYMENT_GUIDE.md +547 -0
- package/template/docs/ENTERPRISE_ERROR_HANDLING_GUIDE.md +357 -0
- package/template/docs/ENTERPRISE_LOGGING_SYSTEM_GUIDE.md +494 -0
- package/template/docs/ENVIRONMENT_CONFIG_EXAMPLE.md +69 -0
- package/template/docs/FINAL_IMPLEMENTATION_SUMMARY.md +206 -0
- package/template/docs/HEALTH_CHECK_ROUTE_FIX.md +134 -0
- package/template/docs/IMPLEMENTATION_CHECKLIST.md +204 -0
- package/template/docs/INSTALLATION_GUIDE.md +611 -0
- package/template/docs/INTERCEPTOR_TESTING_REPORT.md +226 -0
- package/template/docs/INTERCEPTOR_TESTING_SCRIPTS.md +143 -0
- package/template/docs/LOGGING_OPTIMIZATION_GUIDE.md +126 -0
- package/template/docs/MEMORY_DATABASE_GUIDE.md +212 -0
- package/template/docs/NEW_ROUTER_INTEGRATION_GUIDE.md +345 -0
- package/template/docs/NEW_ROUTER_INTEGRATION_SUMMARY.md +259 -0
- package/template/docs/NEW_ROUTER_USAGE_GUIDE.md +364 -0
- package/template/docs/QUICK_START.md +268 -0
- package/template/docs/ROUTE_SLASH_COMPATIBILITY_FIX.md +191 -0
- package/template/docs/SERVICE_INTERCEPTOR_GUIDE.md +243 -0
- package/template/docs/SERVICE_LAYER_INDEX.md +205 -0
- package/template/docs/SERVICE_PATTERN_GUIDE.md +270 -0
- package/template/docs/SERVICE_RETURN_VALUE_SPECIFICATION.md +466 -0
- package/template/docs/SWAGGER_DEBUG_MODE_GUIDE.md +80 -0
- package/template/docs/SWAGGER_INTEGRATION_GUIDE.md +416 -0
- package/template/docs/TRANSACTION_MANAGER_USAGE.md +360 -0
- package/template/docs/TROUBLESHOOTING.md +869 -0
- package/template/env.production.example +62 -0
- package/template/jest.config.js +34 -0
- package/template/package-lock.json +13240 -0
- package/template/package.json +119 -0
- package/template/patches/typeorm+0.3.25.patch +22 -0
- package/template/scripts/sync-template.mjs +84 -0
- package/template/scripts/test-annotation-system.sh +48 -0
- package/template/scripts/test-core-functionality.sh +28 -0
- package/template/src/annotations/decorators/ConfigManagement.ts +9 -0
- package/template/src/annotations/decorators/DistributedTracing.ts +9 -0
- package/template/src/annotations/decorators/EnterprisePerformance.ts +9 -0
- package/template/src/annotations/decorators/PerformanceMonitor.ts +32 -0
- package/template/src/annotations/decorators/SecurityAudit.ts +9 -0
- package/template/src/annotations/index.ts +50 -0
- package/template/src/annotations/processors/ConfigManagementProcessor.ts +369 -0
- package/template/src/annotations/processors/DistributedTracingProcessor.ts +288 -0
- package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +189 -0
- package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +101 -0
- package/template/src/annotations/processors/SecurityAuditProcessor.ts +345 -0
- package/template/src/annotations/processors/SwaggerProcessor.ts +612 -0
- package/template/src/annotations/processors/index.ts +10 -0
- package/template/src/app.ts +123 -0
- package/template/src/controllers/base.controller.ts +41 -0
- package/template/src/controllers/cacheManagement.controller.ts +131 -0
- package/template/src/controllers/captcha.controller.ts +57 -0
- package/template/src/controllers/demo/AnnotationDemoController.ts +118 -0
- package/template/src/controllers/example/EnterpriseExampleController.ts +297 -0
- package/template/src/controllers/example/ExampleController.ts +110 -0
- package/template/src/controllers/example/NewAnnotationExampleController.ts +159 -0
- package/template/src/controllers/example/SwaggerExampleController.ts +205 -0
- package/template/src/controllers/example/TransactionExample.controller.ts +336 -0
- package/template/src/controllers/health.controller.ts +235 -0
- package/template/src/controllers/home/register.controller.ts +58 -0
- package/template/src/controllers/home/ytGoods.controller.ts +92 -0
- package/template/src/controllers/home/ytShop.controller.ts +135 -0
- package/template/src/controllers/home/ytUser.controller.ts +89 -0
- package/template/src/controllers/logManagement.controller.ts +396 -0
- package/template/src/controllers/public/emailSend.controller.ts +65 -0
- package/template/src/controllers/public/ytUserAuth.controller.ts +174 -0
- package/template/src/controllers/testData.controller.ts +253 -0
- package/template/src/dto/controller/example/NewAnnotationExampleController.dto.ts +73 -0
- package/template/src/dto/controller/home/emailSend.controller.dto.ts +40 -0
- package/template/src/dto/controller/home/register.controller.dto.ts +45 -0
- package/template/src/dto/controller/home/ytGoods.controller.dto.ts +55 -0
- package/template/src/dto/controller/home/ytShop.controller.dto.ts +69 -0
- package/template/src/dto/controller/home/ytUser.controller.dto.ts +44 -0
- package/template/src/dto/controller/public/ytUserAuth.controller.dto.ts +63 -0
- package/template/src/dto/goods.dto.ts +212 -0
- package/template/src/dto/service/ytService.dto.ts +13 -0
- package/template/src/dto/user.dto.ts +177 -0
- package/template/src/entity/base.entity.ts +13 -0
- package/template/src/entity/columnTypes.ts +13 -0
- package/template/src/entity/goodsImagesUnlockKey.entity.ts +33 -0
- package/template/src/entity/goodsUnlocker.entity.ts +34 -0
- package/template/src/entity/index.ts +15 -0
- package/template/src/entity/shop.entity.ts +52 -0
- package/template/src/entity/shopUser.entity.ts +41 -0
- package/template/src/entity/ytGoods.entity.ts +94 -0
- package/template/src/entity/ytUser.entity.ts +96 -0
- package/template/src/examples/InterceptorExampleRunner.ts +284 -0
- package/template/src/examples/ServiceInterceptorExample.ts +214 -0
- package/template/src/examples/SwaggerProcessorExample.ts +169 -0
- package/template/src/examples/TransactionManagerDemo.ts +377 -0
- package/template/src/examples/cacheExamples.ts +155 -0
- package/template/src/framework/decorator/controller.ts +311 -0
- package/template/src/framework/decorator/processor/AnnotationDecorators.ts +100 -0
- package/template/src/framework/decorator/processor/AnnotationProcessor.ts +156 -0
- package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +45 -0
- package/template/src/framework/decorator/processor/AnnotationRegistry.ts +117 -0
- package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +95 -0
- package/template/src/framework/decorator/processor/ProcessorManager.ts +76 -0
- package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +126 -0
- package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +207 -0
- package/template/src/framework/decorator/refactored/DecoratorFactory.ts +99 -0
- package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +125 -0
- package/template/src/framework/decorator/refactored/DecoratorValidator.ts +128 -0
- package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +139 -0
- package/template/src/framework/decorator/refactored/index.ts +98 -0
- package/template/src/framework/decorator/swagger.ts +150 -0
- package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +375 -0
- package/template/src/framework/interceptors/ServiceCallInterceptor.ts +348 -0
- package/template/src/framework/interceptors/index.ts +19 -0
- package/template/src/framework/plugins/registry.ts +63 -0
- package/template/src/framework/plugins/types.ts +15 -0
- package/template/src/framework/types/ServiceResult.ts +151 -0
- package/template/src/framework/types/index.ts +16 -0
- package/template/src/framework/utils/CacheManager.ts +430 -0
- package/template/src/framework/utils/CacheService.ts +248 -0
- package/template/src/framework/utils/DtoValidator.ts +164 -0
- package/template/src/framework/utils/MigrationHelper.ts +179 -0
- package/template/src/framework/utils/MigrationManager.ts +256 -0
- package/template/src/framework/utils/NewRouter.ts +207 -0
- package/template/src/framework/utils/TransactionManager.ts +172 -0
- package/template/src/framework/utils/bootstrap.ts +445 -0
- package/template/src/framework/utils/cache.ts +269 -0
- package/template/src/framework/utils/databaseConfig.ts +148 -0
- package/template/src/framework/utils/db.ts +39 -0
- package/template/src/framework/utils/dbMonitor.ts +106 -0
- package/template/src/framework/utils/dynamicSwagger.ts +410 -0
- package/template/src/framework/utils/function.ts +61 -0
- package/template/src/framework/utils/gracefulShutdown.ts +131 -0
- package/template/src/framework/utils/logger.ts +388 -0
- package/template/src/framework/utils/metrics.ts +182 -0
- package/template/src/framework/utils/router.ts +417 -0
- package/template/src/framework/utils/swagger.ts +184 -0
- package/template/src/framework/utils/testDb.ts +19 -0
- package/template/src/framework/utils/token.ts +23 -0
- package/template/src/framework/utils/transform.ts +17 -0
- package/template/src/libs/aokEmailSender.ts +42 -0
- package/template/src/libs/captcha.ts +37 -0
- package/template/src/libs/cos.ts +45 -0
- package/template/src/libs/mCache.ts +7 -0
- package/template/src/libs/serviceValidate.ts +3 -0
- package/template/src/libs/tecentSms.ts +51 -0
- package/template/src/middlewares/a.middleware.ts +6 -0
- package/template/src/middlewares/error.middleware.ts +14 -0
- package/template/src/middlewares/logging.middleware.ts +187 -0
- package/template/src/middlewares/static.middleware.ts +79 -0
- package/template/src/middlewares/swagger.middleware.ts +70 -0
- package/template/src/middlewares/token.middleware.ts +32 -0
- package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +172 -0
- package/template/src/migrations/index.ts +6 -0
- package/template/src/plugins/weboffice/core/context.ts +47 -0
- package/template/src/plugins/weboffice/core/errors.ts +51 -0
- package/template/src/plugins/weboffice/core/types.ts +63 -0
- package/template/src/plugins/weboffice/core/utils.ts +7 -0
- package/template/src/plugins/weboffice/entities/index.ts +3 -0
- package/template/src/plugins/weboffice/entities/webofficeFile.entity.ts +28 -0
- package/template/src/plugins/weboffice/entities/webofficeFileVersion.entity.ts +29 -0
- package/template/src/plugins/weboffice/http/routes.ts +179 -0
- package/template/src/plugins/weboffice/index.ts +23 -0
- package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +274 -0
- package/template/src/repository/UserRepository.ts +122 -0
- package/template/src/repository/base/BaseRepository.ts +124 -0
- package/template/src/repository/interfaces/IBaseRepository.ts +67 -0
- package/template/src/routers/index.ts +49 -0
- package/template/src/service/base.service.ts +116 -0
- package/template/src/service/paramValidateTest.service.ts +139 -0
- package/template/src/service/ytGoods.service.ts +42 -0
- package/template/src/service/ytShop.service.ts +90 -0
- package/template/src/service/ytUser.service.ts +451 -0
- package/template/src/test/swaggerParameterTest.ts +90 -0
- package/template/src/utils/testDataInitializer.ts +296 -0
- package/template/static/output.json +15203 -0
- package/template/test/controllers/controllers.test.ts +173 -0
- package/template/test/controllers/example/ExampleController.test.ts +222 -0
- package/template/test/controllers/example/NewAnnotationExampleController.test.ts +200 -0
- package/template/test/framework/TransactionManagerDemo.test.ts +363 -0
- package/template/test/framework/annotation/AnnotationDecorators.test.ts +222 -0
- package/template/test/framework/annotation/AnnotationExecutor.test.ts +246 -0
- package/template/test/framework/annotation/AnnotationProcessor.test.ts +179 -0
- package/template/test/framework/annotation/CustomProcessors.test.ts +313 -0
- package/template/test/framework/annotation/DefaultProcessors.test.ts +371 -0
- package/template/test/framework/annotation/NewRouter.test.ts +272 -0
- package/template/test/framework/annotation/ProcessorManager.test.ts +248 -0
- package/template/test/framework/annotation/setup.ts +26 -0
- package/template/test/framework/cache.test.ts +101 -0
- package/template/test/framework/databaseConfig.test.ts +142 -0
- package/template/test/integration/integration.test.ts +153 -0
- package/template/test/plugins/weboffice/http.routes.int.test.ts +61 -0
- package/template/test/service/business.test.ts +87 -0
- package/template/test/service/paramValidateTest.service.test.ts +184 -0
- package/template/test/service/ytUser.service.test.ts +566 -0
- package/template/test/setup.ts +20 -0
- package/template/test/setupAfterEnv.ts +14 -0
- package/template/test/utils/testHelpers.ts +220 -0
- package/template/test_output.txt +0 -0
- package/template/tsconfig.build.json +17 -0
- package/template/tsconfig.json +31 -0
- package/template/webpack.config.js +71 -0
- package/template/yarn.lock +7354 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import mount from "koa-mount";
|
|
3
|
+
import serve from "koa-static";
|
|
4
|
+
import { isDebug } from "@src/framework/utils/function";
|
|
5
|
+
|
|
6
|
+
export interface StaticMiddlewareOptions {
|
|
7
|
+
/**
|
|
8
|
+
* URL 前缀,例如:/static
|
|
9
|
+
* - 不建议以 / 结尾
|
|
10
|
+
*/
|
|
11
|
+
urlPrefix?: string;
|
|
12
|
+
/**
|
|
13
|
+
* 本地目录(相对项目根目录 process.cwd()),例如:assets / uploads
|
|
14
|
+
*/
|
|
15
|
+
dir?: string;
|
|
16
|
+
/**
|
|
17
|
+
* 生产环境缓存秒数(Cache-Control max-age)
|
|
18
|
+
*/
|
|
19
|
+
maxAgeSeconds?: number;
|
|
20
|
+
/**
|
|
21
|
+
* 访问前缀根路径时的默认文件,例如:index.html
|
|
22
|
+
* - false 表示不提供默认文件
|
|
23
|
+
*/
|
|
24
|
+
index?: string | false;
|
|
25
|
+
/**
|
|
26
|
+
* 是否在 next() 之后再尝试提供静态文件(默认 false,优先静态)
|
|
27
|
+
*/
|
|
28
|
+
defer?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* 是否允许访问隐藏文件(默认 false)
|
|
31
|
+
*/
|
|
32
|
+
hidden?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizePrefix(prefix: string): string {
|
|
36
|
+
let p = prefix.trim();
|
|
37
|
+
if (!p.startsWith("/")) p = `/${p}`;
|
|
38
|
+
// 只保留末尾非根路径的前缀(避免 /static/ 和 /static 产生差异)
|
|
39
|
+
if (p.length > 1 && p.endsWith("/")) p = p.slice(0, -1);
|
|
40
|
+
return p;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 静态文件映射中间件(基于 koa-static + koa-mount)
|
|
45
|
+
* - 默认:/static -> ./static
|
|
46
|
+
* - 支持环境变量覆盖:STATIC_URL_PREFIX、STATIC_DIR、STATIC_MAX_AGE_SECONDS、STATIC_INDEX
|
|
47
|
+
*/
|
|
48
|
+
export default function staticMiddleware(options: StaticMiddlewareOptions = {}) {
|
|
49
|
+
const urlPrefix = normalizePrefix(
|
|
50
|
+
options.urlPrefix ?? process.env.STATIC_URL_PREFIX ?? "/static"
|
|
51
|
+
);
|
|
52
|
+
const dir = options.dir ?? process.env.STATIC_DIR ?? "static";
|
|
53
|
+
const root = path.resolve(process.cwd(), dir);
|
|
54
|
+
const index =
|
|
55
|
+
options.index ??
|
|
56
|
+
(typeof process.env.STATIC_INDEX === "string"
|
|
57
|
+
? process.env.STATIC_INDEX
|
|
58
|
+
: false);
|
|
59
|
+
|
|
60
|
+
const maxAgeSeconds =
|
|
61
|
+
options.maxAgeSeconds ??
|
|
62
|
+
(process.env.STATIC_MAX_AGE_SECONDS
|
|
63
|
+
? Number(process.env.STATIC_MAX_AGE_SECONDS)
|
|
64
|
+
: !isDebug()
|
|
65
|
+
? 86400
|
|
66
|
+
: 0);
|
|
67
|
+
|
|
68
|
+
return mount(
|
|
69
|
+
urlPrefix,
|
|
70
|
+
serve(root, {
|
|
71
|
+
maxage: Math.max(0, maxAgeSeconds) * 1000,
|
|
72
|
+
index,
|
|
73
|
+
defer: options.defer ?? false,
|
|
74
|
+
hidden: options.hidden ?? false,
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { getSwaggerSpec } from '@src/framework/utils/swagger';
|
|
2
|
+
import { logger } from '@src/framework/utils/logger';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Swagger UI中间件 - 简化版本
|
|
6
|
+
*/
|
|
7
|
+
export function swaggerMiddleware() {
|
|
8
|
+
logger.info('Swagger UI已配置');
|
|
9
|
+
|
|
10
|
+
return async (ctx: any, next: any) => {
|
|
11
|
+
if (ctx.path === '/swagger') {
|
|
12
|
+
ctx.set('Content-Type', 'text/html');
|
|
13
|
+
ctx.body = `
|
|
14
|
+
<!DOCTYPE html>
|
|
15
|
+
<html>
|
|
16
|
+
<head>
|
|
17
|
+
<title>DP Koa Framework API文档</title>
|
|
18
|
+
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.25.0/swagger-ui.css" />
|
|
19
|
+
<style>
|
|
20
|
+
.topbar { display: none !important; }
|
|
21
|
+
.swagger-ui .info { margin: 20px 0; }
|
|
22
|
+
</style>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<div id="swagger-ui"></div>
|
|
26
|
+
<script src="https://unpkg.com/swagger-ui-dist@3.25.0/swagger-ui-bundle.js"></script>
|
|
27
|
+
<script>
|
|
28
|
+
SwaggerUIBundle({
|
|
29
|
+
url: '/swagger.json',
|
|
30
|
+
dom_id: '#swagger-ui',
|
|
31
|
+
presets: [
|
|
32
|
+
SwaggerUIBundle.presets.apis,
|
|
33
|
+
SwaggerUIBundle.presets.standalone
|
|
34
|
+
],
|
|
35
|
+
layout: "StandaloneLayout"
|
|
36
|
+
});
|
|
37
|
+
</script>
|
|
38
|
+
</body>
|
|
39
|
+
</html>
|
|
40
|
+
`;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await next();
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Swagger JSON端点
|
|
49
|
+
*/
|
|
50
|
+
export async function swaggerJson(ctx: any, next: any) {
|
|
51
|
+
if (ctx.path === '/swagger.json') {
|
|
52
|
+
try {
|
|
53
|
+
const swaggerSpec = getSwaggerSpec();
|
|
54
|
+
|
|
55
|
+
// 动态从Controller中提取Swagger信息
|
|
56
|
+
// 这里可以集成现有的路由系统来生成完整的文档
|
|
57
|
+
|
|
58
|
+
ctx.set('Content-Type', 'application/json');
|
|
59
|
+
ctx.body = swaggerSpec;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger.error('生成Swagger文档失败:', error as Error);
|
|
62
|
+
ctx.status = 500;
|
|
63
|
+
ctx.body = { error: '无法生成Swagger文档' };
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
await next();
|
|
69
|
+
}
|
|
70
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as jwt from "jsonwebtoken";
|
|
2
|
+
import { Context } from "koa";
|
|
3
|
+
import { getTokenFromHeader } from "@src/framework/utils/token";
|
|
4
|
+
|
|
5
|
+
export default function tokenMiddleware() {
|
|
6
|
+
|
|
7
|
+
return async (ctx: Context, next: Function) => {
|
|
8
|
+
// 1. 从请求头获取token
|
|
9
|
+
const token = getTokenFromHeader(ctx);
|
|
10
|
+
if (!token) {
|
|
11
|
+
ctx.status = 401;
|
|
12
|
+
ctx.body = { code: -1, message: "未提供认证token" };
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// 2. 验证token
|
|
18
|
+
const decoded = jwt.verify(token, process.env.jwt_secret ?? "123456") as any;
|
|
19
|
+
|
|
20
|
+
// 3. 将用户信息挂载到ctx.state
|
|
21
|
+
ctx.state.user = {
|
|
22
|
+
userId: decoded.userId,
|
|
23
|
+
type: decoded.type,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
await next();
|
|
27
|
+
} catch (err) {
|
|
28
|
+
ctx.status = 401;
|
|
29
|
+
ctx.body = { code: -1, message: "无效或过期的token" };
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 初始数据库结构迁移
|
|
5
|
+
* 创建所有基础表结构
|
|
6
|
+
*/
|
|
7
|
+
export class InitialDatabaseStructure1700000000000 implements MigrationInterface {
|
|
8
|
+
name = 'InitialDatabaseStructure1700000000000';
|
|
9
|
+
|
|
10
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
11
|
+
// 创建用户表
|
|
12
|
+
await queryRunner.query(`
|
|
13
|
+
CREATE TABLE \`yt_user\` (
|
|
14
|
+
\`id\` int NOT NULL AUTO_INCREMENT,
|
|
15
|
+
\`nickName\` varchar(255) NOT NULL DEFAULT '',
|
|
16
|
+
\`telnumber\` varchar(255) NOT NULL DEFAULT '',
|
|
17
|
+
\`email\` varchar(255) NOT NULL DEFAULT '',
|
|
18
|
+
\`password\` varchar(255) NOT NULL DEFAULT '',
|
|
19
|
+
\`userType\` varchar(50) NOT NULL DEFAULT 'CUSTOMER',
|
|
20
|
+
\`gender\` int NOT NULL DEFAULT '0',
|
|
21
|
+
\`age\` int NOT NULL DEFAULT '0',
|
|
22
|
+
\`constellation\` varchar(255) NOT NULL DEFAULT '',
|
|
23
|
+
\`avatar\` varchar(255) NOT NULL DEFAULT '',
|
|
24
|
+
\`status\` varchar(50) NOT NULL DEFAULT 'normal',
|
|
25
|
+
\`updateDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
26
|
+
\`createDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
27
|
+
PRIMARY KEY (\`id\`),
|
|
28
|
+
UNIQUE KEY \`IDX_yt_user_email\` (\`email\`),
|
|
29
|
+
UNIQUE KEY \`IDX_yt_user_telnumber\` (\`telnumber\`),
|
|
30
|
+
KEY \`IDX_yt_user_status\` (\`status\`),
|
|
31
|
+
KEY \`IDX_yt_user_userType\` (\`userType\`)
|
|
32
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
33
|
+
`);
|
|
34
|
+
|
|
35
|
+
// 创建店铺表
|
|
36
|
+
await queryRunner.query(`
|
|
37
|
+
CREATE TABLE \`shop\` (
|
|
38
|
+
\`id\` int NOT NULL AUTO_INCREMENT,
|
|
39
|
+
\`name\` varchar(255) NOT NULL DEFAULT '',
|
|
40
|
+
\`description\` varchar(255) NOT NULL DEFAULT '',
|
|
41
|
+
\`status\` varchar(50) NOT NULL DEFAULT 'NORMAL',
|
|
42
|
+
\`updateDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
43
|
+
\`createDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
44
|
+
PRIMARY KEY (\`id\`),
|
|
45
|
+
KEY \`IDX_shop_status\` (\`status\`)
|
|
46
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
47
|
+
`);
|
|
48
|
+
|
|
49
|
+
// 创建店铺用户关联表
|
|
50
|
+
await queryRunner.query(`
|
|
51
|
+
CREATE TABLE \`shop_and_user\` (
|
|
52
|
+
\`id\` int NOT NULL AUTO_INCREMENT,
|
|
53
|
+
\`shopId\` int NOT NULL DEFAULT '0',
|
|
54
|
+
\`userId\` int NOT NULL DEFAULT '0',
|
|
55
|
+
\`updateDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
56
|
+
\`createDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
57
|
+
PRIMARY KEY (\`id\`),
|
|
58
|
+
UNIQUE KEY \`IDX_shop_and_user_shopId\` (\`shopId\`),
|
|
59
|
+
UNIQUE KEY \`IDX_shop_and_user_userId\` (\`userId\`),
|
|
60
|
+
KEY \`IDX_shop_and_user_shopId_userId\` (\`shopId\`, \`userId\`)
|
|
61
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
62
|
+
`);
|
|
63
|
+
|
|
64
|
+
// 创建商品表
|
|
65
|
+
await queryRunner.query(`
|
|
66
|
+
CREATE TABLE \`yt_goods\` (
|
|
67
|
+
\`id\` int NOT NULL AUTO_INCREMENT,
|
|
68
|
+
\`name\` varchar(255) NOT NULL DEFAULT '',
|
|
69
|
+
\`shopId\` int NOT NULL DEFAULT '0',
|
|
70
|
+
\`albums\` text NOT NULL,
|
|
71
|
+
\`price\` decimal(10,2) NOT NULL DEFAULT '0.00',
|
|
72
|
+
\`tags\` text NOT NULL,
|
|
73
|
+
\`description\` varchar(255) NOT NULL DEFAULT '',
|
|
74
|
+
\`content\` text NOT NULL,
|
|
75
|
+
\`imagesContent\` text NOT NULL,
|
|
76
|
+
\`status\` varchar(50) NOT NULL DEFAULT 'NORMAL',
|
|
77
|
+
\`updateDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
78
|
+
\`createDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
79
|
+
PRIMARY KEY (\`id\`),
|
|
80
|
+
KEY \`IDX_yt_goods_name\` (\`name\`),
|
|
81
|
+
KEY \`IDX_yt_goods_shopId\` (\`shopId\`),
|
|
82
|
+
KEY \`IDX_yt_goods_status\` (\`status\`)
|
|
83
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
84
|
+
`);
|
|
85
|
+
|
|
86
|
+
// 创建商品解锁记录表
|
|
87
|
+
await queryRunner.query(`
|
|
88
|
+
CREATE TABLE \`yt_goods_unlock\` (
|
|
89
|
+
\`id\` int NOT NULL AUTO_INCREMENT,
|
|
90
|
+
\`goodsId\` int NOT NULL DEFAULT '0',
|
|
91
|
+
\`ytUserId\` int NOT NULL DEFAULT '0',
|
|
92
|
+
\`updateDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
93
|
+
\`createDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
94
|
+
PRIMARY KEY (\`id\`),
|
|
95
|
+
KEY \`IDX_yt_goods_unlock_goodsId\` (\`goodsId\`),
|
|
96
|
+
KEY \`IDX_yt_goods_unlock_ytUserId\` (\`ytUserId\`),
|
|
97
|
+
UNIQUE KEY \`IDX_yt_goods_unlock_goods_user\` (\`goodsId\`, \`ytUserId\`)
|
|
98
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
99
|
+
`);
|
|
100
|
+
|
|
101
|
+
// 创建商品图片解锁密钥表
|
|
102
|
+
await queryRunner.query(`
|
|
103
|
+
CREATE TABLE \`goods_images_unlock_key\` (
|
|
104
|
+
\`id\` int NOT NULL AUTO_INCREMENT,
|
|
105
|
+
\`key\` varchar(255) NOT NULL DEFAULT '',
|
|
106
|
+
\`goodsId\` int NOT NULL DEFAULT '0',
|
|
107
|
+
\`isUse\` tinyint(1) NOT NULL DEFAULT '0',
|
|
108
|
+
\`updateDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
109
|
+
\`createDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
110
|
+
PRIMARY KEY (\`id\`),
|
|
111
|
+
UNIQUE KEY \`IDX_goods_images_unlock_key_key\` (\`key\`),
|
|
112
|
+
KEY \`IDX_goods_images_unlock_key_goodsId\` (\`goodsId\`),
|
|
113
|
+
KEY \`IDX_goods_images_unlock_key_isUse\` (\`isUse\`)
|
|
114
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
115
|
+
`);
|
|
116
|
+
|
|
117
|
+
// 添加外键约束
|
|
118
|
+
await queryRunner.query(`
|
|
119
|
+
ALTER TABLE \`shop_and_user\`
|
|
120
|
+
ADD CONSTRAINT \`FK_shop_and_user_shopId\`
|
|
121
|
+
FOREIGN KEY (\`shopId\`) REFERENCES \`shop\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
|
|
122
|
+
`);
|
|
123
|
+
|
|
124
|
+
await queryRunner.query(`
|
|
125
|
+
ALTER TABLE \`shop_and_user\`
|
|
126
|
+
ADD CONSTRAINT \`FK_shop_and_user_userId\`
|
|
127
|
+
FOREIGN KEY (\`userId\`) REFERENCES \`yt_user\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
|
|
128
|
+
`);
|
|
129
|
+
|
|
130
|
+
await queryRunner.query(`
|
|
131
|
+
ALTER TABLE \`yt_goods\`
|
|
132
|
+
ADD CONSTRAINT \`FK_yt_goods_shopId\`
|
|
133
|
+
FOREIGN KEY (\`shopId\`) REFERENCES \`shop\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
|
|
134
|
+
`);
|
|
135
|
+
|
|
136
|
+
await queryRunner.query(`
|
|
137
|
+
ALTER TABLE \`yt_goods_unlock\`
|
|
138
|
+
ADD CONSTRAINT \`FK_yt_goods_unlock_goodsId\`
|
|
139
|
+
FOREIGN KEY (\`goodsId\`) REFERENCES \`yt_goods\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
|
|
140
|
+
`);
|
|
141
|
+
|
|
142
|
+
await queryRunner.query(`
|
|
143
|
+
ALTER TABLE \`yt_goods_unlock\`
|
|
144
|
+
ADD CONSTRAINT \`FK_yt_goods_unlock_ytUserId\`
|
|
145
|
+
FOREIGN KEY (\`ytUserId\`) REFERENCES \`yt_user\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
|
|
146
|
+
`);
|
|
147
|
+
|
|
148
|
+
await queryRunner.query(`
|
|
149
|
+
ALTER TABLE \`goods_images_unlock_key\`
|
|
150
|
+
ADD CONSTRAINT \`FK_goods_images_unlock_key_goodsId\`
|
|
151
|
+
FOREIGN KEY (\`goodsId\`) REFERENCES \`yt_goods\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
|
|
152
|
+
`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
156
|
+
// 删除外键约束
|
|
157
|
+
await queryRunner.query(`ALTER TABLE \`goods_images_unlock_key\` DROP FOREIGN KEY \`FK_goods_images_unlock_key_goodsId\``);
|
|
158
|
+
await queryRunner.query(`ALTER TABLE \`yt_goods_unlock\` DROP FOREIGN KEY \`FK_yt_goods_unlock_ytUserId\``);
|
|
159
|
+
await queryRunner.query(`ALTER TABLE \`yt_goods_unlock\` DROP FOREIGN KEY \`FK_yt_goods_unlock_goodsId\``);
|
|
160
|
+
await queryRunner.query(`ALTER TABLE \`yt_goods\` DROP FOREIGN KEY \`FK_yt_goods_shopId\``);
|
|
161
|
+
await queryRunner.query(`ALTER TABLE \`shop_and_user\` DROP FOREIGN KEY \`FK_shop_and_user_userId\``);
|
|
162
|
+
await queryRunner.query(`ALTER TABLE \`shop_and_user\` DROP FOREIGN KEY \`FK_shop_and_user_shopId\``);
|
|
163
|
+
|
|
164
|
+
// 删除表
|
|
165
|
+
await queryRunner.query(`DROP TABLE \`goods_images_unlock_key\``);
|
|
166
|
+
await queryRunner.query(`DROP TABLE \`yt_goods_unlock\``);
|
|
167
|
+
await queryRunner.query(`DROP TABLE \`yt_goods\``);
|
|
168
|
+
await queryRunner.query(`DROP TABLE \`shop_and_user\``);
|
|
169
|
+
await queryRunner.query(`DROP TABLE \`shop\``);
|
|
170
|
+
await queryRunner.query(`DROP TABLE \`yt_user\``);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { WebOfficeContext } from "./types";
|
|
2
|
+
|
|
3
|
+
const X_APP_ID = "x-app-id";
|
|
4
|
+
const X_WEBOFFICE_TOKEN = "x-weboffice-token";
|
|
5
|
+
const X_REQUEST_ID = "x-request-id";
|
|
6
|
+
const X_USER_QUERY = "x-user-query";
|
|
7
|
+
|
|
8
|
+
function parseQuery(header: string | undefined): Record<string, string | string[] | undefined> {
|
|
9
|
+
if (!header) return {};
|
|
10
|
+
try {
|
|
11
|
+
const params = new URLSearchParams(header);
|
|
12
|
+
const out: Record<string, string | string[] | undefined> = {};
|
|
13
|
+
params.forEach((value, key) => {
|
|
14
|
+
const existing = out[key];
|
|
15
|
+
if (existing === undefined) out[key] = value;
|
|
16
|
+
else if (Array.isArray(existing)) existing.push(value);
|
|
17
|
+
else out[key] = [existing, value];
|
|
18
|
+
});
|
|
19
|
+
return out;
|
|
20
|
+
} catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getQueryToken(query: Record<string, string | string[] | undefined> | undefined): string {
|
|
26
|
+
if (!query?.token) return "";
|
|
27
|
+
const t = query.token;
|
|
28
|
+
return Array.isArray(t) ? (t[0] ?? "") : (t ?? "");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function parseWebOfficeContext(ctx: {
|
|
32
|
+
request: {
|
|
33
|
+
headers: Record<string, string | string[] | undefined>;
|
|
34
|
+
query?: Record<string, string | string[] | undefined>;
|
|
35
|
+
};
|
|
36
|
+
}): WebOfficeContext {
|
|
37
|
+
const headers = ctx.request.headers;
|
|
38
|
+
const headerToken = (headers[X_WEBOFFICE_TOKEN] as string) || "";
|
|
39
|
+
const token = headerToken || getQueryToken(ctx.request.query);
|
|
40
|
+
return {
|
|
41
|
+
appId: (headers[X_APP_ID] as string) || "",
|
|
42
|
+
token,
|
|
43
|
+
requestId: (headers[X_REQUEST_ID] as string) || "",
|
|
44
|
+
query: parseQuery(headers[X_USER_QUERY] as string),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const OK = 0;
|
|
2
|
+
|
|
3
|
+
export const WebOfficeErrorCode = {
|
|
4
|
+
Unauthorized: 40002,
|
|
5
|
+
PermissionDenied: 40003,
|
|
6
|
+
FileNotExists: 40004,
|
|
7
|
+
InvalidArguments: 40005,
|
|
8
|
+
SpaceFull: 40006,
|
|
9
|
+
CustomMessage: 40007,
|
|
10
|
+
FileNameConflict: 40008,
|
|
11
|
+
FileVersionNotExists: 40009,
|
|
12
|
+
UserNotExists: 40010,
|
|
13
|
+
InternalError: 50001,
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
export class WebOfficeError extends Error {
|
|
17
|
+
constructor(
|
|
18
|
+
public readonly code: number,
|
|
19
|
+
public readonly statusCode: number,
|
|
20
|
+
message: string
|
|
21
|
+
) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = "WebOfficeError";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
withMessage(msg: string): WebOfficeError {
|
|
27
|
+
return new WebOfficeError(this.code, this.statusCode, msg);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const ErrFileNotExists = new WebOfficeError(
|
|
32
|
+
WebOfficeErrorCode.FileNotExists,
|
|
33
|
+
403,
|
|
34
|
+
"file not exists"
|
|
35
|
+
);
|
|
36
|
+
export const ErrInvalidArguments = new WebOfficeError(
|
|
37
|
+
WebOfficeErrorCode.InvalidArguments,
|
|
38
|
+
403,
|
|
39
|
+
"invalid arguments"
|
|
40
|
+
);
|
|
41
|
+
export const ErrFileVersionNotExists = new WebOfficeError(
|
|
42
|
+
WebOfficeErrorCode.FileVersionNotExists,
|
|
43
|
+
403,
|
|
44
|
+
"file version not exists"
|
|
45
|
+
);
|
|
46
|
+
export const ErrInternalError = new WebOfficeError(
|
|
47
|
+
WebOfficeErrorCode.InternalError,
|
|
48
|
+
500,
|
|
49
|
+
"internal error"
|
|
50
|
+
);
|
|
51
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface WebOfficeContext {
|
|
2
|
+
appId: string;
|
|
3
|
+
token: string;
|
|
4
|
+
requestId: string;
|
|
5
|
+
query: Record<string, string | string[] | undefined>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface GetFileReply {
|
|
9
|
+
create_time: number;
|
|
10
|
+
creator_id: string;
|
|
11
|
+
id: string;
|
|
12
|
+
modifier_id: string;
|
|
13
|
+
modify_time: number;
|
|
14
|
+
name: string;
|
|
15
|
+
size: number;
|
|
16
|
+
version: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface GetFileDownloadReply {
|
|
20
|
+
url: string;
|
|
21
|
+
digest: string;
|
|
22
|
+
digest_type: string;
|
|
23
|
+
headers: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface GetFilePermissionReply {
|
|
27
|
+
comment: number;
|
|
28
|
+
copy: number;
|
|
29
|
+
download: number;
|
|
30
|
+
history: number;
|
|
31
|
+
print: number;
|
|
32
|
+
read: number;
|
|
33
|
+
rename: number;
|
|
34
|
+
saveas: number;
|
|
35
|
+
update: number;
|
|
36
|
+
user_id: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface WebOfficeUser {
|
|
40
|
+
id: string;
|
|
41
|
+
name: string;
|
|
42
|
+
avatar_url: string;
|
|
43
|
+
logined: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface GetWatermarkReply {
|
|
47
|
+
type: number;
|
|
48
|
+
value: string;
|
|
49
|
+
fill_style: string;
|
|
50
|
+
font: string;
|
|
51
|
+
rotate: number;
|
|
52
|
+
horizontal: number;
|
|
53
|
+
vertical: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface UpdateFile1PhaseArgs {
|
|
57
|
+
name: string;
|
|
58
|
+
size: number;
|
|
59
|
+
sha1: string;
|
|
60
|
+
isManual: boolean;
|
|
61
|
+
filePath: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Column, Entity, OneToMany } from "typeorm";
|
|
2
|
+
import { BaseEntity } from "@src/entity/base.entity";
|
|
3
|
+
import { WebofficeFileVersionEntity } from "./webofficeFileVersion.entity";
|
|
4
|
+
|
|
5
|
+
@Entity({ name: "weboffice_files" })
|
|
6
|
+
export class WebofficeFileEntity extends BaseEntity {
|
|
7
|
+
@Column({ type: "varchar", length: 128, unique: true })
|
|
8
|
+
fileId: string;
|
|
9
|
+
|
|
10
|
+
@Column({ type: "varchar", length: 512 })
|
|
11
|
+
name: string;
|
|
12
|
+
|
|
13
|
+
@Column({ type: "varchar", length: 128, default: "" })
|
|
14
|
+
creatorId: string;
|
|
15
|
+
|
|
16
|
+
@Column({ type: "varchar", length: 128, default: "" })
|
|
17
|
+
modifierId: string;
|
|
18
|
+
|
|
19
|
+
@Column({ type: "int", default: 1 })
|
|
20
|
+
currentVersion: number;
|
|
21
|
+
|
|
22
|
+
@Column({ type: "int", nullable: true })
|
|
23
|
+
projectId: number | null;
|
|
24
|
+
|
|
25
|
+
@OneToMany(() => WebofficeFileVersionEntity, (v) => v.webofficeFile)
|
|
26
|
+
versions?: WebofficeFileVersionEntity[];
|
|
27
|
+
}
|
|
28
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Column, Entity, ManyToOne, JoinColumn } from "typeorm";
|
|
2
|
+
import { BaseEntity } from "@src/entity/base.entity";
|
|
3
|
+
import { WebofficeFileEntity } from "./webofficeFile.entity";
|
|
4
|
+
|
|
5
|
+
@Entity({ name: "weboffice_file_versions" })
|
|
6
|
+
export class WebofficeFileVersionEntity extends BaseEntity {
|
|
7
|
+
@ManyToOne(() => WebofficeFileEntity, (f) => f.versions, { onDelete: "CASCADE" })
|
|
8
|
+
@JoinColumn({ name: "webofficeFileId" })
|
|
9
|
+
webofficeFile: WebofficeFileEntity;
|
|
10
|
+
|
|
11
|
+
@Column()
|
|
12
|
+
webofficeFileId: number;
|
|
13
|
+
|
|
14
|
+
@Column({ type: "int" })
|
|
15
|
+
version: number;
|
|
16
|
+
|
|
17
|
+
@Column({ type: "bigint", default: 0 })
|
|
18
|
+
size: number;
|
|
19
|
+
|
|
20
|
+
@Column({ type: "varchar", length: 64, default: "" })
|
|
21
|
+
digest: string;
|
|
22
|
+
|
|
23
|
+
@Column({ type: "varchar", length: 512 })
|
|
24
|
+
cosKey: string;
|
|
25
|
+
|
|
26
|
+
@Column({ type: "varchar", length: 128, default: "" })
|
|
27
|
+
creatorId: string;
|
|
28
|
+
}
|
|
29
|
+
|