gen.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package ktgen
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "text/template"
  7. "git.i2edu.net/i2/go-zero/tools/goctl/api/spec"
  8. "github.com/iancoleman/strcase"
  9. )
  10. const (
  11. apiBaseTemplate = `package {{.}}
  12. import com.google.gson.Gson
  13. import kotlinx.coroutines.Dispatchers
  14. import kotlinx.coroutines.withContext
  15. import java.io.BufferedReader
  16. import java.io.InputStreamReader
  17. import java.io.OutputStreamWriter
  18. import java.net.HttpURLConnection
  19. import java.net.URL
  20. const val SERVER = "http://localhost:8080"
  21. suspend fun apiRequest(
  22. method: String,
  23. uri: String,
  24. body: Any = "",
  25. onOk: ((String) -> Unit)? = null,
  26. onFail: ((String) -> Unit)? = null,
  27. eventually: (() -> Unit)? = null
  28. ) = withContext(Dispatchers.IO) {
  29. val url = URL(SERVER + uri)
  30. with(url.openConnection() as HttpURLConnection) {
  31. connectTimeout = 3000
  32. requestMethod = method
  33. doInput = true
  34. if (method == "POST" || method == "PUT" || method == "PATCH") {
  35. setRequestProperty("Content-Type", "application/json")
  36. doOutput = true
  37. val data = when (body) {
  38. is String -> {
  39. body
  40. }
  41. else -> {
  42. Gson().toJson(body)
  43. }
  44. }
  45. val wr = OutputStreamWriter(outputStream)
  46. wr.write(data)
  47. wr.flush()
  48. }
  49. try {
  50. if (responseCode >= 400) {
  51. BufferedReader(InputStreamReader(errorStream)).use {
  52. val response = it.readText()
  53. onFail?.invoke(response)
  54. }
  55. return@with
  56. }
  57. //response
  58. BufferedReader(InputStreamReader(inputStream)).use {
  59. val response = it.readText()
  60. onOk?.invoke(response)
  61. }
  62. } catch (e: Exception) {
  63. e.message?.let { onFail?.invoke(it) }
  64. }
  65. }
  66. eventually?.invoke()
  67. }
  68. `
  69. apiTemplate = `package {{with .Info}}{{.Desc}}{{end}}
  70. import com.google.gson.Gson
  71. object {{with .Info}}{{.Title}}{{end}}{
  72. {{range .Types}}
  73. data class {{.Name}}({{$length := (len .Members)}}{{range $i,$item := .Members}}
  74. val {{with $item}}{{lowCamelCase .Name}}: {{parseType .Type}}{{end}}{{if ne $i (add $length -1)}},{{end}}{{end}}
  75. ){{end}}
  76. {{with .Service}}
  77. {{range .Routes}}suspend fun {{routeToFuncName .Method .Path}}({{with .RequestType}}{{if ne .Name ""}}
  78. req:{{.Name}},{{end}}{{end}}
  79. onOk: (({{with .ResponseType}}{{.Name}}{{end}}) -> Unit)? = null,
  80. onFail: ((String) -> Unit)? = null,
  81. eventually: (() -> Unit)? = null
  82. ){
  83. apiRequest("{{upperCase .Method}}","{{.Path}}",{{with .RequestType}}{{if ne .Name ""}}body=req,{{end}}{{end}} onOk = { {{with .ResponseType}}
  84. onOk?.invoke({{if ne .Name ""}}Gson().fromJson(it,{{.Name}}::class.java){{end}}){{end}}
  85. }, onFail = onFail, eventually =eventually)
  86. }
  87. {{end}}{{end}}
  88. }`
  89. )
  90. func genBase(dir, pkg string, api *spec.ApiSpec) error {
  91. e := os.MkdirAll(dir, 0o755)
  92. if e != nil {
  93. return e
  94. }
  95. path := filepath.Join(dir, "BaseApi.kt")
  96. if _, e := os.Stat(path); e == nil {
  97. fmt.Println("BaseApi.kt already exists, skipped it.")
  98. return nil
  99. }
  100. file, e := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644)
  101. if e != nil {
  102. return e
  103. }
  104. defer file.Close()
  105. t, e := template.New("n").Parse(apiBaseTemplate)
  106. if e != nil {
  107. return e
  108. }
  109. e = t.Execute(file, pkg)
  110. if e != nil {
  111. return e
  112. }
  113. return nil
  114. }
  115. func genApi(dir, pkg string, api *spec.ApiSpec) error {
  116. properties := api.Info.Properties
  117. if properties == nil {
  118. return fmt.Errorf("none properties")
  119. }
  120. title := properties["Title"]
  121. if len(title) == 0 {
  122. return fmt.Errorf("none title")
  123. }
  124. desc := properties["Desc"]
  125. if len(desc) == 0 {
  126. return fmt.Errorf("none desc")
  127. }
  128. name := strcase.ToCamel(title + "Api")
  129. path := filepath.Join(dir, name+".kt")
  130. api.Info.Title = name
  131. api.Info.Desc = desc
  132. e := os.MkdirAll(dir, 0o755)
  133. if e != nil {
  134. return e
  135. }
  136. file, e := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o644)
  137. if e != nil {
  138. return e
  139. }
  140. defer file.Close()
  141. t, e := template.New("api").Funcs(funcsMap).Parse(apiTemplate)
  142. if e != nil {
  143. return e
  144. }
  145. return t.Execute(file, api)
  146. }