package run import ( "net/http" "strconv" "git.iwork-ai.com/xdc/iqudo-top1/internal/access" "git.iwork-ai.com/xdc/iqudo-top1/internal/auth" "git.iwork-ai.com/xdc/iqudo-top1/internal/model" "git.iwork-ai.com/xdc/iqudo-top1/internal/response" "git.iwork-ai.com/xdc/iqudo-top1/internal/scriptkit" "github.com/gin-gonic/gin" ) func (h *Handler) PreviewScenario(c *gin.Context) { p, _ := auth.PrincipalFromContext(c) scenarioID, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil || scenarioID == 0 || !access.CanViewScenario(h.db, p, scenarioID) { response.Error(c, http.StatusNotFound, "NOT_FOUND", "场景不存在") return } var body struct { Input map[string]interface{} `json:"input"` InitialValues map[string]interface{} `json:"initial_values"` StageKey string `json:"stage_key"` } if err := c.ShouldBindJSON(&body); err != nil { response.Error(c, http.StatusBadRequest, "INVALID_ARGUMENT", "预览参数格式不正确") return } var scenario model.Scenario if err := h.db.Where("id = ? AND tenant_id = ?", scenarioID, p.TenantID).First(&scenario).Error; err != nil { response.Error(c, http.StatusNotFound, "NOT_FOUND", "场景不存在") return } var fields []model.ScenarioField if err := h.db.Where("scenario_id = ? AND tenant_id = ?", scenarioID, p.TenantID).Order("sort_order,id").Find(&fields).Error; err != nil { response.Error(c, http.StatusInternalServerError, "QUERY_FAILED", "查询场景输入失败") return } mapped := mergeValues(mapScenarioInput(fields, body.Input), body.InitialValues) if err := validateInitialAnswers(fields, mapped); err != nil { response.Error(c, http.StatusUnprocessableEntity, "INVALID_INPUT", err.Error()) return } derived, matchedRules, err := deriveForScenario(h.db, p.TenantID, scenarioID, mapped) if err != nil { response.Error(c, http.StatusUnprocessableEntity, "RULE_EVALUATION_FAILED", err.Error()) return } outputs, err := buildOutputViews(scenario.OutputSchema, mapped, derived, map[string]interface{}{}, "preview", "") if err != nil { response.Error(c, http.StatusInternalServerError, "OUTPUT_FAILED", "生成场景输出失败") return } data := gin.H{"input": mapped, "derived": derived, "matched_rules": matchedRules, "outputs": outputs} pkg, loadErr := scriptkit.LoadPackageByScenario(h.db, p.TenantID, scenarioID) if loadErr != nil { response.OK(c, data) return } stageKey := body.StageKey if stageKey == "" { stageKey = pkg.Package.StartStageKey } stage, ok := pkg.StageByKey(stageKey) if !ok { response.OK(c, data) return } ctx := scriptkit.RenderContext{Input: mapped, Derived: derived, Form: map[string]interface{}{}} state := scriptkit.ScriptState{ScriptAnswers: map[string][]string{}, DimensionSelects: map[string]bool{}} weights := pkg.RecomputeWeights(pkg.InitialWeights(ctx), state, ctx) data["stage"] = pkg.BuildStageView(stage, weights, ctx, state, []scriptkit.FormFieldView{}) response.OK(c, data) }