WIP: Working in Progress 迭代中 版权声明:鲁班H5 版权所有,禁止任何形式的转载和抄袭,侵权必

问:如何将鲁班H5 API 由 Node.js 换成 Java、PHP、Python 等语言?

答:一句话 -> 用 Java…等语言 实现 Node 实现的接口即可

步骤

  1. 了解鲁班H5 编辑器的后端 接口
  2. 了解鲁班H5 编辑器的后端 Model

1. 了解鲁班H5 编辑器的后端 接口

1.1 访问 Node.js 版本接口文档 (本地)

  1. 访问鲁班H5 管理后台:http://localhost:1337/admin/
  2. 访问鲁班H5 API(Node.js) 文档配置:http://localhost:1337/admin/plugins/documentation
    image.png
  3. 访问鲁班H5 API(Node.js) 对应的 Swagger 文档:http://localhost:1337/documentation/v1.0.0,请开始探索吧
    image.png

1.2 接口实现思路 + 伪代码

Node.js 代码实现:https://github.com/ly525/luban-h5/blob/dev/back-end/h5-api/api/work/controllers/Work.js

  1. {
  2. "routes": [
  3. {
  4. // 图片代理,防止跨域
  5. // 主要是请求一些跨域图片的时候,先走APIAPI负责请求图片,用来解决跨域问题
  6. // 代码关键实现:return http.request(request.get.imgURL)
  7. "method": "GET",
  8. "path": "/works/cors-proxy",
  9. "handler": "Work.corsProxy",
  10. "config": {
  11. "policies": []
  12. }
  13. },
  14. {
  15. // 所有作品
  16. "method": "GET",
  17. "path": "/works",
  18. "handler": "Work.find",
  19. "config": {
  20. "policies": []
  21. }
  22. },
  23. {
  24. // 统计作品总数
  25. "method": "GET",
  26. "path": "/works/count",
  27. "handler": "Work.count",
  28. "config": {
  29. "policies": []
  30. }
  31. },
  32. {
  33. // 获取某个作品的详情数据
  34. // 伪代码:return HTTPJsonResponse(WorkModel.findOne(workId).toJSON())
  35. "method": "GET",
  36. "path": "/works/:id",
  37. "handler": "Work.findOne",
  38. "config": {
  39. "policies": []
  40. }
  41. },
  42. {
  43. // 创建作品
  44. "method": "POST",
  45. "path": "/works",
  46. "handler": "Work.create",
  47. "config": {
  48. "policies": []
  49. }
  50. },
  51. {
  52. // 更新作品
  53. "method": "PUT",
  54. "path": "/works/:id",
  55. "handler": "Work.update",
  56. "config": {
  57. "policies": []
  58. }
  59. },
  60. {
  61. // 删除某个作品
  62. "method": "DELETE",
  63. "path": "/works/:id",
  64. "handler": "Work.delete",
  65. "config": {
  66. "policies": []
  67. }
  68. },
  69. {
  70. // 预览某个作品
  71. // workJSON = WorkModel.findOne(workId).toJSON()
  72. // return render('作品模板.jsp', workJSON)
  73. "method": "GET",
  74. "path": "/works/preview/:id",
  75. "handler": "Work.previewOne",
  76. "config": {
  77. "policies": []
  78. }
  79. },
  80. {
  81. //
  82. /**
  83. * 提交某个作品的表单
  84. * 思路:
  85. 比如页面中有
  86. 输入框:姓名,UUID为:11...
  87. 输入框:年龄,UUID为:22...
  88. 单选框:角色,UUID为:33...
  89. 在表单提交的时候,其实提交到后端的数据方式如下:
  90. 1. URL /submit-form/:workId/
  91. 2. payload 是一个 JSON
  92. {
  93. "11": "张三", // 姓名
  94. "22": 18, // 年龄
  95. "33": "工程师" // 角色
  96. }
  97. 后端在接收到数据之后
  98. 1. 会向 WorkForm 表中插入一条记录,主要存储在其 form 字段中(JSON 类型字段)
  99. 2. 根据 workId 找到 Work,并绑定到该记录的work字段上(外键)
  100. */
  101. // Node.js 参考代码如下:
  102. // https://github.com/ly525/luban-h5/blob/dev/back-end/h5-api/api/work/controllers/Work.js#L16-L24
  103. "method": "POST",
  104. "path": "/works/form/submit/:id",
  105. "handler": "Work.submitForm",
  106. "config": {
  107. "policies": []
  108. }
  109. },
  110. {
  111. /*
  112. * 查询某个作品的表单统计数据
  113. * 思路
  114. 1. 根据 workId 获得 Work
  115. 2. work.pages.find(所有的表单类型元素)
  116. 3. 构造 Objectuuid2NameMap,即 UUID 和元素名称的映射,比如 11 代表姓名,22代表年龄这样
  117. 举个栗子:
  118. 这是 Work 记录:
  119. {
  120. "11": "姓名",
  121. "22": 年龄,
  122. "33": "角色"
  123. }
  124. 4. 我们再从服务器中找出来刚才提交的和这个 Work 绑定的所有表单,其中一条记录栗子如下:
  125. 其中一条表单记录:
  126. {
  127. "11": "张三", // 姓名
  128. "22": 18, // 年龄
  129. "33": "工程师" // 角色
  130. }
  131. 5. 这样,我们把两条记录结合下,就会得到如下结果:
  132. {
  133. "姓名": "张三",
  134. "年龄": 18,
  135. "角色": "工程师"
  136. }
  137. 其中的一条记录,我们就生成完毕了。
  138. 同样的办法,所有的表单记录都可以生成了,我们把这个返回给前端,前端就可以渲染表单数据了
  139. Response Demo
  140. ---------------------
  141. {
  142. formRecords: [
  143. {
  144. workId: 1,
  145. formJSON: {
  146. "11": "张三", // 姓名
  147. "22": 18, // 年龄
  148. "33": "工程师" // 角色
  149. }
  150. },
  151. {
  152. workId: 1,
  153. formJSON: {
  154. "11": "张三", // 姓名
  155. "22": 18, // 年龄
  156. "33": "工程师" // 角色
  157. }
  158. },
  159. ],
  160. uuidToName: {
  161. "11": "姓名",
  162. "22": 年龄,
  163. "33": "角色"
  164. }
  165. }
  166. ---------------------
  167. */
  168. // Node.js 参考代码如下:
  169. // https://github.com/ly525/luban-h5/blob/dev/back-end/h5-api/api/work/controllers/Work.js#L25-L55
  170. "method": "GET",
  171. "path": "/works/form/query/:id",
  172. "handler": "Work.queryFormsOfOneWork",
  173. "config": {
  174. "policies": []
  175. }
  176. },
  177. {
  178. // 设置某个作品为模板
  179. // 伪代码:
  180. // work = WorkModel.findOne(workId).toJSON()
  181. // newTemplateWork = work.clone()
  182. // newTemplateWork.isTemplate = true // 不是模版,是正常作品
  183. // result = WorkModel.create(newTemplateWork)
  184. // return result
  185. // Node.js 参考代码如下:
  186. // https://github.com/ly525/luban-h5/blob/dev/back-end/h5-api/api/work/controllers/Work.js#L56-L63
  187. "method": "POST",
  188. "path": "/works/set-as-template/:id",
  189. "handler": "Work.setAsTemplate",
  190. "config": {
  191. "policies": []
  192. }
  193. },
  194. {
  195. // 基于某个模版创建新作品
  196. // 伪代码:
  197. // templateWork = WorkModel.findOne(templateId).toJSON()
  198. // newWork = templateWork.clone()
  199. // newWork.title = newTitle || ''
  200. // newWork.desc = newDesc || ''
  201. // newWork.isTemplate = false // 不是模版,是正常作品
  202. // result = WorkModel.create(newWork)
  203. // return result
  204. // Node.js 参考代码如下:
  205. // https://github.com/ly525/luban-h5/blob/dev/back-end/h5-api/api/work/controllers/Work.js#L64-L71
  206. "method": "POST",
  207. "path": "/works/use-template/:id",
  208. "handler": "Work.useTemplate",
  209. "config": {
  210. "policies": []
  211. }
  212. },
  213. ]
  214. }

