script.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // script
  2. package util
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. qu "qfw/util"
  7. ljson "github.com/yuin/gopher-json"
  8. "github.com/yuin/gopher-lua"
  9. )
  10. type LuaScript struct {
  11. Code, Name, Script string
  12. Doc map[string]interface{} //经过前置过滤的源信息
  13. Block []*Block //分块信息
  14. KvMap map[string][]map[string]interface{}
  15. Result map[string][]map[string]interface{} //抽取结果信息
  16. L *lua.LState
  17. }
  18. //stype per:前置,core:抽取,back:后置
  19. func (s *LuaScript) RunScript(stype string) map[string]interface{} {
  20. data := map[string]interface{}{}
  21. s.L = lua.NewState()
  22. s.L.PreloadModule("json", ljson.Loader)
  23. defer s.L.Close()
  24. if err := s.L.DoString(s.Script); err != nil {
  25. data["err"] = err.Error()
  26. } else {
  27. if stype == "pre" {
  28. tab := MapToLuaTable(s.L, s.Doc)
  29. if err := s.L.CallByParam(lua.P{
  30. Fn: s.L.GetGlobal("main"),
  31. NRet: 1,
  32. Protect: true,
  33. }, tab); err != nil {
  34. data["err"] = err.Error()
  35. }
  36. } else if stype == "core" {
  37. tab := MapToLuaTable(s.L, s.Doc)
  38. block, _ := json.Marshal(s.Block)
  39. kvMap := MapToLuaTable2(s.L, s.KvMap)
  40. if err := s.L.CallByParam(lua.P{
  41. Fn: s.L.GetGlobal("main"),
  42. NRet: 1,
  43. Protect: true,
  44. }, tab, lua.LString(block), kvMap); err != nil {
  45. data["err"] = err.Error()
  46. }
  47. } else if stype == "back" {
  48. result := MapToLuaTable2(s.L, s.Result)
  49. if err := s.L.CallByParam(lua.P{
  50. Fn: s.L.GetGlobal("main"),
  51. NRet: 1,
  52. Protect: true,
  53. }, result); err != nil {
  54. data["err"] = err.Error()
  55. }
  56. }
  57. ret := s.L.Get(-1)
  58. s.L.Pop(1)
  59. if tmp, ok := ret.(*lua.LTable); ok {
  60. data = LuaTableToMap(tmp)
  61. } else {
  62. data["rep"] = ret
  63. }
  64. }
  65. return data
  66. }
  67. func Logic(str string, doc map[string]interface{}) bool {
  68. L := lua.NewState()
  69. L.PreloadModule("json", ljson.Loader)
  70. defer L.Close()
  71. b := false
  72. if err := L.DoString(str); err != nil {
  73. panic(err)
  74. } else {
  75. tab := MapToLuaTable(L, doc)
  76. if err := L.CallByParam(lua.P{
  77. Fn: L.GetGlobal("logic"),
  78. NRet: 1,
  79. Protect: true,
  80. }, tab); err != nil {
  81. panic(err)
  82. }
  83. ret := L.Get(-1)
  84. L.Pop(1)
  85. if ret.String() == "true" {
  86. b = true
  87. }
  88. }
  89. return b
  90. }
  91. func MapToLuaTable(l *lua.LState, obj map[string]interface{}) *lua.LTable {
  92. tab := l.NewTable()
  93. for k, v := range obj {
  94. if val, ok := v.(string); ok {
  95. tab.RawSet(lua.LString(k), lua.LString(val))
  96. } else if val, ok := v.(int64); ok {
  97. tab.RawSet(lua.LString(k), lua.LNumber(val))
  98. } else if val, ok := v.(int32); ok {
  99. tab.RawSet(lua.LString(k), lua.LNumber(val))
  100. } else if val, ok := v.(float64); ok {
  101. tab.RawSet(lua.LString(k), lua.LNumber(val))
  102. } else if val, ok := v.(float32); ok {
  103. tab.RawSet(lua.LString(k), lua.LNumber(val))
  104. } else if val, ok := v.(bool); ok {
  105. tab.RawSet(lua.LString(k), lua.LBool(val))
  106. } else if val, ok := v.(map[string]interface{}); ok {
  107. tab.RawSet(lua.LString(k), MapToLuaTable(l, val))
  108. } else if val, ok := v.([]string); ok {
  109. tb := l.NewTable()
  110. for k, vv := range val {
  111. tb.Insert(k, lua.LString(vv))
  112. }
  113. tab.RawSet(lua.LString(k), tb)
  114. } else if val, ok := v.([]map[string]interface{}); ok {
  115. tab2 := l.NewTable()
  116. for i, v := range val {
  117. tab2.Insert(i, MapToLuaTable(l, v))
  118. }
  119. tab.RawSet(lua.LString(k), tab2)
  120. } else if val, ok := v.([]interface{}); ok {
  121. bs, _ := json.Marshal(val)
  122. tab.RawSet(lua.LString(k), lua.LString(string(bs)))
  123. }
  124. }
  125. return tab
  126. }
  127. func MapToLuaTable2(l *lua.LState, obj map[string][]map[string]interface{}) *lua.LTable {
  128. tab := l.NewTable()
  129. for k, ms := range obj {
  130. tab2 := l.NewTable()
  131. for i, v := range ms {
  132. tab2.Insert(i, MapToLuaTable(l, v))
  133. }
  134. tab.RawSet(lua.LString(k), tab2)
  135. }
  136. return tab
  137. }
  138. func LuaTableToMap(param *lua.LTable) map[string]interface{} {
  139. tmp := map[string]interface{}{}
  140. param.ForEach(func(key, val lua.LValue) {
  141. k := fmt.Sprint(key)
  142. if v, ok := val.(lua.LString); ok {
  143. tmp[k] = string(v)
  144. } else if v, ok := val.(*lua.LTable); ok {
  145. i := qu.IntAllDef(k, -1)
  146. if i > -1 { //转数组
  147. t := []map[string]interface{}{}
  148. v.ForEach(func(k, inv lua.LValue) {
  149. if vv, ok := inv.(*lua.LTable); ok {
  150. t = append(t, LuaTableToMap(vv))
  151. }
  152. })
  153. tmp[k] = t
  154. } else {
  155. tmp[k] = LuaTableToMap(v)
  156. }
  157. } else if v, ok := val.(*lua.LBool); ok {
  158. if v.String() == "true" {
  159. tmp[k] = true
  160. } else {
  161. tmp[k] = false
  162. }
  163. } else {
  164. tmp[k] = v
  165. }
  166. })
  167. return tmp
  168. }