engineclient.go 16 KB

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