base.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. export type ListItem = {
  2. id?: number;
  3. children?: ListItem[];
  4. [key: string]: any;
  5. };
  6. export type BaseMockOptions = { name: string; copyTimes?: number; list: ListItem[]; idGenerator: number };
  7. type CopyListParams = { originList: ListItem[]; newList: ListItem[]; options: BaseMockOptions; parentId?: number };
  8. function copyList(props: CopyListParams) {
  9. const { originList, newList, options, parentId } = props;
  10. for (const item of originList) {
  11. const newItem: ListItem = { ...item, parentId };
  12. newItem.id = options.idGenerator;
  13. options.idGenerator += 1;
  14. newList.push(newItem);
  15. if (item.children) {
  16. newItem.children = [];
  17. copyList({
  18. originList: item.children,
  19. newList: newItem.children,
  20. options,
  21. parentId: newItem.id
  22. });
  23. }
  24. }
  25. }
  26. function delById(req: Service.MockOption, list: any[]) {
  27. for (let i = 0; i < list.length; i += 1) {
  28. const item = list[i];
  29. if (item.id === parseInt(req.query.id, 10)) {
  30. list.splice(i, 1);
  31. break;
  32. }
  33. if (item.children && item.children.length > 0) {
  34. delById(req, item.children);
  35. }
  36. }
  37. }
  38. function findById(id: number, list: ListItem[]): any {
  39. for (const item of list) {
  40. if (item.id === id) {
  41. return item;
  42. }
  43. if (item.children && item.children.length > 0) {
  44. const sub = findById(id, item.children);
  45. if (sub !== null && sub !== undefined) {
  46. return sub;
  47. }
  48. }
  49. }
  50. return null;
  51. }
  52. function matchWithArrayCondition(value: any[], item: ListItem, key: string) {
  53. if (value.length === 0) {
  54. return true;
  55. }
  56. let matched = false;
  57. for (const i of value) {
  58. if (item[key] instanceof Array) {
  59. for (const j of item[key]) {
  60. if (i === j) {
  61. matched = true;
  62. break;
  63. }
  64. }
  65. if (matched) {
  66. break;
  67. }
  68. } else if (item[key] === i || (typeof item[key] === 'string' && item[key].indexOf(`${i}`) >= 0)) {
  69. matched = true;
  70. break;
  71. }
  72. if (matched) {
  73. break;
  74. }
  75. }
  76. return matched;
  77. }
  78. function matchWithObjectCondition(value: any, item: ListItem, key: string) {
  79. let matched = true;
  80. for (const key2 of Object.keys(value)) {
  81. const v = value[key2];
  82. if (v && item[key] && v !== item[key][key2]) {
  83. matched = false;
  84. break;
  85. }
  86. }
  87. return matched;
  88. }
  89. function searchFromList(list: ListItem[], query: any) {
  90. const filter = (item: ListItem) => {
  91. let allFound = true; // 是否所有条件都符合
  92. for (const key of Object.keys(query)) {
  93. const value = query[key];
  94. if (value === undefined || value === null || value === '') {
  95. // no nothing
  96. } else if (value instanceof Array) {
  97. // 如果条件中的value是数组的话,只要查到一个就行
  98. const matched = matchWithArrayCondition(value, item, key);
  99. if (!matched) {
  100. allFound = false;
  101. }
  102. } else if (value instanceof Object) {
  103. // 如果条件中的value是对象的话,需要每个key都匹配
  104. const matched = matchWithObjectCondition(value, item, key);
  105. if (!matched) {
  106. allFound = false;
  107. }
  108. } else if (item[key] !== value) {
  109. allFound = false;
  110. }
  111. }
  112. return allFound;
  113. };
  114. return list.filter(filter);
  115. }
  116. export default {
  117. buildMock(options: BaseMockOptions) {
  118. const name = options.name;
  119. if (!options.copyTimes) {
  120. options.copyTimes = 29;
  121. }
  122. const list: any[] = [];
  123. for (let i = 0; i < options.copyTimes; i += 1) {
  124. copyList({
  125. originList: options.list,
  126. newList: list,
  127. options
  128. });
  129. }
  130. options.list = list;
  131. return [
  132. {
  133. path: `/mock/${name}/page`,
  134. method: 'post',
  135. handle(req: Service.MockOption) {
  136. let data = [...list];
  137. let limit = 20;
  138. let offset = 0;
  139. for (const item of list) {
  140. if (item.children && item.children.length === 0) {
  141. item.hasChildren = false;
  142. item.lazy = false;
  143. }
  144. }
  145. let orderAsc: any;
  146. let orderProp: any;
  147. if (req && req.body) {
  148. const { page, query } = req.body;
  149. if (page.limit) {
  150. limit = parseInt(page.limit, 10);
  151. }
  152. if (page.offset) {
  153. offset = parseInt(page.offset, 10);
  154. }
  155. if (Object.keys(query).length > 0) {
  156. data = searchFromList(list, query);
  157. }
  158. }
  159. const start = offset;
  160. let end = offset + limit;
  161. if (data.length < end) {
  162. end = data.length;
  163. }
  164. if (orderProp) {
  165. // 排序
  166. data.sort((a, b) => {
  167. let ret = 0;
  168. if (a[orderProp] > b[orderProp]) {
  169. ret = 1;
  170. } else if (a[orderProp] < b[orderProp]) {
  171. ret = -1;
  172. }
  173. return orderAsc ? ret : -ret;
  174. });
  175. }
  176. const records = data.slice(start, end);
  177. const lastOffset = data.length - (data.length % limit);
  178. if (offset > lastOffset) {
  179. offset = lastOffset;
  180. }
  181. return {
  182. code: 200,
  183. message: 'success',
  184. data: {
  185. records,
  186. total: data.length,
  187. limit,
  188. offset
  189. }
  190. };
  191. }
  192. },
  193. {
  194. path: `/mock/${name}/get`,
  195. method: 'get',
  196. handle(req: Service.MockOption) {
  197. let id = req.query.id;
  198. id = parseInt(id, 10);
  199. let current = null;
  200. for (const item of list) {
  201. if (item.id === id) {
  202. current = item;
  203. break;
  204. }
  205. }
  206. return {
  207. code: 200,
  208. message: 'success',
  209. data: current
  210. };
  211. }
  212. },
  213. {
  214. path: `/mock/${name}/add`,
  215. method: 'post',
  216. handle(req: Service.MockOption) {
  217. req.body.id = options.idGenerator;
  218. options.idGenerator += 1;
  219. list.unshift(req.body);
  220. return {
  221. code: 200,
  222. message: 'success',
  223. data: req.body.id
  224. };
  225. }
  226. },
  227. {
  228. path: `/mock/${name}/update`,
  229. method: 'post',
  230. handle(req: Service.MockOption) {
  231. const item = findById(req.body.id, list);
  232. if (item) {
  233. Object.assign(item, req.body);
  234. }
  235. return {
  236. code: 200,
  237. message: 'success',
  238. data: null
  239. };
  240. }
  241. },
  242. {
  243. path: `/mock/${name}/delete`,
  244. method: 'post',
  245. handle(req: Service.MockOption) {
  246. delById(req, list);
  247. return {
  248. code: 200,
  249. message: 'success',
  250. data: null
  251. };
  252. }
  253. },
  254. {
  255. path: `/mock/${name}/batchDelete`,
  256. method: 'post',
  257. handle(req: Service.MockOption) {
  258. const ids = req.body.ids;
  259. for (let i = list.length - 1; i >= 0; i -= 1) {
  260. const item = list[i];
  261. if (ids.indexOf(item.id) >= 0) {
  262. list.splice(i, 1);
  263. }
  264. }
  265. return {
  266. code: 200,
  267. message: 'success',
  268. data: null
  269. };
  270. }
  271. },
  272. {
  273. path: `/mock/${name}/all`,
  274. method: 'post',
  275. handle() {
  276. return {
  277. code: 200,
  278. message: 'success',
  279. data: list
  280. };
  281. }
  282. }
  283. ];
  284. }
  285. };