2. 了解鲁班H5 编辑器的后端 Model

数据库表/Table(Model/Entity class) + 字段说明

1. Work 表:H5 作品

建表语句
  1. DROP TABLE IF EXISTS `work`;
  2. CREATE TABLE `work` (
  3. `id` bigint(20) NOT NULL AUTO_INCREMENT,
  4. `title` varchar(255) NOT NULL COMMENT '标题',
  5. `description` longtext COMMENT '描述',
  6. `cover_image_url` longtext,
  7. `pages` json DEFAULT NULL,
  8. `publish` tinyint(1) NOT NULL DEFAULT '0',
  9. `template` tinyint(1) NOT NULL DEFAULT '0',
  10. `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  11. `update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  12. PRIMARY KEY (`id`)
  13. ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

image.png

字段说明
  1. {
  2. // 标题
  3. "title": {
  4. "type": "string"
  5. },
  6. // 描述信息
  7. "description": {
  8. "type": "text"
  9. },
  10. // 封面图链接
  11. "cover_image_url": {
  12. "type": "text"
  13. },
  14. // 页面数据,主要部分
  15. "pages": {
  16. "type": "json"
  17. },
  18. // 创建时间
  19. "create_time": {
  20. "type": "date"
  21. },
  22. // 更新时间
  23. "update_time": {
  24. "type": "date"
  25. },
  26. // 是否已经发布
  27. "is_publish": {
  28. "type": "boolean"
  29. },
  30. // 是否是模板
  31. "is_template": {
  32. "type": "boolean"
  33. },
  34. // 关联的表单
  35. "workforms": {
  36. "collection": "workform",
  37. "via": "work"
  38. }
  39. }

2. WorkForm:表单收集表

建表语句
  1. DROP TABLE IF EXISTS `work_forms`;
  2. CREATE TABLE `work_forms` (
  3. `id` bigint(20) NOT NULL AUTO_INCREMENT,
  4. `form` longtext,
  5. `work_id` bigint(20) NOT NULL,
  6. PRIMARY KEY (`id`),
  7. KEY `work_id` (`work_id`),
  8. CONSTRAINT `work_forms_ibfk_1` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  1. WorkForm Table 结构
  2. {
  3. formJSON: JSON, // 一条表单记录
  4. workID: 外键 // 关联的作品ID,外键
  5. }

表单提交记录 Example:
  1. [
  2. {
  3. workId: 1,
  4. formJSON: {
  5. "11": "张三", // 姓名
  6. "22": 18, // 年龄
  7. "33": "工程师" // 角色
  8. }
  9. },
  10. {
  11. workId: 1,
  12. formJSON: {
  13. "11": "张四", // 姓名
  14. "22": 18, // 年龄
  15. "33": "工程师" // 角色
  16. }
  17. },
  18. {
  19. workId: 2,
  20. formJSON: {
  21. "11": "王五", // 姓名
  22. "22": 18, // 年龄
  23. "33": "工程师" // 角色
  24. }
  25. },
  26. ]
  1. {
  2. "formJSON": {}, // "type": "json",
  3. "workId" // 关联的 workId,外键
  4. }

解释:Work 与 FormCollection 的关系是 一对多的关系,一个作品可以有很多关联的表单统计记录。


参考项目

Java API For Luban H5

  1. springboot2-jpa-api-for-luban

    SpringBoot2

JPA

  1. springboot2-mybatis-plus-api-for-luban

    SpringBoot2
    MyBatis Plus