mirror of
https://github.com/oarkflow/mq.git
synced 2025-10-07 00:43:35 +08:00
feat: implement handlers
This commit is contained in:
122
handlers/html_handler.go
Normal file
122
handlers/html_handler.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"os"
|
||||
|
||||
"github.com/oarkflow/mq"
|
||||
"github.com/oarkflow/mq/consts"
|
||||
"github.com/oarkflow/mq/dag"
|
||||
"github.com/oarkflow/mq/renderer"
|
||||
)
|
||||
|
||||
type RenderHTMLNode struct {
|
||||
dag.Operation
|
||||
renderer *renderer.JSONSchemaRenderer
|
||||
}
|
||||
|
||||
func (c *RenderHTMLNode) ProcessTask(ctx context.Context, task *mq.Task) mq.Result {
|
||||
data := c.Payload.Data
|
||||
var (
|
||||
schemaFile, _ = data["schema_file"].(string)
|
||||
templateStr, _ = data["template"].(string)
|
||||
templateFile, _ = data["template_file"].(string)
|
||||
)
|
||||
|
||||
var templateData map[string]any
|
||||
if len(task.Payload) > 0 {
|
||||
if err := json.Unmarshal(task.Payload, &templateData); err != nil {
|
||||
return mq.Result{Payload: task.Payload, Error: err, Ctx: ctx, ConditionStatus: "invalid"}
|
||||
}
|
||||
}
|
||||
if templateData == nil {
|
||||
templateData = make(map[string]any)
|
||||
}
|
||||
templateData["task_id"] = ctx.Value("task_id")
|
||||
|
||||
var renderedHTML string
|
||||
var err error
|
||||
|
||||
switch {
|
||||
// 1. JSONSchema + HTML Template
|
||||
case schemaFile != "" && templateStr != "":
|
||||
if c.renderer == nil {
|
||||
renderer, err := renderer.GetFromFile(schemaFile, templateStr)
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to get renderer from file %s: %v", schemaFile, err), Ctx: ctx}
|
||||
}
|
||||
c.renderer = renderer
|
||||
}
|
||||
renderedHTML, err = c.renderer.RenderFields(templateData)
|
||||
// 2. JSONSchema + HTML File
|
||||
case schemaFile != "" && templateFile != "":
|
||||
if c.renderer == nil {
|
||||
renderer, err := renderer.GetFromFile(schemaFile, "", templateFile)
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to get renderer from file %s: %v", schemaFile, err), Ctx: ctx}
|
||||
}
|
||||
c.renderer = renderer
|
||||
}
|
||||
renderedHTML, err = c.renderer.RenderFields(templateData)
|
||||
// 3. Only JSONSchema
|
||||
case schemaFile != "" || c.renderer != nil:
|
||||
if c.renderer == nil {
|
||||
renderer, err := renderer.GetFromFile(schemaFile, "")
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to get renderer from file %s: %v", schemaFile, err), Ctx: ctx}
|
||||
}
|
||||
c.renderer = renderer
|
||||
}
|
||||
renderedHTML, err = c.renderer.RenderFields(templateData)
|
||||
// 4. Only HTML Template
|
||||
case templateStr != "":
|
||||
tmpl, err := template.New("inline").Parse(templateStr)
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to parse template: %v", err), Ctx: ctx}
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
err = tmpl.Execute(&buf, templateData)
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to execute template: %v", err), Ctx: ctx}
|
||||
}
|
||||
renderedHTML = buf.String()
|
||||
// 5. Only HTML File
|
||||
case templateFile != "":
|
||||
fileContent, err := os.ReadFile(templateFile)
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to read template file: %v", err), Ctx: ctx}
|
||||
}
|
||||
tmpl, err := template.New("file").Parse(string(fileContent))
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to parse template file: %v", err), Ctx: ctx}
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
err = tmpl.Execute(&buf, templateData)
|
||||
if err != nil {
|
||||
return mq.Result{Error: fmt.Errorf("failed to execute template file: %v", err), Ctx: ctx}
|
||||
}
|
||||
renderedHTML = buf.String()
|
||||
default:
|
||||
return mq.Result{Error: fmt.Errorf("no valid rendering approach found"), Ctx: ctx}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return mq.Result{Payload: task.Payload, Error: err, Ctx: ctx, ConditionStatus: "invalid"}
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, consts.ContentType, consts.TypeHtml)
|
||||
resultData := map[string]any{
|
||||
"html_content": renderedHTML,
|
||||
"step": "form",
|
||||
}
|
||||
bt, _ := json.Marshal(resultData)
|
||||
return mq.Result{Payload: bt, Ctx: ctx}
|
||||
}
|
||||
|
||||
func NewRenderHTMLNode(id string) *RenderHTMLNode {
|
||||
return &RenderHTMLNode{Operation: dag.Operation{Key: "render-html", ID: id, Type: dag.Page, Tags: []string{"built-in"}}}
|
||||
}
|
Reference in New Issue
Block a user