| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn, OneToMany } from 'typeorm';
- import { UserEntity } from '../users/user.entity';
- import { SilverKnowledgeCategory } from './silver-knowledge-category.entity';
- import { SilverKnowledgeInteraction } from './silver-knowledge-interaction.entity';
- import { SilverKnowledgeTagRelation } from './silver-knowledge-tag-relation.entity';
- import { z } from '@hono/zod-openapi';
- export enum KnowledgeType {
- ARTICLE = 1, // 文章
- VIDEO = 2, // 视频
- DOCUMENT = 3, // 文档
- COURSE = 4, // 课程
- EXPERIENCE = 5, // 经验分享
- CASE = 6, // 案例分享
- RESEARCH = 7 // 研究报告
- }
- export enum KnowledgeStatus {
- DRAFT = 0, // 草稿
- PUBLISHED = 1, // 已发布
- HIDDEN = 2, // 已隐藏
- DELETED = 3, // 已删除
- REVIEWING = 4 // 审核中
- }
- @Entity('silver_knowledges')
- export class SilverKnowledge {
- @PrimaryGeneratedColumn({ unsigned: true })
- id!: number;
- @Column({ name: 'user_id', type: 'int', unsigned: true })
- userId!: number;
- @ManyToOne(() => UserEntity, user => user.silverKnowledges)
- @JoinColumn({ name: 'user_id' })
- user!: UserEntity;
- @Column({ name: 'category_id', type: 'int', unsigned: true, nullable: true })
- categoryId!: number | null;
- @ManyToOne(() => SilverKnowledgeCategory, category => category.silverKnowledges)
- @JoinColumn({ name: 'category_id' })
- category!: SilverKnowledgeCategory | null;
- @Column({ name: 'title', type: 'varchar', length: 255 })
- title!: string;
- @Column({ name: 'content', type: 'text' })
- content!: string;
- @Column({ name: 'summary', type: 'text', nullable: true })
- summary!: string | null;
- @Column({ name: 'type', type: 'tinyint', unsigned: true })
- type!: KnowledgeType;
- @Column({ name: 'tags', type: 'text', nullable: true })
- tags!: string | null; // JSON array of tags
- @Column({ name: 'cover_image', type: 'varchar', length: 500, nullable: true })
- coverImage!: string | null;
- @Column({ name: 'attachments', type: 'text', nullable: true })
- attachments!: string | null; // JSON array of attachment URLs
- @Column({ name: 'status', type: 'tinyint', default: KnowledgeStatus.DRAFT })
- status!: KnowledgeStatus;
- // 统计字段 - 单个知识统计
- @Column({ name: 'view_count', type: 'int', unsigned: true, default: 0 })
- viewCount!: number;
- @Column({ name: 'download_count', type: 'int', unsigned: true, default: 0 })
- downloadCount!: number;
- @Column({ name: 'like_count', type: 'int', unsigned: true, default: 0 })
- likeCount!: number;
- @Column({ name: 'comment_count', type: 'int', unsigned: true, default: 0 })
- commentCount!: number;
- @Column({ name: 'favorite_count', type: 'int', unsigned: true, default: 0 })
- favoriteCount!: number;
- @Column({ name: 'share_count', type: 'int', unsigned: true, default: 0 })
- shareCount!: number;
- @Column({ name: 'read_count', type: 'int', unsigned: true, default: 0 })
- readCount!: number; // 更准确的阅读统计
- // 推荐和排序
- @Column({ name: 'is_featured', type: 'tinyint', default: 0 })
- isFeatured!: number;
- @Column({ name: 'featured_at', type: 'timestamp', nullable: true })
- featuredAt!: Date | null;
- @Column({ name: 'sort_order', type: 'int', default: 0 })
- sortOrder!: number;
- // 元数据
- @Column({ name: 'keywords', type: 'text', nullable: true })
- keywords!: string | null; // 用于搜索优化的关键词
- @Column({ name: 'source', type: 'varchar', length: 255, nullable: true })
- source!: string | null; // 知识来源
- @Column({ name: 'author', type: 'varchar', length: 100, nullable: true })
- author!: string | null; // 原作者
- @Column({ name: 'duration', type: 'int', unsigned: true, nullable: true })
- duration!: number | null; // 视频时长(秒)或阅读时长(分钟)
- // 时间戳
- @CreateDateColumn({ name: 'created_at' })
- createdAt!: Date;
- @UpdateDateColumn({ name: 'updated_at' })
- updatedAt!: Date;
- @Column({ name: 'published_at', type: 'timestamp', nullable: true })
- publishedAt!: Date | null;
- // 用户跟踪
- @Column({ name: 'created_by', type: 'int', nullable: true })
- createdBy!: number | null;
- @Column({ name: 'updated_by', type: 'int', nullable: true })
- updatedBy!: number | null;
- @OneToMany(() => SilverKnowledgeInteraction, interaction => interaction.knowledge)
- silverKnowledgeInteractions!: SilverKnowledgeInteraction[];
- @OneToMany(() => SilverKnowledgeTagRelation, tagRelation => tagRelation.knowledge)
- silverKnowledgeTagRelations!: SilverKnowledgeTagRelation[];
- }
- // Zod Schema定义
- export const SilverKnowledgeSchema = z.object({
- id: z.number().int().positive().openapi({
- description: '知识ID',
- example: 1
- }),
- userId: z.number().int().positive().openapi({
- description: '发布用户ID',
- example: 1
- }),
- user: UserSchema.optional().openapi({
- description: '发布用户',
- example: {
- id: 1,
- username: 'user123',
- nickname: '张三'
- }
- }),
- categoryId: z.number().int().positive().optional().nullable().openapi({
- description: '分类ID',
- example: 5
- }),
- category: SilverKnowledgeCategorySchema.optional().nullable().openapi({
- description: '知识分类',
- example: {
- id: 5,
- name: '健康养生'
- }
- }),
- title: z.string().max(255).openapi({
- description: '知识标题',
- example: '老年人健康饮食指南'
- }),
- content: z.string().openapi({
- description: '知识内容',
- example: '老年人健康饮食需要注意以下几点...'
- }),
- summary: z.string().optional().openapi({
- description: '知识摘要',
- example: '本指南详细介绍了老年人健康饮食的科学方法...'
- }),
- type: z.coerce.number().int().min(1).max(7).openapi({
- description: '知识类型 1:文章 2:视频 3:文档 4:课程 5:经验分享 6:案例分享 7:研究报告',
- example: 1
- }),
- tags: z.string().optional().nullable().openapi({
- description: '标签(JSON数组)',
- example: '["健康养生", "老年人", "饮食"]'
- }),
- coverImage: z.string().max(500).url().optional().nullable().openapi({
- description: '封面图片URL',
- example: 'https://example.com/cover.jpg'
- }),
- attachments: z.string().optional().nullable().openapi({
- description: '附件URL(JSON数组)',
- example: '["https://example.com/attach1.pdf"]'
- }),
- status: z.coerce.number().int().min(0).max(4).default(0).openapi({
- description: '状态 0:草稿 1:已发布 2:已隐藏 3:已删除 4:审核中',
- example: 1
- }),
- viewCount: z.number().int().min(0).default(0).openapi({
- description: '浏览次数',
- example: 1234
- }),
- downloadCount: z.number().int().min(0).default(0).openapi({
- description: '下载次数',
- example: 567
- }),
- likeCount: z.number().int().min(0).default(0).openapi({
- description: '点赞次数',
- example: 234
- }),
- commentCount: z.number().int().min(0).default(0).openapi({
- description: '评论次数',
- example: 89
- }),
- favoriteCount: z.number().int().min(0).default(0).openapi({
- description: '收藏次数',
- example: 156
- }),
- shareCount: z.number().int().min(0).default(0).openapi({
- description: '分享次数',
- example: 78
- }),
- readCount: z.number().int().min(0).default(0).openapi({
- description: '阅读次数',
- example: 2345
- }),
- isFeatured: z.coerce.number().int().min(0).max(1).default(0).openapi({
- description: '是否推荐 0:否 1:是',
- example: 1
- }),
- featuredAt: z.date().optional().nullable().openapi({
- description: '推荐时间',
- example: '2024-01-01T00:00:00Z'
- }),
- sortOrder: z.number().int().default(0).openapi({
- description: '排序顺序',
- example: 1
- }),
- keywords: z.string().optional().nullable().openapi({
- description: '搜索关键词',
- example: '健康,养生,老年人'
- }),
- source: z.string().max(255).optional().nullable().openapi({
- description: '知识来源',
- example: '中国老年学会'
- }),
- author: z.string().max(100).optional().nullable().openapi({
- description: '原作者',
- example: '张医生'
- }),
- duration: z.number().int().positive().optional().nullable().openapi({
- description: '时长(秒/分钟)',
- example: 15
- }),
- createdAt: z.date().openapi({
- description: '创建时间',
- example: '2024-01-01T00:00:00Z'
- }),
- updatedAt: z.date().openapi({
- description: '更新时间',
- example: '2024-01-01T00:00:00Z'
- }),
- publishedAt: z.date().optional().nullable().openapi({
- description: '发布时间',
- example: '2024-01-01T00:00:00Z'
- })
- });
- export const CreateSilverKnowledgeDto = z.object({
- userId: z.coerce.number().int().positive().openapi({
- description: '发布用户ID',
- example: 1
- }),
- categoryId: z.number().int().positive().optional().openapi({
- description: '分类ID',
- example: 5
- }),
- title: z.string().max(255).openapi({
- description: '知识标题',
- example: '老年人健康饮食指南'
- }),
- content: z.string().openapi({
- description: '知识内容',
- example: '老年人健康饮食需要注意以下几点...'
- }),
- summary: z.string().optional().openapi({
- description: '知识摘要',
- example: '本指南详细介绍了老年人健康饮食的科学方法...'
- }),
- type: z.coerce.number().int().min(1).max(7).openapi({
- description: '知识类型',
- example: 1
- }),
- tags: z.string().optional().openapi({
- description: '标签(JSON数组)',
- example: '["健康养生", "老年人", "饮食"]'
- }),
- coverImage: z.string().max(500).url().optional().openapi({
- description: '封面图片URL',
- example: 'https://example.com/cover.jpg'
- }),
- attachments: z.string().optional().openapi({
- description: '附件URL(JSON数组)',
- example: '["https://example.com/attach1.pdf"]'
- }),
- keywords: z.string().optional().openapi({
- description: '搜索关键词',
- example: '健康,养生,老年人'
- }),
- source: z.string().max(255).optional().openapi({
- description: '知识来源',
- example: '中国老年学会'
- }),
- author: z.string().max(100).optional().openapi({
- description: '原作者',
- example: '张医生'
- }),
- duration: z.number().int().positive().optional().openapi({
- description: '时长(秒/分钟)',
- example: 15
- })
- });
- export const UpdateSilverKnowledgeDto = z.object({
- categoryId: z.number().int().positive().optional().openapi({
- description: '分类ID',
- example: 5
- }),
- title: z.string().max(255).optional().openapi({
- description: '知识标题',
- example: '老年人健康饮食指南'
- }),
- content: z.string().optional().openapi({
- description: '知识内容',
- example: '老年人健康饮食需要注意以下几点...'
- }),
- summary: z.string().optional().openapi({
- description: '知识摘要',
- example: '本指南详细介绍了老年人健康饮食的科学方法...'
- }),
- type: z.coerce.number().int().min(1).max(7).optional().openapi({
- description: '知识类型',
- example: 1
- }),
- tags: z.string().optional().openapi({
- description: '标签(JSON数组)',
- example: '["健康养生", "老年人", "饮食"]'
- }),
- coverImage: z.string().max(500).url().optional().openapi({
- description: '封面图片URL',
- example: 'https://example.com/cover.jpg'
- }),
- attachments: z.string().optional().openapi({
- description: '附件URL(JSON数组)',
- example: '["https://example.com/attach1.pdf"]'
- }),
- status: z.coerce.number().int().min(0).max(4).optional().openapi({
- description: '状态',
- example: 1
- }),
- keywords: z.string().optional().openapi({
- description: '搜索关键词',
- example: '健康,养生,老年人'
- }),
- source: z.string().max(255).optional().openapi({
- description: '知识来源',
- example: '中国老年学会'
- }),
- author: z.string().max(100).optional().openapi({
- description: '原作者',
- example: '张医生'
- }),
- duration: z.number().int().positive().optional().openapi({
- description: '时长(秒/分钟)',
- example: 15
- }),
- isFeatured: z.coerce.number().int().min(0).max(1).optional().openapi({
- description: '是否推荐',
- example: 1
- }),
- featuredAt: z.date().optional().nullable().openapi({
- description: '推荐时间',
- example: '2024-01-01T00:00:00Z'
- }),
- sortOrder: z.number().int().optional().openapi({
- description: '排序顺序',
- example: 1
- })
- });
|