feat(health): 随访模板系统 — follow_up_template + template_field 全栈
新增随访模板和模板字段两张表及完整 CRUD: - 迁移 083: follow_up_template + follow_up_template_field - Entity: 模板(名称/类型/适用范围/状态) + 字段(标签/键名/类型/选项/校验) - DTO: 创建时内嵌字段列表、更新支持全量替换字段 - Service: 随访类型+字段类型校验、级联软删除 - Handler: 5 端点 + RBAC 权限 - 路由: /api/v1/health/follow-up-templates
This commit is contained in:
@@ -82,6 +82,7 @@ mod m20260427_000079_add_vital_signs_fields;
|
||||
mod m20260427_000080_create_medication_record;
|
||||
mod m20260427_000081_create_dialysis_prescription;
|
||||
mod m20260427_000082_seed_ai_prompts;
|
||||
mod m20260427_000083_create_follow_up_template;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
@@ -171,6 +172,7 @@ impl MigratorTrait for Migrator {
|
||||
Box::new(m20260427_000080_create_medication_record::Migration),
|
||||
Box::new(m20260427_000081_create_dialysis_prescription::Migration),
|
||||
Box::new(m20260427_000082_seed_ai_prompts::Migration),
|
||||
Box::new(m20260427_000083_create_follow_up_template::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// 随访模板主表
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Alias::new("follow_up_template"))
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(Alias::new("id")).uuid().not_null().primary_key())
|
||||
.col(ColumnDef::new(Alias::new("tenant_id")).uuid().not_null())
|
||||
// 模板名称
|
||||
.col(ColumnDef::new(Alias::new("name")).string_len(200).not_null())
|
||||
// 模板描述
|
||||
.col(ColumnDef::new(Alias::new("description")).text().null())
|
||||
// 随访类型: phone/outpatient/home_visit/online/wechat
|
||||
.col(ColumnDef::new(Alias::new("follow_up_type")).string_len(20).not_null())
|
||||
// 适用疾病/科室(JSON 数组)
|
||||
.col(ColumnDef::new(Alias::new("applicable_scope")).text().null())
|
||||
// 状态: active/disabled
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("status"))
|
||||
.string_len(20)
|
||||
.not_null()
|
||||
.default("active"),
|
||||
)
|
||||
// 标准审计字段
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("created_at"))
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("updated_at"))
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.col(ColumnDef::new(Alias::new("created_by")).uuid().null())
|
||||
.col(ColumnDef::new(Alias::new("updated_by")).uuid().null())
|
||||
.col(ColumnDef::new(Alias::new("deleted_at")).timestamp_with_time_zone().null())
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("version"))
|
||||
.integer()
|
||||
.not_null()
|
||||
.default(1),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.if_not_exists()
|
||||
.name("idx_follow_up_template_tenant_id")
|
||||
.table(Alias::new("follow_up_template"))
|
||||
.col(Alias::new("tenant_id"))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// 模板字段表
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Alias::new("follow_up_template_field"))
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(Alias::new("id")).uuid().not_null().primary_key())
|
||||
.col(ColumnDef::new(Alias::new("tenant_id")).uuid().not_null())
|
||||
.col(ColumnDef::new(Alias::new("template_id")).uuid().not_null())
|
||||
// 字段标签
|
||||
.col(ColumnDef::new(Alias::new("label")).string_len(200).not_null())
|
||||
// 字段键名(用于程序引用)
|
||||
.col(ColumnDef::new(Alias::new("field_key")).string_len(100).not_null())
|
||||
// 字段类型: text/number/date/select/checkbox/textarea/scale
|
||||
.col(ColumnDef::new(Alias::new("field_type")).string_len(20).not_null())
|
||||
// 是否必填
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("required"))
|
||||
.boolean()
|
||||
.not_null()
|
||||
.default(false),
|
||||
)
|
||||
// 选项(JSON 数组,select/checkbox 时使用)
|
||||
.col(ColumnDef::new(Alias::new("options")).text().null())
|
||||
// 占位提示
|
||||
.col(ColumnDef::new(Alias::new("placeholder")).string_len(200).null())
|
||||
// 校验规则(JSON)
|
||||
.col(ColumnDef::new(Alias::new("validation")).text().null())
|
||||
// 排序序号
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("sort_order"))
|
||||
.integer()
|
||||
.not_null()
|
||||
.default(0),
|
||||
)
|
||||
// 标准审计字段
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("created_at"))
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("updated_at"))
|
||||
.timestamp_with_time_zone()
|
||||
.not_null()
|
||||
.default(Expr::current_timestamp()),
|
||||
)
|
||||
.col(ColumnDef::new(Alias::new("created_by")).uuid().null())
|
||||
.col(ColumnDef::new(Alias::new("updated_by")).uuid().null())
|
||||
.col(ColumnDef::new(Alias::new("deleted_at")).timestamp_with_time_zone().null())
|
||||
.col(
|
||||
ColumnDef::new(Alias::new("version"))
|
||||
.integer()
|
||||
.not_null()
|
||||
.default(1),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.if_not_exists()
|
||||
.name("idx_follow_up_template_field_template_id")
|
||||
.table(Alias::new("follow_up_template_field"))
|
||||
.col(Alias::new("template_id"))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
manager
|
||||
.create_index(
|
||||
Index::create()
|
||||
.if_not_exists()
|
||||
.name("idx_follow_up_template_field_tenant_id")
|
||||
.table(Alias::new("follow_up_template_field"))
|
||||
.col(Alias::new("tenant_id"))
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Alias::new("follow_up_template_field")).to_owned())
|
||||
.await?;
|
||||
manager
|
||||
.drop_table(Table::drop().table(Alias::new("follow_up_template")).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user