mock平台

markdown.js 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. const schema = require('./shema-transformTo-table.js');
  2. const _ = require('underscore');
  3. const json_parse = function(json) {
  4. try {
  5. return JSON.parse(json);
  6. } catch (err) {
  7. return {};
  8. }
  9. };
  10. // 处理字符串换行
  11. const handleWrap = str => {
  12. return _.isString(str) ? str.replace(/\n/gi, '<br/>') : str;
  13. };
  14. const messageMap = {
  15. desc: '备注',
  16. default: '实例',
  17. maximum: '最大值',
  18. minimum: '最小值',
  19. maxItems: '最大数量',
  20. minItems: '最小数量',
  21. maxLength: '最大长度',
  22. minLength: '最小长度',
  23. uniqueItems: '元素是否都不同',
  24. itemType: 'item 类型',
  25. format: 'format',
  26. enum: '枚举',
  27. enumDesc: '枚举备注',
  28. mock: 'mock'
  29. };
  30. const columns = [
  31. {
  32. title: '名称',
  33. dataIndex: 'name',
  34. key: 'name'
  35. },
  36. {
  37. title: '类型',
  38. dataIndex: 'type',
  39. key: 'type'
  40. },
  41. {
  42. title: '是否必须',
  43. dataIndex: 'required',
  44. key: 'required'
  45. },
  46. {
  47. title: '默认值',
  48. dataIndex: 'default',
  49. key: 'default'
  50. },
  51. {
  52. title: '备注',
  53. dataIndex: 'desc',
  54. key: 'desc'
  55. },
  56. {
  57. title: '其他信息',
  58. dataIndex: 'sub',
  59. key: 'sub'
  60. }
  61. ];
  62. function escapeStr(str, isToc) {
  63. return isToc ? escape(str) : str;
  64. }
  65. function createBaseMessage(basepath, inter) {
  66. // 基本信息
  67. let baseMessage = `### 基本信息\n\n**Path:** ${basepath + inter.path}\n\n**Method:** ${
  68. inter.method
  69. }\n\n**接口描述:**\n${_.isUndefined(inter.desc) ? '' : inter.desc}\n`;
  70. return baseMessage;
  71. }
  72. function createReqHeaders(req_headers) {
  73. // Request-headers
  74. if (req_headers && req_headers.length) {
  75. let headersTable = `**Headers**\n\n`;
  76. headersTable += `| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 |\n| ------------ | ------------ | ------------ | ------------ | ------------ |\n`;
  77. for (let j = 0; j < req_headers.length; j++) {
  78. headersTable += `| ${req_headers[j].name || ''} | ${req_headers[j].value || ''} | ${
  79. req_headers[j].required == 1 ? '是' : '否'
  80. } | ${handleWrap(req_headers[j].example) || ''} | ${handleWrap(req_headers[j].desc) ||
  81. ''} |\n`;
  82. }
  83. return headersTable;
  84. }
  85. return '';
  86. }
  87. function createPathParams(req_params) {
  88. if (req_params && req_params.length) {
  89. let paramsTable = `**路径参数**\n\n`;
  90. paramsTable += `| 参数名称 | 示例 | 备注 |\n| ------------ | ------------ | ------------ |\n`;
  91. for (let j = 0; j < req_params.length; j++) {
  92. paramsTable += `| ${req_params[j].name || ''} | ${handleWrap(req_params[j].example) ||
  93. ''} | ${handleWrap(req_params[j].desc) || ''} |\n`;
  94. }
  95. return paramsTable;
  96. }
  97. return '';
  98. }
  99. function createReqQuery(req_query) {
  100. if (req_query && req_query.length) {
  101. let headersTable = `**Query**\n\n`;
  102. headersTable += `| 参数名称 | 是否必须 | 示例 | 备注 |\n| ------------ | ------------ | ------------ | ------------ |\n`;
  103. for (let j = 0; j < req_query.length; j++) {
  104. headersTable += `| ${req_query[j].name || ''} | ${
  105. req_query[j].required == 1 ? '是' : '否'
  106. } | ${handleWrap(req_query[j].example) || ''} | ${handleWrap(req_query[j].desc) ||
  107. ''} |\n`;
  108. }
  109. return headersTable;
  110. }
  111. return '';
  112. }
  113. function createReqBody(req_body_type, req_body_form, req_body_other, req_body_is_json_schema) {
  114. if (req_body_type === 'form' && req_body_form.length) {
  115. let bodyTable = `**Body**\n\n`;
  116. bodyTable += `| 参数名称 | 参数类型 | 是否必须 | 示例 | 备注 |\n| ------------ | ------------ | ------------ | ------------ | ------------ |\n`;
  117. let req_body = req_body_form;
  118. for (let j = 0; j < req_body.length; j++) {
  119. bodyTable += `| ${req_body[j].name || ''} | ${req_body[j].type || ''} | ${
  120. req_body[j].required == 1 ? '是' : '否'
  121. } | ${req_body[j].example || ''} | ${req_body[j].desc || ''} |\n`;
  122. }
  123. return `${bodyTable}\n\n`;
  124. } else if (req_body_other) {
  125. if (req_body_is_json_schema) {
  126. let reqBody = createSchemaTable(req_body_other);
  127. return `**Body**\n\n` + reqBody;
  128. } else {
  129. //other
  130. return `**Body**\n\n` + '```javascript' + `\n${req_body_other || ''}` + '\n```';
  131. }
  132. }
  133. return '';
  134. }
  135. function tableHeader(columns) {
  136. let header = ``;
  137. columns.map(item => {
  138. header += `<th key=${item.key}>${item.title}</th>`;
  139. });
  140. return header;
  141. }
  142. function handleObject(text) {
  143. if (!_.isObject(text)) {
  144. return text;
  145. }
  146. let tpl = ``;
  147. Object.keys(text || {}).map((item, index) => {
  148. let name = messageMap[item];
  149. let value = text[item];
  150. tpl += _.isUndefined(text[item])
  151. ? ''
  152. : `<p key=${index}><span style="font-weight: '700'">${name}: </span><span>${value.toString()}</span></p>`;
  153. });
  154. return tpl;
  155. }
  156. function tableCol(col, columns, level) {
  157. let tpl = ``;
  158. columns.map((item, index) => {
  159. let dataIndex = item.dataIndex;
  160. let value = col[dataIndex];
  161. value = _.isUndefined(value) ? '' : value;
  162. let text = ``;
  163. switch (dataIndex) {
  164. case 'sub':
  165. text = handleObject(value);
  166. break;
  167. case 'type':
  168. text =
  169. value === 'array'
  170. ? `<span>${col.sub ? col.sub.itemType || '' : 'array'} []</span>`
  171. : `<span>${value}</span>`;
  172. break;
  173. case 'required':
  174. text = value ? '必须' : '非必须';
  175. break;
  176. case 'desc':
  177. text = _.isUndefined(col.childrenDesc)
  178. ? `<span style="white-space: pre-wrap">${value}</span>`
  179. : `<span style="white-space: pre-wrap">${col.childrenDesc}</span>`;
  180. break;
  181. case 'name':
  182. text = `<span style="padding-left: ${20 * level}px"><span style="color: #8c8a8a">${
  183. level > 0 ? '├─' : ''
  184. }</span> ${value}</span>`;
  185. break;
  186. default:
  187. text = value;
  188. }
  189. tpl += `<td key=${index}>${text}</td>`;
  190. });
  191. return tpl;
  192. }
  193. function tableBody(dataSource, columns, level) {
  194. // 按照columns的顺序排列数据
  195. let tpl = ``;
  196. dataSource.map(col => {
  197. let child = null;
  198. tpl += `<tr key=${col.key}>${tableCol(col, columns, level)}</tr>`;
  199. if (!_.isUndefined(col.children) && _.isArray(col.children)) {
  200. let index = level + 1;
  201. child = tableBody(col.children, columns, index);
  202. }
  203. tpl += child ? `${child}` : ``;
  204. });
  205. return tpl;
  206. }
  207. function createSchemaTable(body) {
  208. let template = ``;
  209. let dataSource = schema.schemaTransformToTable(json_parse(body));
  210. template += `<table>
  211. <thead class="ant-table-thead">
  212. <tr>
  213. ${tableHeader(columns)}
  214. </tr>
  215. </thead>`;
  216. template += `<tbody className="ant-table-tbody">${tableBody(dataSource, columns, 0)}
  217. </tbody>
  218. </table>
  219. `;
  220. return template;
  221. }
  222. function createResponse(res_body, res_body_is_json_schema, res_body_type) {
  223. let resTitle = `\n### 返回数据\n\n`;
  224. if (res_body) {
  225. if (res_body_is_json_schema && res_body_type === 'json') {
  226. let resBody = createSchemaTable(res_body);
  227. return resTitle + resBody;
  228. } else {
  229. let resBody = '```javascript' + `\n${res_body || ''}\n` + '```';
  230. return resTitle + resBody;
  231. }
  232. }
  233. return '';
  234. }
  235. function createInterMarkdown(basepath, listItem, isToc) {
  236. let mdTemplate = ``;
  237. const toc = `[TOC]\n\n`;
  238. // 接口名称
  239. mdTemplate += `\n## ${escapeStr(`${listItem.title}\n<a id=${listItem.title}> </a>`, isToc)}\n`;
  240. isToc && (mdTemplate += toc);
  241. // 基本信息
  242. mdTemplate += createBaseMessage(basepath, listItem);
  243. // Request
  244. mdTemplate += `\n### 请求参数\n`;
  245. // Request-headers
  246. mdTemplate += createReqHeaders(listItem.req_headers);
  247. // Request-params
  248. mdTemplate += createPathParams(listItem.req_params);
  249. // Request-query
  250. mdTemplate += createReqQuery(listItem.req_query);
  251. // Request-body
  252. mdTemplate += createReqBody(
  253. listItem.req_body_type,
  254. listItem.req_body_form,
  255. listItem.req_body_other,
  256. listItem.req_body_is_json_schema
  257. );
  258. // Response
  259. // Response-body
  260. mdTemplate += createResponse(
  261. listItem.res_body,
  262. listItem.res_body_is_json_schema,
  263. listItem.res_body_type
  264. );
  265. return mdTemplate;
  266. }
  267. function createProjectMarkdown(curProject, wikiData) {
  268. let mdTemplate = ``;
  269. // 项目名、项目描述
  270. let title = `<h1 class="curproject-name"> ${curProject.name} </h1>`;
  271. mdTemplate += `\n ${title} \n ${curProject.desc || ''}\n\n`;
  272. // 增加公共wiki信息展示
  273. mdTemplate += wikiData ? `\n### 公共信息\n${wikiData.desc || ''}\n` : '';
  274. return mdTemplate;
  275. }
  276. function createClassMarkdown(curProject, list, isToc) {
  277. let mdTemplate = ``;
  278. const toc = `[TOC]\n\n`;
  279. list.map(item => {
  280. // 分类名称
  281. mdTemplate += `\n# ${escapeStr(item.name, isToc)}\n`;
  282. isToc && (mdTemplate += toc);
  283. for (let i = 0; i < item.list.length; i++) {
  284. //循环拼接 接口
  285. // 接口内容
  286. mdTemplate += createInterMarkdown(curProject.basepath, item.list[i], isToc);
  287. }
  288. });
  289. return mdTemplate;
  290. }
  291. let r = {
  292. createInterMarkdown,
  293. createProjectMarkdown,
  294. createClassMarkdown
  295. };
  296. module.exports = r;