engineclient.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. package client
  2. import (
  3. "bytes"
  4. "compress/gzip"
  5. "encoding/json"
  6. "encoding/xml"
  7. "fmt"
  8. "git.qianqiusoft.com/qianqiusoft/light-apiengine/env"
  9. "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
  10. "git.qianqiusoft.com/qianqiusoft/light-apiengine-client/code_gen"
  11. "io"
  12. "io/ioutil"
  13. "mime/multipart"
  14. "net/http"
  15. "os"
  16. "path/filepath"
  17. "strings"
  18. )
  19. type EngineClient struct {
  20. ProjectName string
  21. ServerUrl string
  22. }
  23. type ResponeResult struct {
  24. Code int32 `json:"code"`
  25. //描述
  26. Msg string `json:"msg"`
  27. //数据
  28. Data []GenerateResult `json:"data"`
  29. }
  30. type GenerateResult struct {
  31. Name string `json:"name"`
  32. Content []byte `json:"content"`
  33. Type string `json:"type"`
  34. }
  35. func NewEngineClient(project_name string, server_url string) *EngineClient {
  36. return &EngineClient{project_name, server_url}
  37. }
  38. func (c *EngineClient) InitDefalutFile(project_name string) {
  39. c.ProjectName = project_name
  40. os.MkdirAll("controllers/gen", os.ModePerm)
  41. os.MkdirAll("controllers/partial", os.ModePerm)
  42. os.MkdirAll("models", os.ModePerm)
  43. os.MkdirAll("routers", os.ModePerm)
  44. os.MkdirAll("conf", os.ModePerm)
  45. os.MkdirAll("sqlconfig", os.ModePerm)
  46. //os.MkdirAll("sqlconfig/gen", os.ModePerm)
  47. os.MkdirAll("doc", os.ModePerm)
  48. os.MkdirAll("web", os.ModePerm)
  49. _, err := os.Stat(project_name + ".xml")
  50. if os.IsNotExist(err) {
  51. xml := strings.Replace(DefaultProjectXML, "{project_name}", project_name, -1)
  52. ioutil.WriteFile(project_name+".xml", []byte(xml), os.ModePerm)
  53. }
  54. _, err = os.Stat(project_name + ".xsd")
  55. if os.IsNotExist(err) {
  56. ioutil.WriteFile(project_name+".xsd", []byte(XSD), os.ModePerm)
  57. }
  58. _, err = os.Stat("Dockerfile")
  59. if os.IsNotExist(err) {
  60. xml := strings.Replace(DockerFile, "{project_name}", project_name, -1)
  61. ioutil.WriteFile("Dockerfile", []byte(xml), os.ModePerm)
  62. }
  63. _, err = os.Stat("build_docker.sh")
  64. if os.IsNotExist(err) {
  65. xml := strings.Replace(BuildSH, "{project_name}", project_name, -1)
  66. ioutil.WriteFile("build_docker.sh", []byte(xml), os.ModePerm)
  67. }
  68. _, err = os.Stat("README.md")
  69. if os.IsNotExist(err) {
  70. xml := strings.Replace(MARK_DOWN, "{project_name}", project_name, -1)
  71. xml = strings.Replace(xml, "{!}", "`", -1)
  72. ioutil.WriteFile("README.md", []byte(xml), os.ModePerm)
  73. }
  74. }
  75. func (c *EngineClient) GenerateCurrentProject() {
  76. c.GenerateCurrentProjectToPath("")
  77. }
  78. func (c *EngineClient) GenerateCurrentProjectToPath(destPath string) {
  79. c.InitDefalutFile(c.ProjectName)
  80. // 0---0
  81. //path, _ := utils.GetCurrentPath()
  82. //c.Generate(path + c.ProjectName + ".xml")
  83. projMainXmlFileTemp := c.MergeXmlToSingle()
  84. if projMainXmlFileTemp == "" {
  85. fmt.Println("projMainXmlFileTemp is empty")
  86. return
  87. }
  88. c.GenerateToPath(projMainXmlFileTemp, destPath)
  89. //c.GenSwagger(projMainXmlFileTemp)
  90. path, _ := utils.GetCurrentPath()
  91. CopyDir(env.Get("GOPATH", "") + "/src/git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig",
  92. path+"vendor/git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig",
  93. "./vendor/git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig",
  94. "../src/git.qianqiusoft.com/qianqiusoft/light-apiengine/sqlconfig",
  95. path+"sqlconfig")
  96. }
  97. func (c *EngineClient) GenerateToPath(xmlfile string, dest_path string) {
  98. var result ResponeResult
  99. isCompress := true
  100. var bJson []byte
  101. if c.ServerUrl == "local" {
  102. isCompress = false
  103. //dest_path+="../i2-erp-compare/"
  104. bs := code_gen.DoGenerate(xmlfile, isCompress)
  105. bJson = bs
  106. } else {
  107. server := "http://qianqiusoft.com:6166"
  108. if c.ServerUrl != "" {
  109. server = c.ServerUrl
  110. }
  111. server += "/api/v1/develop/generate"
  112. bs := DoRequest(xmlfile, server)
  113. bJson = bs.Bytes()
  114. }
  115. if bJson != nil {
  116. err := json.Unmarshal(bJson, &result)
  117. if err != nil {
  118. fmt.Println(err.Error())
  119. }
  120. if isCompress {
  121. for i := 0; i < len(result.Data); i++ {
  122. var b bytes.Buffer
  123. b.Write(result.Data[i].Content)
  124. unzip := unzipbytes(&b)
  125. result.Data[i].Content = unzip.Bytes()
  126. }
  127. }
  128. for i := 0; i < len(result.Data); i++ {
  129. path := result.Data[i].Name
  130. //fmt.Println(path)
  131. path = path[len(c.ProjectName)+1:]
  132. path = dest_path + path
  133. fmt.Println(path)
  134. ft := result.Data[i].Type
  135. if ft == "main" {
  136. //fmt.Println(string(result.Data[i].Content))
  137. } else if ft == "config" || ft == "ci" {
  138. _, err := os.Stat(path)
  139. if err == nil {
  140. fmt.Println(path + "已经存在,忽略...")
  141. // fmt.Println(result.Data[i].Content)
  142. } else {
  143. ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm)
  144. }
  145. } else if ft == "controllers" {
  146. os.MkdirAll(filepath.Dir(path), os.ModePerm)
  147. if strings.Index(path, "_gen.go") > 0 {
  148. ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm)
  149. } else {
  150. _, err := os.Stat(path)
  151. if err == nil {
  152. ioutil.WriteFile(path+"_new", result.Data[i].Content, os.ModePerm)
  153. } else if os.IsNotExist(err) {
  154. ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm)
  155. }
  156. }
  157. } else if ft == "routers" {
  158. os.MkdirAll(filepath.Dir(path), os.ModePerm)
  159. ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm)
  160. } else if ft == "sql" {
  161. if strings.Index(path, "_gen.xml") > 0 {
  162. os.MkdirAll(filepath.Dir(path), os.ModePerm)
  163. ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm)
  164. } else {
  165. _, err := os.Stat(path)
  166. if err == nil {
  167. //ioutil.WriteFile(path+"_new", result.Data[i].Content, os.ModePerm)
  168. } else if os.IsNotExist(err) {
  169. os.MkdirAll(filepath.Dir(path), os.ModePerm)
  170. ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm)
  171. }
  172. }
  173. } else {
  174. os.MkdirAll(filepath.Dir(path), os.ModePerm)
  175. err := ioutil.WriteFile(path, result.Data[i].Content, os.ModePerm)
  176. if err != nil {
  177. fmt.Println(err.Error())
  178. }
  179. }
  180. }
  181. }
  182. }
  183. /*
  184. func (c *EngineClient) Generate(xmlfile string) {
  185. c.GenerateToPath(xmlfile, "")
  186. //c.GenSwagger(xmlfile)
  187. }
  188. */
  189. func (c *EngineClient) GenSwagger(xmlfile string) {
  190. server := "http://swagger.pusher.i2erp.cn"
  191. server += "/api/v1/upload"
  192. fmt.Println("===========================================================================>11")
  193. request, err := newfileUploadRequest(server, nil, "xmlfile", xmlfile)
  194. if err != nil {
  195. fmt.Println(err)
  196. }
  197. client := &http.Client{}
  198. resp, err := client.Do(request)
  199. if err != nil {
  200. fmt.Println("===========================================================================>", err.Error())
  201. } else {
  202. defer resp.Body.Close()
  203. bytess, err := ioutil.ReadAll(resp.Body)
  204. if err != nil {
  205. fmt.Println("=======================================>ioutil.ReadAll error", err.Error())
  206. } else {
  207. fmt.Println("=======================================>", string(bytess))
  208. }
  209. }
  210. }
  211. /**
  212. * @brief: merge xml
  213. * @param: none
  214. * @return: the path of final xml
  215. */
  216. func (c *EngineClient) MergeXmlToSingle() string {
  217. path, _ := utils.GetCurrentPath()
  218. // e.g.: c:/gopath/src/hanghua_background_proj
  219. path = "D:\\dev\\Go\\go_path\\src\\i2-erp-backend\\"
  220. projDir := fmt.Sprintf("%s%s.proj", path, c.ProjectName)
  221. projMainXmlFile := projDir + "/" + c.ProjectName + ".xml"
  222. projMainXmlFileTemp := projDir + "/" + c.ProjectName + "_temp.xml"
  223. _, err := os.Stat(projMainXmlFileTemp)
  224. if os.IsNotExist(err) {
  225. fmt.Println("-------------------------->remove project main file temp")
  226. os.Remove(projMainXmlFileTemp) // remove
  227. }
  228. _, err = os.Stat(projMainXmlFile)
  229. if os.IsNotExist(err) {
  230. fmt.Println("main xml file of " + c.ProjectName + " does not exist")
  231. return ""
  232. }
  233. app := XmlApplication{}
  234. bytess, _ := ioutil.ReadFile(projMainXmlFile)
  235. err = xml.Unmarshal(bytess, &app)
  236. if err != nil {
  237. fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error())
  238. return ""
  239. }
  240. controllers, err := scanControllers(projDir + "/controllers")
  241. if err != nil {
  242. fmt.Println("scanControllers error " + err.Error())
  243. return ""
  244. }
  245. beans, err := scanBeans(projDir + "/beans")
  246. if err != nil {
  247. fmt.Println("scanBeans error " + err.Error())
  248. return ""
  249. }
  250. tables, err := scanTables(projDir + "/tables")
  251. if err != nil {
  252. fmt.Println("scanTables error " + err.Error())
  253. return ""
  254. }
  255. if app.Controllers.ControllerList == nil {
  256. app.Controllers.ControllerList = []XmlController{}
  257. }
  258. for i := range controllers {
  259. app.Controllers.ControllerList = append(app.Controllers.ControllerList, controllers[i])
  260. }
  261. createVueApisFolder(app.Controllers.ControllerList)
  262. if app.Beans.BeanList == nil {
  263. app.Beans.BeanList = []XmlBean{}
  264. }
  265. for i := range beans {
  266. app.Beans.BeanList = append(app.Beans.BeanList, beans[i])
  267. }
  268. if app.Tables.TableList == nil {
  269. app.Tables.TableList = []XmlTable{}
  270. }
  271. for i := range tables {
  272. app.Tables.TableList = append(app.Tables.TableList, tables[i])
  273. }
  274. bytess, err = xml.Marshal(app)
  275. if err != nil {
  276. fmt.Println("xml.Marshal(app) error " + err.Error())
  277. return ""
  278. }
  279. err = ioutil.WriteFile(projMainXmlFileTemp, bytess, os.ModePerm)
  280. if err != nil {
  281. fmt.Println("ioutil.WriteFile(projMainXmlFileTemp, bytess,os.ModePerm) error " + err.Error())
  282. return ""
  283. }
  284. _, err = os.Stat(projMainXmlFileTemp)
  285. if os.IsNotExist(err) {
  286. fmt.Println("main xml file temp of " + c.ProjectName + " does not exist")
  287. return ""
  288. } else {
  289. fmt.Println("main xml file temp of " + c.ProjectName + " exist")
  290. }
  291. return projMainXmlFileTemp
  292. }
  293. func scanControllers(ctrldir string) ([]XmlController, error) {
  294. _, err := os.Stat(ctrldir)
  295. if os.IsNotExist(err) {
  296. fmt.Println("controller dir does not exist", err.Error())
  297. return nil, err
  298. }
  299. controllers := []XmlController{}
  300. filePaths := []string{}
  301. filePaths, err = getAllFile(strings.TrimSuffix(ctrldir, "/"), filePaths)
  302. if err != nil {
  303. fmt.Println("controller getAllFile error", err.Error())
  304. return nil, err
  305. }
  306. for i := range filePaths {
  307. ctrl := XmlController{}
  308. ctrlfile := filePaths[i]
  309. _, err = os.Stat(ctrlfile)
  310. if os.IsNotExist(err) {
  311. fmt.Println("controller xml file " + ctrlfile + " does not exist")
  312. return controllers, err
  313. }
  314. ctrlfile = strings.Replace(ctrlfile, "\\", "/", -1)
  315. arr := strings.Split(ctrlfile, "/")
  316. bytess, _ := ioutil.ReadFile(ctrlfile)
  317. err = xml.Unmarshal(bytess, &ctrl)
  318. if err != nil {
  319. fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error())
  320. return controllers, err
  321. }
  322. // get sub dir name
  323. if arr[len(arr)-2] != "controllers" {
  324. // if sub dir is not controllers, set the dir attr
  325. ctrl.Dir = arr[len(arr)-2]
  326. }
  327. controllers = append(controllers, ctrl)
  328. }
  329. return controllers, nil
  330. //err = filepath.Walk(ctrldir, func(path string, info os.FileInfo, err error) error {
  331. //
  332. // if err != nil {
  333. // return filepath.SkipDir
  334. // }
  335. // if info.IsDir(){
  336. // return nil
  337. // }
  338. //
  339. // ctrl := XmlController{}
  340. // ctrlfile := ctrldir + "/" + info.Name()
  341. // _, err = os.Stat(ctrlfile)
  342. // if os.IsNotExist(err) {
  343. // fmt.Println("controller xml file " + ctrlfile + " does not exist")
  344. // return filepath.SkipDir
  345. // }
  346. // bytess, _ := ioutil.ReadFile(ctrlfile)
  347. // err = xml.Unmarshal(bytess, &ctrl)
  348. // if err != nil{
  349. // fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error())
  350. // return filepath.SkipDir
  351. // }
  352. // controllers = append(controllers, ctrl)
  353. //
  354. // return nil
  355. //})
  356. //return controllers, err
  357. }
  358. func scanBeans(ctrldir string) ([]XmlBean, error) {
  359. _, err := os.Stat(ctrldir)
  360. if os.IsNotExist(err) {
  361. fmt.Println("controller dir does not exist")
  362. return nil, err
  363. }
  364. beans := []XmlBean{}
  365. filePaths := []string{}
  366. filePaths, err = getAllFile(strings.TrimSuffix(ctrldir, "/"), filePaths)
  367. if err != nil {
  368. fmt.Println("controller getAllFile error", err.Error())
  369. return nil, err
  370. }
  371. for i := range filePaths {
  372. ctrl := XmlBean{}
  373. ctrlfile := filePaths[i]
  374. _, err = os.Stat(ctrlfile)
  375. if os.IsNotExist(err) {
  376. fmt.Println("controller xml file " + ctrlfile + " does not exist")
  377. return beans, err
  378. }
  379. bytess, _ := ioutil.ReadFile(ctrlfile)
  380. err = xml.Unmarshal(bytess, &ctrl)
  381. if err != nil {
  382. fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error())
  383. return beans, err
  384. }
  385. beans = append(beans, ctrl)
  386. }
  387. return beans, nil
  388. //err = filepath.Walk(ctrldir, func(path string, info os.FileInfo, err error) error {
  389. //
  390. // if err != nil {
  391. // return filepath.SkipDir
  392. // }
  393. // if info.IsDir(){
  394. // return nil
  395. // }
  396. //
  397. // bean := XmlBean{}
  398. // beanfile := ctrldir + "/" + info.Name()
  399. // _, err = os.Stat(beanfile)
  400. // if os.IsNotExist(err) {
  401. // fmt.Println("controller xml file " + beanfile + " does not exist")
  402. // return filepath.SkipDir
  403. // }
  404. // bytess, _ := ioutil.ReadFile(beanfile)
  405. // err = xml.Unmarshal(bytess, &bean)
  406. // if err != nil{
  407. // fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error())
  408. // return filepath.SkipDir
  409. // }
  410. // beans = append(beans, bean)
  411. //
  412. // return nil
  413. //})
  414. //
  415. //return beans, err
  416. }
  417. func scanTables(ctrldir string) ([]XmlTable, error) {
  418. _, err := os.Stat(ctrldir)
  419. if os.IsNotExist(err) {
  420. fmt.Println("controller dir does not exist")
  421. return nil, err
  422. }
  423. tables := []XmlTable{}
  424. filePaths := []string{}
  425. filePaths, err = getAllFile(strings.TrimSuffix(ctrldir, "/"), filePaths)
  426. if err != nil {
  427. fmt.Println("controller getAllFile error", err.Error())
  428. return nil, err
  429. }
  430. for i := range filePaths {
  431. ctrl := XmlTable{}
  432. ctrlfile := filePaths[i]
  433. _, err = os.Stat(ctrlfile)
  434. if os.IsNotExist(err) {
  435. fmt.Println("controller xml file " + ctrlfile + " does not exist")
  436. return tables, err
  437. }
  438. bytess, _ := ioutil.ReadFile(ctrlfile)
  439. err = xml.Unmarshal(bytess, &ctrl)
  440. if err != nil {
  441. fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error())
  442. return tables, err
  443. }
  444. tables = append(tables, ctrl)
  445. }
  446. return tables, nil
  447. //err = filepath.Walk(ctrldir, func(path string, info os.FileInfo, err error) error {
  448. //
  449. // if err != nil {
  450. // return filepath.SkipDir
  451. // }
  452. // if info.IsDir(){
  453. // return nil
  454. // }
  455. //
  456. // table := XmlTable{}
  457. // tablefile := ctrldir + "/" + info.Name()
  458. // _, err = os.Stat(tablefile)
  459. // if os.IsNotExist(err) {
  460. // fmt.Println("controller xml file " + tablefile + " does not exist")
  461. // return filepath.SkipDir
  462. // }
  463. // bytess, _ := ioutil.ReadFile(tablefile)
  464. // err = xml.Unmarshal(bytess, &table)
  465. // if err != nil{
  466. // fmt.Println("xml.Unmarshal(bytess, &app) error " + err.Error())
  467. // return filepath.SkipDir
  468. // }
  469. // tables = append(tables, table)
  470. //
  471. // return nil
  472. //})
  473. //
  474. //return tables, err
  475. }
  476. func createVueApisFolder(controllers []XmlController) {
  477. for i := range controllers {
  478. fmt.Println("------------------------------>" + controllers[i].Name)
  479. os.MkdirAll("vue/api/modules/"+controllers[i].Name, os.ModePerm)
  480. }
  481. }
  482. func getAllFile(pathname string, s []string) ([]string, error) {
  483. rd, err := ioutil.ReadDir(pathname)
  484. if err != nil {
  485. fmt.Println("read dir fail:", err)
  486. return s, err
  487. }
  488. for _, fi := range rd {
  489. if fi.IsDir() {
  490. fullDir := pathname + "/" + fi.Name()
  491. s, err = getAllFile(fullDir, s)
  492. if err != nil {
  493. fmt.Println("read dir fail:", err)
  494. return s, err
  495. }
  496. } else {
  497. if strings.HasSuffix(strings.ToLower(fi.Name()), ".xml") {
  498. fullName := pathname + "/" + fi.Name()
  499. s = append(s, fullName)
  500. }
  501. }
  502. }
  503. return s, nil
  504. }
  505. func unzipbytes(bs *bytes.Buffer) bytes.Buffer {
  506. r, _ := gzip.NewReader(bs)
  507. defer r.Close()
  508. var b bytes.Buffer
  509. b.ReadFrom(r)
  510. //undatas, _ := ioutil.ReadAll(r)
  511. //fmt.Println("ungzip size:", len(undatas))
  512. return b
  513. }
  514. func DoRequest(xmlfile string, server string) *bytes.Buffer {
  515. request, err := newfileUploadRequest(server, nil, "xmlfile", xmlfile)
  516. if err != nil {
  517. fmt.Println(err)
  518. }
  519. client := &http.Client{}
  520. resp, err := client.Do(request)
  521. if err != nil {
  522. fmt.Println(err)
  523. } else {
  524. body := &bytes.Buffer{}
  525. _, err := body.ReadFrom(resp.Body)
  526. if err != nil {
  527. fmt.Println(err)
  528. }
  529. resp.Body.Close()
  530. fmt.Println(resp.StatusCode)
  531. fmt.Println(resp.Header)
  532. //fmt.Println(body)
  533. return body
  534. }
  535. return nil
  536. }
  537. func newfileUploadRequest(uri string, params map[string]string, paramName, path string) (*http.Request, error) {
  538. file, err := os.Open(path)
  539. if err != nil {
  540. return nil, err
  541. }
  542. defer file.Close()
  543. body := &bytes.Buffer{}
  544. writer := multipart.NewWriter(body)
  545. part, err := writer.CreateFormFile(paramName, filepath.Base(path))
  546. if err != nil {
  547. return nil, err
  548. }
  549. _, err = io.Copy(part, file)
  550. for key, val := range params {
  551. _ = writer.WriteField(key, val)
  552. }
  553. err = writer.Close()
  554. if err != nil {
  555. return nil, err
  556. }
  557. request, err := http.NewRequest("POST", uri, body)
  558. request.Header.Add("Content-Type", writer.FormDataContentType())
  559. return request, err
  560. }