feat(health): 积分触发扩展 + 随访模板关联 — Phase 3

- 新增 follow_up.completed 事件积分消费者,随访完成触发 30 积分
- follow_up_task 新增 template_id FK 关联随访模板
- follow_up_record 新增 form_data JSONB 存储结构化表单数据
- 新增 POST /health/follow-up-tasks/from-template 基于模板创建随访任务端点
- 数据库迁移 160:follow_up_task.template_id + follow_up_record.form_data + 积分规则种子
This commit is contained in:
iven
2026-05-21 00:50:29 +08:00
parent 5877342a4d
commit ec7f76127d
11 changed files with 341 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ use axum::extract::{FromRef, Json, Path, Query, State};
use serde::Deserialize;
use utoipa::IntoParams;
use uuid::Uuid;
use validator::Validate;
use erp_core::error::AppError;
use erp_core::rbac::require_permission;
@@ -250,3 +251,25 @@ where
.await?;
Ok(Json(ApiResponse::ok(result)))
}
// ---------------------------------------------------------------------------
// 基于模板创建随访任务
// ---------------------------------------------------------------------------
pub async fn create_task_from_template<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Json(req): Json<CreateTaskFromTemplateReq>,
) -> Result<Json<ApiResponse<FollowUpTaskResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.follow-up.manage")?;
req.validate()
.map_err(|e: validator::ValidationErrors| AppError::Validation(e.to_string()))?;
let result =
follow_up_service::create_task_from_template(&state, ctx.tenant_id, Some(ctx.user_id), req)
.await?;
Ok(Json(ApiResponse::ok(result)))
}