|
|
@@ -2,27 +2,108 @@ package main
|
|
2
|
2
|
|
|
3
|
3
|
import (
|
|
4
|
4
|
"fmt"
|
|
|
5
|
+ "strings"
|
|
5
|
6
|
|
|
6
|
|
- "git.x2erp.com/qdy/go-base/config"
|
|
|
7
|
+ "github.com/traefik/yaegi/interp"
|
|
|
8
|
+ "github.com/traefik/yaegi/stdlib"
|
|
7
|
9
|
)
|
|
8
|
10
|
|
|
9
|
11
|
func main() {
|
|
10
|
|
- // 获取配置实例
|
|
11
|
|
- cfg := config.GetConfig()
|
|
12
|
|
-
|
|
13
|
|
- // 使用配置
|
|
14
|
|
- if cfg.IsDatabaseConfigured() {
|
|
15
|
|
- dbConfig := cfg.GetDatabaseConfig()
|
|
16
|
|
- fmt.Printf("Host: %s\n", dbConfig.Host)
|
|
17
|
|
- fmt.Printf("Port: %d\n", dbConfig.Port)
|
|
18
|
|
- fmt.Printf("Database: %s\n", dbConfig.Database)
|
|
|
12
|
+
|
|
|
13
|
+ calculateSimple("(2+3)*5")
|
|
|
14
|
+ calculateSimple("15/5")
|
|
|
15
|
+ // 测试多行代码(使用专门的多行函数)
|
|
|
16
|
+ code := `x := 10
|
|
|
17
|
+if x > 5 {
|
|
|
18
|
+ return "大于5"
|
|
|
19
|
+} else {
|
|
|
20
|
+ return "小于等于5"
|
|
|
21
|
+}`
|
|
|
22
|
+
|
|
|
23
|
+ calculateMultiLine(code)
|
|
|
24
|
+ // // 获取配置实例
|
|
|
25
|
+ // cfg := config.GetConfig()
|
|
|
26
|
+
|
|
|
27
|
+ // // 使用配置
|
|
|
28
|
+ // if cfg.IsDatabaseConfigured() {
|
|
|
29
|
+ // dbConfig := cfg.GetDatabaseConfig()
|
|
|
30
|
+ // fmt.Printf("Host: %s\n", dbConfig.Host)
|
|
|
31
|
+ // fmt.Printf("Port: %d\n", dbConfig.Port)
|
|
|
32
|
+ // fmt.Printf("Database: %s\n", dbConfig.Database)
|
|
|
33
|
+ // }
|
|
|
34
|
+
|
|
|
35
|
+ // //authConfig := cfg.GetAuth()
|
|
|
36
|
+ // //fmt.Printf("token: %s\n", authConfig.Token)
|
|
|
37
|
+
|
|
|
38
|
+ // serviceConfig := cfg.GetServiceConfig()
|
|
|
39
|
+ // fmt.Printf("ReadTimeout: %d秒\n", serviceConfig.ReadTimeout)
|
|
|
40
|
+ // fmt.Printf("WriteTimeout: %d秒\n", serviceConfig.WriteTimeout)
|
|
|
41
|
+ // fmt.Printf("IdleTimeout: %d秒\n", serviceConfig.IdleTimeout)
|
|
|
42
|
+
|
|
|
43
|
+}
|
|
|
44
|
+
|
|
|
45
|
+func calculateSimple(expression string) (string, error) {
|
|
|
46
|
+ i := interp.New(interp.Options{})
|
|
|
47
|
+ i.Use(stdlib.Symbols)
|
|
|
48
|
+
|
|
|
49
|
+ // 包装成匿名函数立即调用,既简洁又安全
|
|
|
50
|
+ code := fmt.Sprintf("(func() interface{} { return %s })()", expression)
|
|
|
51
|
+
|
|
|
52
|
+ v, err := i.Eval(code)
|
|
|
53
|
+ if err != nil {
|
|
|
54
|
+ fmt.Printf("calculateSimple: err v:%v \n", err)
|
|
|
55
|
+ return "", err
|
|
19
|
56
|
}
|
|
20
|
57
|
|
|
21
|
|
- //authConfig := cfg.GetAuth()
|
|
22
|
|
- //fmt.Printf("token: %s\n", authConfig.Token)
|
|
|
58
|
+ fmt.Printf("calculateSimple: %s v:%v \n", expression, v)
|
|
|
59
|
+ return fmt.Sprintf("%v", v), nil
|
|
|
60
|
+}
|
|
|
61
|
+
|
|
|
62
|
+// 专门处理多行代码(if/for/变量声明等)
|
|
|
63
|
+func calculateMultiLine(code string) (string, error) {
|
|
|
64
|
+ i := interp.New(interp.Options{})
|
|
|
65
|
+ i.Use(stdlib.Symbols)
|
|
23
|
66
|
|
|
24
|
|
- serviceConfig := cfg.GetServiceConfig()
|
|
25
|
|
- fmt.Printf("ReadTimeout: %d秒\n", serviceConfig.ReadTimeout)
|
|
26
|
|
- fmt.Printf("WriteTimeout: %d秒\n", serviceConfig.WriteTimeout)
|
|
27
|
|
- fmt.Printf("IdleTimeout: %d秒\n", serviceConfig.IdleTimeout)
|
|
|
67
|
+ // 关键:整个代码块作为函数体,最后一行作为返回值
|
|
|
68
|
+ wrappedCode := fmt.Sprintf(`
|
|
|
69
|
+(func() interface{} {
|
|
|
70
|
+ %s
|
|
|
71
|
+})()`, code)
|
|
|
72
|
+
|
|
|
73
|
+ v, err := i.Eval(wrappedCode)
|
|
|
74
|
+ if err != nil {
|
|
|
75
|
+ fmt.Printf("calculateMultiLine 错误: %v\n代码: %s\n", err, code)
|
|
|
76
|
+ return "", err
|
|
|
77
|
+ }
|
|
|
78
|
+
|
|
|
79
|
+ fmt.Printf("calculateMultiLine 成功: %v\n", v)
|
|
|
80
|
+ return fmt.Sprintf("%v", v), nil
|
|
|
81
|
+}
|
|
|
82
|
+
|
|
|
83
|
+// 更智能的版本:自动判断使用哪种处理方式
|
|
|
84
|
+func calculateAuto(expression string) (string, error) {
|
|
|
85
|
+ // 如果是纯数学表达式(只有数字和运算符)
|
|
|
86
|
+ if isPureMath(expression) {
|
|
|
87
|
+ return calculateSimple(expression)
|
|
|
88
|
+ }
|
|
|
89
|
+
|
|
|
90
|
+ // 否则当做多行代码处理
|
|
|
91
|
+ return calculateMultiLine(expression)
|
|
|
92
|
+}
|
|
|
93
|
+
|
|
|
94
|
+func isPureMath(expr string) bool {
|
|
|
95
|
+ // 移除非空格的空白字符
|
|
|
96
|
+ cleaned := strings.ReplaceAll(expr, "\n", "")
|
|
|
97
|
+ cleaned = strings.ReplaceAll(cleaned, "\t", "")
|
|
|
98
|
+ cleaned = strings.ReplaceAll(cleaned, " ", "")
|
|
|
99
|
+
|
|
|
100
|
+ // 检查是否只包含数字、运算符、括号和小数点
|
|
|
101
|
+ for _, ch := range cleaned {
|
|
|
102
|
+ if !((ch >= '0' && ch <= '9') ||
|
|
|
103
|
+ ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
|
|
|
104
|
+ ch == '(' || ch == ')' || ch == '.') {
|
|
|
105
|
+ return false
|
|
|
106
|
+ }
|
|
|
107
|
+ }
|
|
|
108
|
+ return len(cleaned) > 0
|
|
28
|
109
|
}
|