m8-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +67 -0
  2. package/bin/m8-mcp.js +2 -0
  3. package/dist/constants.js +1 -0
  4. package/dist/data/ejs-doc/api_audio/api_audio.md +225 -0
  5. package/dist/data/ejs-doc/api_auth/api_auth.md +256 -0
  6. package/dist/data/ejs-doc/api_contact/api_contact.md +295 -0
  7. package/dist/data/ejs-doc/api_contact/images/component_contact.jpg +0 -0
  8. package/dist/data/ejs-doc/api_device/api_device.md +761 -0
  9. package/dist/data/ejs-doc/api_event/api_event.md +244 -0
  10. package/dist/data/ejs-doc/api_global/api_global.md +440 -0
  11. package/dist/data/ejs-doc/api_io/api_io.md +369 -0
  12. package/dist/data/ejs-doc/api_navigator/api_navigator.md +654 -0
  13. package/dist/data/ejs-doc/api_navigator/images/navigator.backbtn.png +0 -0
  14. package/dist/data/ejs-doc/api_navigator/images/navigator.hide.png +0 -0
  15. package/dist/data/ejs-doc/api_navigator/images/navigator.hidestatus.png +0 -0
  16. package/dist/data/ejs-doc/api_navigator/images/navigator.leftarrowbtn.jpg +0 -0
  17. package/dist/data/ejs-doc/api_navigator/images/navigator.leftbtn.png +0 -0
  18. package/dist/data/ejs-doc/api_navigator/images/navigator.leftbtnimg.png +0 -0
  19. package/dist/data/ejs-doc/api_navigator/images/navigator.multititle.jpg +0 -0
  20. package/dist/data/ejs-doc/api_navigator/images/navigator.rightbtn.png +0 -0
  21. package/dist/data/ejs-doc/api_navigator/images/navigator.rightbtn2.png +0 -0
  22. package/dist/data/ejs-doc/api_navigator/images/navigator.rightbtnimg.png +0 -0
  23. package/dist/data/ejs-doc/api_navigator/images/navigator.rightbtnimg2.png +0 -0
  24. package/dist/data/ejs-doc/api_navigator/images/navigator.rightmenu.png +0 -0
  25. package/dist/data/ejs-doc/api_navigator/images/navigator.searchbar.png +0 -0
  26. package/dist/data/ejs-doc/api_navigator/images/navigator.subtitle.jpg +0 -0
  27. package/dist/data/ejs-doc/api_navigator/images/navigator.title.png +0 -0
  28. package/dist/data/ejs-doc/api_page/api_page.md +261 -0
  29. package/dist/data/ejs-doc/api_runtime/api_runtime.md +788 -0
  30. package/dist/data/ejs-doc/api_storage/api_storage.md +320 -0
  31. package/dist/data/ejs-doc/api_stream/api_stream.md +152 -0
  32. package/dist/data/ejs-doc/api_stream/images/body_multiform.jpg +0 -0
  33. package/dist/data/ejs-doc/api_ui/api_ui.md +836 -0
  34. package/dist/data/ejs-doc/api_ui/images/ui.popwindow.png +0 -0
  35. package/dist/data/ejs-doc/api_ui/images/ui_actionsheet.png +0 -0
  36. package/dist/data/ejs-doc/api_ui/images/ui_alert.png +0 -0
  37. package/dist/data/ejs-doc/api_ui/images/ui_confirm.png +0 -0
  38. package/dist/data/ejs-doc/api_ui/images/ui_pickDateTime.png +0 -0
  39. package/dist/data/ejs-doc/api_ui/images/ui_pickdate.png +0 -0
  40. package/dist/data/ejs-doc/api_ui/images/ui_pickmonth.png +0 -0
  41. package/dist/data/ejs-doc/api_ui/images/ui_picktime.png +0 -0
  42. package/dist/data/ejs-doc/api_ui/images/ui_poppicker.png +0 -0
  43. package/dist/data/ejs-doc/api_ui/images/ui_poppicker2.png +0 -0
  44. package/dist/data/ejs-doc/api_ui/images/ui_poppicker3.png +0 -0
  45. package/dist/data/ejs-doc/api_ui/images/ui_prompt.png +0 -0
  46. package/dist/data/ejs-doc/api_ui/images/ui_select.png +0 -0
  47. package/dist/data/ejs-doc/api_ui/images/ui_select2.png +0 -0
  48. package/dist/data/ejs-doc/api_ui/images/ui_select3.png +0 -0
  49. package/dist/data/ejs-doc/api_ui/images/ui_showdebugdialog.png +0 -0
  50. package/dist/data/ejs-doc/api_ui/images/ui_showwaiting.png +0 -0
  51. package/dist/data/ejs-doc/api_ui/images/ui_toast.png +0 -0
  52. package/dist/data/ejs-doc/api_ui/images/ui_toastAndEvent.png +0 -0
  53. package/dist/data/ejs-doc/api_util/api_util.md +615 -0
  54. package/dist/data/ejs-doc/api_util/images/util.playvideo.png +0 -0
  55. package/dist/data/ejs-doc/api_util/images/util.previmage.png +0 -0
  56. package/dist/data/ejs-doc/api_util/images/util.selectfile.png +0 -0
  57. package/dist/data/ejs-doc/api_util/images/util.selectimage.png +0 -0
  58. package/dist/data/m8mpdoc-develop/003-/345/205/270/345/236/213/346/241/210/344/276/213/003-/345/210/227/350/241/250/350/257/246/346/203/205.md +247 -0
  59. package/dist/data/m8mpdoc-develop/003-/345/205/270/345/236/213/346/241/210/344/276/213/003-/345/210/227/350/241/250/350/257/246/346/203/205vue3.md +276 -0
  60. package/dist/data/m8mpdoc-develop/003-/345/205/270/345/236/213/346/241/210/344/276/213/003-/350/241/250/345/215/225/346/217/220/344/272/244.md +130 -0
  61. package/dist/data/m8mpdoc-develop/003-/345/205/270/345/236/213/346/241/210/344/276/213/003-/350/241/250/345/215/225/346/217/220/344/272/244vue3.md +115 -0
  62. package/dist/data/m8mpdoc-develop/005-/346/240/270/345/277/203/351/200/232/347/224/250Util/000-/346/240/270/345/277/203/346/226/271/346/263/225.md +398 -0
  63. package/dist/data/m8mpdoc-develop/005-/346/240/270/345/277/203/351/200/232/347/224/250Util/001-Ajax/344/270/216/346/226/207/344/273/266/344/270/212/344/274/240.md +456 -0
  64. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/000-charset.md +128 -0
  65. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/001-base64.md +142 -0
  66. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/002-date.md +210 -0
  67. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/004-math.md +85 -0
  68. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/006-sha1.md +21 -0
  69. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/007-sha256.md +36 -0
  70. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/008-storage.md +128 -0
  71. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/009-string.md +148 -0
  72. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/010-Util/346/211/251/345/261/225/346/214/207/345/215/227.md +76 -0
  73. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/011-cookie.md +59 -0
  74. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/012-util-sm.md +95 -0
  75. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/013-1.baseapi.md +76 -0
  76. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/013-2.network.md +202 -0
  77. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/013-2.socketTask.md +92 -0
  78. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/013-3.uiapi.md +412 -0
  79. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/013-4.eventapi.md +146 -0
  80. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/013-5.otherapi.md +137 -0
  81. package/dist/data/m8mpdoc-develop/006-Util/345/267/245/345/205/267/351/233/206/014-util-mpVerifyManager.md +363 -0
  82. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/000-/347/273/204/344/273/266/345/272/223/344/270/213/350/275/275/344/275/277/347/224/250.md +188 -0
  83. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/001-actionsheet/345/212/250/344/275/234/351/235/242/346/235/277.md +460 -0
  84. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/004-amap/345/234/260/345/233/276.md +285 -0
  85. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/005-button/346/214/211/351/222/256.md +211 -0
  86. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/008-cell/345/215/225/345/205/203/346/240/274.md +213 -0
  87. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/009-checkbox/345/244/215/351/200/211/346/241/206.md +501 -0
  88. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/010-circle/347/216/257/345/275/242/350/277/233/345/272/246/346/235/241.md +168 -0
  89. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/011-datepicker/346/227/245/346/234/237/351/200/211/346/213/251.md +617 -0
  90. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/013-field/350/276/223/345/205/245/346/241/206.md +539 -0
  91. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/015-form/350/241/250/345/215/225.md +999 -0
  92. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/018-header/345/244/264/351/203/250/345/257/274/350/210/252/346/240/217.md +150 -0
  93. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/019-icon/345/233/276/346/240/207.md +133 -0
  94. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/020-loading/345/212/240/350/275/275.md +117 -0
  95. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/021-noticebar/351/200/232/347/237/245/346/240/217.md +152 -0
  96. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/022-numberkeyboard/346/225/260/345/255/227/351/224/256/347/233/230.md +427 -0
  97. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/023-pagination/345/210/206/351/241/265.md +212 -0
  98. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/024-panel/351/235/242/346/235/277.md +85 -0
  99. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/025-passwordinput/345/257/206/347/240/201/350/276/223/345/205/245/346/241/206.md +175 -0
  100. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/026-picker/351/200/211/346/213/251/345/231/250.md +519 -0
  101. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/027-popup/345/274/271/345/207/272/345/261/202.md +152 -0
  102. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/028-progress/350/277/233/345/272/246/346/235/241.md +103 -0
  103. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/029-radio/345/215/225/351/200/211/346/241/206.md +285 -0
  104. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/030-rate/350/257/204/345/210/206.md +189 -0
  105. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/031-search/346/220/234/347/264/242.md +217 -0
  106. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/032-slider/346/273/221/345/235/227.md +166 -0
  107. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/033-stepper/346/255/245/350/277/233/345/231/250.md +340 -0
  108. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/035-swipecell/346/273/221/345/212/250/345/215/225/345/205/203/346/240/274.md +265 -0
  109. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/036-switch/345/274/200/345/205/263.md +196 -0
  110. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/037-switchcell/345/274/200/345/205/263/345/215/225/345/205/203/346/240/274.md +115 -0
  111. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/038-tag/346/240/207/350/256/260.md +232 -0
  112. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/039-treeselect/345/210/206/347/261/273/351/200/211/346/213/251.md +631 -0
  113. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/040-uploader/346/226/207/344/273/266/344/270/212/344/274/240.md +531 -0
  114. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/041-verifycode/351/252/214/350/257/201/347/240/201.md +111 -0
  115. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/042-minirefresh/344/270/213/346/213/211/345/210/267/346/226/260.md +337 -0
  116. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/043-layout/345/270/203/345/261/200.md +150 -0
  117. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/044-image/345/233/276/347/211/207.md +144 -0
  118. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/045-toast/350/275/273/346/217/220/347/244/272.md +429 -0
  119. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/046-calendar/346/227/245/345/216/206.md +467 -0
  120. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/047-area/347/234/201/345/270/202/345/214/272/351/200/211/346/213/251.md +295 -0
  121. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/048-tab/346/240/207/347/255/276/351/241/265.md +577 -0
  122. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/049-dialog/345/274/271/345/207/272/346/241/206.md +491 -0
  123. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/050-dropdownmenu/344/270/213/346/213/211/350/217/234/345/215/225.md +265 -0
  124. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/051-notify/346/266/210/346/201/257/351/200/232/347/237/245.md +203 -0
  125. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/052-overlay/351/201/256/347/275/251/345/261/202.md +139 -0
  126. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/053-collapse/346/212/230/345/217/240/351/235/242/346/235/277.md +199 -0
  127. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/054-grid/345/256/253/346/240/274.md +183 -0
  128. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/055-countdown/345/200/222/350/256/241/346/227/266.md +289 -0
  129. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/056-divider/345/210/206/345/211/262/347/272/277.md +97 -0
  130. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/057-empty/347/251/272/347/212/266/346/200/201.md +146 -0
  131. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/058-imagepreview/345/233/276/347/211/207/351/242/204/350/247/210.md +292 -0
  132. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/059-lazyload/346/207/222/345/212/240/350/275/275.md +120 -0
  133. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/060-skeleton/351/252/250/346/236/266/345/261/217.md +114 -0
  134. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/061-steps/346/255/245/351/252/244/346/235/241.md +119 -0
  135. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/062-sticky/347/262/230/346/200/247/345/270/203/345/261/200.md +208 -0
  136. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/063-indexbar/347/264/242/345/274/225/346/240/217.md +161 -0
  137. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/064-sidebar/344/276/247/350/276/271/345/257/274/350/210/252.md +248 -0
  138. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/065-tabbar/346/240/207/347/255/276/346/240/217.md +314 -0
  139. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/066-badge/345/276/275/346/240/207.md +162 -0
  140. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/067-popover/346/260/224/346/263/241/345/274/271/345/207/272/346/241/206.md +325 -0
  141. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/068-cascader/347/272/247/350/201/224/351/200/211/346/213/251.md +360 -0
  142. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/069-selectperson/351/200/211/344/272/272/347/273/204/344/273/266.md +595 -0
  143. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/070-swipe/350/275/256/346/222/255.md +262 -0
  144. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/071-/345/233/275/351/231/205/345/214/226.md +51 -0
  145. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/072-easycalendar/346/227/245/345/216/206.md +132 -0
  146. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/073-qrcode/344/272/214/347/273/264/347/240/201.md +1538 -0
  147. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/074-imagescale/345/233/276/347/211/207/350/243/201/345/211/252.md +261 -0
  148. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/075-dragsort/346/213/226/346/213/275/346/216/222/345/272/217.md +161 -0
  149. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/076-chart/345/233/276/350/241/250.md +381 -0
  150. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/077-rtc/351/237/263/350/247/206/351/242/221.md +531 -0
  151. package/dist/data/m8mpdoc-develop/009-UI/347/273/204/344/273/266/078-table/350/241/250/346/240/274.md +849 -0
  152. package/dist/data/m8mpdoc-develop/012-Mock/347/232/204/344/275/277/347/224/250/Mock/347/232/204/344/275/277/347/224/250.md +116 -0
  153. package/dist/data/standards/css-style.md +531 -0
  154. package/dist/data/standards/js-style.md +394 -0
  155. package/dist/data/standards/project-structure.md +325 -0
  156. package/dist/data/standards/vue-style.md +644 -0
  157. package/dist/index.js +1 -0
  158. package/dist/tools/search.js +1 -0
  159. package/dist/tools/standards.js +1 -0
  160. package/package.json +43 -0
@@ -0,0 +1,394 @@
1
+ # JavaScript/TypeScript 编码规范
2
+
3
+ <!-- id: js-style -->
4
+ <!-- category: javascript -->
5
+ <!-- version: 1.0.0 -->
6
+ <!-- lastUpdated: 2024-12-19 -->
7
+
8
+ 本规范定义了 M8 框架项目中 JavaScript/TypeScript 的编码标准。
9
+
10
+ ## 命名规范
11
+
12
+ ### 变量和函数使用 camelCase
13
+
14
+ ```javascript
15
+ // ✅ 正确
16
+ const userName = "John";
17
+ const itemCount = 10;
18
+ function getUserInfo() {}
19
+ function handleClick() {}
20
+
21
+ // ❌ 错误
22
+ const user_name = "John";
23
+ const ItemCount = 10;
24
+ function GetUserInfo() {}
25
+ ```
26
+
27
+ ### 常量使用 UPPER_SNAKE_CASE
28
+
29
+ ```javascript
30
+ // ✅ 正确
31
+ const MAX_COUNT = 100;
32
+ const API_BASE_URL = "/api";
33
+ const DEFAULT_PAGE_SIZE = 20;
34
+
35
+ // ❌ 错误
36
+ const maxCount = 100;
37
+ const apiBaseUrl = "/api";
38
+ ```
39
+
40
+ ### 类和组件使用 PascalCase
41
+
42
+ ```javascript
43
+ // ✅ 正确
44
+ class UserService {}
45
+ class DataManager {}
46
+ const UserProfile = defineComponent({});
47
+
48
+ // ❌ 错误
49
+ class userService {}
50
+ class data_manager {}
51
+ ```
52
+
53
+ ## 函数规范
54
+
55
+ ### 函数应该只做一件事
56
+
57
+ ```javascript
58
+ // ✅ 正确
59
+ function validateEmail(email) {
60
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
61
+ }
62
+
63
+ function formatUserName(user) {
64
+ return `${user.firstName} ${user.lastName}`;
65
+ }
66
+
67
+ // ❌ 错误 - 函数做了太多事情
68
+ function processUser(user) {
69
+ // 验证
70
+ if (!user.email.includes("@")) {
71
+ throw new Error("Invalid email");
72
+ }
73
+ // 格式化
74
+ user.fullName = user.firstName + " " + user.lastName;
75
+ // 保存
76
+ saveToDatabase(user);
77
+ // 发送通知
78
+ sendNotification(user);
79
+ }
80
+ ```
81
+
82
+ ### 使用默认参数
83
+
84
+ ```javascript
85
+ // ✅ 正确
86
+ function createUser(name, role = "user", active = true) {
87
+ return { name, role, active };
88
+ }
89
+
90
+ // ❌ 错误
91
+ function createUser(name, role, active) {
92
+ role = role || "user";
93
+ active = active !== undefined ? active : true;
94
+ return { name, role, active };
95
+ }
96
+ ```
97
+
98
+ ### 使用解构参数
99
+
100
+ ```javascript
101
+ // ✅ 正确
102
+ function updateUser({ id, name, email }) {
103
+ // ...
104
+ }
105
+
106
+ updateUser({ id: 1, name: "John", email: "john@example.com" });
107
+
108
+ // ❌ 错误
109
+ function updateUser(id, name, email) {
110
+ // ...
111
+ }
112
+ ```
113
+
114
+ ## 异步处理
115
+
116
+ ### 优先使用 async/await
117
+
118
+ ```javascript
119
+ // ✅ 正确
120
+ async function fetchUserData(userId) {
121
+ try {
122
+ const response = await Util.ajax({
123
+ url: `${Config.serverUrl}/api/user/${userId}`,
124
+ type: "GET",
125
+ });
126
+ return response.data;
127
+ } catch (error) {
128
+ console.error("获取用户数据失败:", error);
129
+ throw error;
130
+ }
131
+ }
132
+
133
+ // ❌ 不推荐 - 回调地狱
134
+ function fetchUserData(userId, callback) {
135
+ Util.ajax({
136
+ url: `${Config.serverUrl}/api/user/${userId}`,
137
+ success: (response) => {
138
+ Util.ajax({
139
+ url: `${Config.serverUrl}/api/user/${response.data.id}/profile`,
140
+ success: (profile) => {
141
+ callback(null, { ...response.data, profile: profile.data });
142
+ },
143
+ error: callback,
144
+ });
145
+ },
146
+ error: callback,
147
+ });
148
+ }
149
+ ```
150
+
151
+ ### 并发请求使用 Promise.all 或 Util.ajaxAll
152
+
153
+ ```javascript
154
+ // ✅ 正确
155
+ async function loadPageData() {
156
+ const [users, products, orders] = await Promise.all([
157
+ fetchUsers(),
158
+ fetchProducts(),
159
+ fetchOrders(),
160
+ ]);
161
+
162
+ return { users, products, orders };
163
+ }
164
+
165
+ // 或使用 Util.ajaxAll
166
+ const ajax1 = Util.ajax({ url: "/api/users" });
167
+ const ajax2 = Util.ajax({ url: "/api/products" });
168
+
169
+ Util.ajaxAll(ajax1, ajax2).then(([users, products]) => {
170
+ // 处理数据
171
+ });
172
+ ```
173
+
174
+ ## 错误处理
175
+
176
+ ### 使用 try-catch 处理异步错误
177
+
178
+ ```javascript
179
+ // ✅ 正确
180
+ async function submitForm(data) {
181
+ try {
182
+ const result = await Util.ajax({
183
+ url: Config.serverUrl + "/api/submit",
184
+ type: "POST",
185
+ data: { params: JSON.stringify(data) },
186
+ });
187
+
188
+ if (result.code === 1) {
189
+ return result.data;
190
+ } else {
191
+ throw new Error(result.message || "提交失败");
192
+ }
193
+ } catch (error) {
194
+ // 统一错误处理
195
+ console.error("表单提交失败:", error);
196
+ ejs.ui.toast({ message: error.message || "网络错误,请重试" });
197
+ throw error;
198
+ }
199
+ }
200
+ ```
201
+
202
+ ### 提供有意义的错误信息
203
+
204
+ ```javascript
205
+ // ✅ 正确
206
+ function validateAge(age) {
207
+ if (typeof age !== "number") {
208
+ throw new TypeError(`年龄必须是数字,收到: ${typeof age}`);
209
+ }
210
+ if (age < 0 || age > 150) {
211
+ throw new RangeError(`年龄必须在 0-150 之间,收到: ${age}`);
212
+ }
213
+ }
214
+
215
+ // ❌ 错误
216
+ function validateAge(age) {
217
+ if (typeof age !== "number" || age < 0 || age > 150) {
218
+ throw new Error("Invalid");
219
+ }
220
+ }
221
+ ```
222
+
223
+ ## M8 框架最佳实践
224
+
225
+ ### 使用 Util.ajax 进行 HTTP 请求
226
+
227
+ ```javascript
228
+ // ✅ 正确 - 使用 Util.ajax
229
+ const result = await Util.ajax({
230
+ url: Config.serverUrl + "/api/data",
231
+ type: "POST",
232
+ data: { params: JSON.stringify(params) },
233
+ dataPath: "data",
234
+ });
235
+
236
+ // ❌ 错误 - 使用原生 fetch 或不存在的 API
237
+ const result = await fetch("/api/data");
238
+ const result = await ejs.http.post("/api/data"); // 不存在的 API
239
+ ```
240
+
241
+ ### 使用 Config 管理配置
242
+
243
+ ```javascript
244
+ // ✅ 正确
245
+ const apiUrl = Config.serverUrl + "/api/users";
246
+ const timeout = Config.requestTimeout;
247
+
248
+ // ❌ 错误 - 硬编码
249
+ const apiUrl = "http://localhost:3000/api/users";
250
+ ```
251
+
252
+ ## 反模式
253
+
254
+ ### 避免使用 var
255
+
256
+ ```javascript
257
+ // ❌ 错误
258
+ var count = 0;
259
+ var name = "John";
260
+
261
+ // ✅ 正确
262
+ const name = "John"; // 不会重新赋值
263
+ let count = 0; // 会重新赋值
264
+ ```
265
+
266
+ ### 避免修改函数参数
267
+
268
+ ```javascript
269
+ // ❌ 错误
270
+ function updateUser(user) {
271
+ user.name = "New Name"; // 直接修改参数
272
+ return user;
273
+ }
274
+
275
+ // ✅ 正确
276
+ function updateUser(user) {
277
+ return {
278
+ ...user,
279
+ name: "New Name",
280
+ };
281
+ }
282
+ ```
283
+
284
+ ### 避免使用 == 进行比较
285
+
286
+ ```javascript
287
+ // ❌ 错误
288
+ if (value == null) {
289
+ }
290
+ if (count == "0") {
291
+ }
292
+
293
+ // ✅ 正确
294
+ if (count === 0) {
295
+ }
296
+ ```
297
+
298
+ ## M8 框架 JS 开发规范
299
+
300
+ ### 全局变量与工具类
301
+
302
+ 以下变量和方法在 M8 框架中已经全局注入,**严禁通过 import 导入**:
303
+
304
+ - `Config`: 全局配置对象 (如 `Config.serverUrl`)
305
+ - `Util`: 全局工具方法
306
+
307
+ ```javascript
308
+ // ❌ 错误
309
+ import { Util } from "@shared";
310
+ import { Config } from "@config";
311
+
312
+ // ✅ 正确
313
+ Util.string.isMobile("13800000000");
314
+ const url = Config.serverUrl + "/api/list";
315
+ ```
316
+
317
+ ### 字符串校验 (Util.string)
318
+
319
+ 优先使用 `Util.string` 提供的校验方法,而不是手写正则:
320
+
321
+ - `isMobile(str)`: 手机号
322
+ - `isTel(str)`: 固定电话
323
+ - `isPhone(str)`: 电话 (手机或固话)
324
+ - `isEmail(str)`: 邮箱
325
+ - `isIdCard(str)`: 身份证
326
+ - `isPostCode(str)`: 邮政编码
327
+ - `isOrgCode(str)`: 组织机构代码
328
+
329
+ ### 页面导航 (ejs.page)
330
+
331
+ 使用 `ejs.page` 系列 API 进行页面跳转:
332
+
333
+ ```javascript
334
+ // 打开新页面
335
+ ejs.page.open({
336
+ pageUrl: "./detail", // 同模块相对路径
337
+ // pageUrl: '../other_module/index', // 跨模块路径
338
+ data: { id: "123" }, // 传递参数
339
+ success: (result) => {
340
+ // 目标页面关闭并返回数据时触发
341
+ console.log("Returned:", result.resultData);
342
+ },
343
+ });
344
+
345
+ // 关闭当前页面
346
+ ejs.page.close({
347
+ resultData: { status: "success" },
348
+ });
349
+ ```
350
+
351
+ ### 接收页面参数
352
+
353
+ - **Vue2**: `Util.getExtraDataByKey('key')` (在 `created` 中)
354
+ - **Vue3**: `onLoad((options) => { ... })` (在 `setup` 中)
355
+
356
+ ### 网络请求 (Util.ajax)
357
+
358
+ 必须使用 `Util.ajax` 进行网络请求,**禁止使用原生 fetch 或 axios**。
359
+
360
+ ```javascript
361
+ Util.ajax({
362
+ url: `${Config.serverUrl}/rest/api/list`,
363
+ type: "POST",
364
+ data: {
365
+ params: JSON.stringify({ keyword: "test" }),
366
+ },
367
+ // dataPath: 'custom.infolist' // 可选,自动提取数据路径
368
+ })
369
+ .then((res) => {
370
+ if (res.status.code === 1) {
371
+ // handle success
372
+ } else {
373
+ ejs.ui.toast(res.status.text);
374
+ }
375
+ })
376
+ .catch((err) => {
377
+ console.error(err);
378
+ });
379
+ ```
380
+
381
+ ### 日志输出规范
382
+
383
+ - 禁止使用无参数的 `console.log`。
384
+ - 必须包含日志信息描述。
385
+ - 关键逻辑(如表单提交、接口错误)必须打日志。
386
+
387
+ ```javascript
388
+ // ❌ 错误
389
+ console.log(data);
390
+
391
+ // ✅ 正确
392
+ console.log("提交表单数据:", data);
393
+ console.error("接口请求失败:", err);
394
+ ```
@@ -0,0 +1,325 @@
1
+ # 项目结构规范
2
+
3
+ <!-- id: project-structure -->
4
+ <!-- category: project -->
5
+ <!-- version: 1.0.0 -->
6
+ <!-- lastUpdated: 2024-12-19 -->
7
+
8
+ 本规范定义了 M8 框架项目的目录结构和文件组织标准。
9
+
10
+ ## 目录结构
11
+
12
+ ### 标准项目结构
13
+
14
+ ```
15
+ project/
16
+ ├── src/
17
+ │ ├── api/ # API 接口定义
18
+ │ │ ├── index.js # API 统一导出
19
+ │ │ ├── user.js # 用户相关接口
20
+ │ │ └── order.js # 订单相关接口
21
+ │ ├── assets/ # 静态资源
22
+ │ │ ├── images/ # 图片资源
23
+ │ │ ├── styles/ # 全局样式
24
+ │ │ └── fonts/ # 字体文件
25
+ │ ├── components/ # 公共组件
26
+ │ │ ├── common/ # 通用组件
27
+ │ │ └── business/ # 业务组件
28
+ │ ├── composables/ # Vue3 组合式函数 (M8.4)
29
+ │ ├── hooks/ # 自定义 hooks
30
+ │ ├── pages/ # 页面组件
31
+ │ ├── router/ # 路由配置
32
+ │ ├── store/ # 状态管理
33
+ │ │ ├── index.js
34
+ │ │ └── modules/
35
+ │ ├── utils/ # 工具函数
36
+ │ ├── App.vue # 根组件
37
+ │ └── main.js # 入口文件
38
+ ├── public/ # 公共资源(不经过构建)
39
+ ├── config/ # 项目配置
40
+ ├── tests/ # 测试文件
41
+ ├── package.json
42
+ └── README.md
43
+ ```
44
+
45
+ ## 文件命名
46
+
47
+ ### 组件文件
48
+
49
+ 组件文件使用 PascalCase 命名。
50
+
51
+ ```
52
+ // ✅ 正确
53
+ components/
54
+ ├── UserProfile.vue
55
+ ├── TodoList.vue
56
+ ├── SearchInput.vue
57
+ └── common/
58
+ ├── BaseButton.vue
59
+ └── BaseInput.vue
60
+
61
+ // ❌ 错误
62
+ components/
63
+ ├── userProfile.vue
64
+ ├── todo-list.vue
65
+ └── searchinput.vue
66
+ ```
67
+
68
+ ### 页面文件
69
+
70
+ 页面文件应严格按照模块划分,每个模块对应一个文件夹。文件名应与模块名保持一致(m8 规范),或使用 kebab-case(通用规范)。
71
+
72
+ ```
73
+ // ✅ 正确
74
+ pages/
75
+ ├── home/
76
+ │ └── index.vue
77
+ ├── user/
78
+ │ ├── index.vue
79
+ │ ├── profile.vue
80
+ │ └── settings.vue
81
+ └── order/
82
+ ├── list.vue
83
+ └── detail.vue
84
+ ```
85
+
86
+ ### 工具函数文件
87
+
88
+ 工具函数文件使用 kebab-case 命名。
89
+
90
+ ```
91
+ // ✅ 正确
92
+ utils/
93
+ ├── date-format.js
94
+ ├── string-utils.js
95
+ ├── validate.js
96
+ └── index.js
97
+
98
+ // ❌ 错误
99
+ utils/
100
+ ├── dateFormat.js
101
+ ├── StringUtils.js
102
+ ```
103
+
104
+ ## API 组织
105
+
106
+ ### 按模块组织 API
107
+
108
+ ```javascript
109
+ // api/user.js
110
+ import { request } from "./request";
111
+
112
+ /**
113
+ * 获取用户信息
114
+ */
115
+ export function getUserInfo(userId) {
116
+ return request({
117
+ url: `/api/user/${userId}`,
118
+ method: "GET",
119
+ });
120
+ }
121
+
122
+ /**
123
+ * 更新用户信息
124
+ */
125
+ export function updateUserInfo(data) {
126
+ return request({
127
+ url: "/api/user/update",
128
+ method: "POST",
129
+ data,
130
+ });
131
+ }
132
+
133
+ // api/index.js - 统一导出
134
+ export * from "./user";
135
+ export * from "./order";
136
+ export * from "./product";
137
+ ```
138
+
139
+ ### 请求封装
140
+
141
+ ```javascript
142
+ // api/request.js
143
+ /**
144
+ * 统一请求封装
145
+ */
146
+ export function request(options) {
147
+ return Util.ajax({
148
+ url: Config.serverUrl + options.url,
149
+ type: options.method || "POST",
150
+ data: options.data ? { params: JSON.stringify(options.data) } : undefined,
151
+ dataPath: options.dataPath || "data",
152
+ ...options,
153
+ });
154
+ }
155
+ ```
156
+
157
+ ## 组件组织
158
+
159
+ ### 公共组件
160
+
161
+ 公共组件放在 `components/common/` 目录下,使用 `Base` 或 `Ne` 前缀。
162
+
163
+ ```
164
+ components/
165
+ ├── common/
166
+ │ ├── BaseButton.vue # 基础按钮
167
+ │ ├── BaseInput.vue # 基础输入框
168
+ │ ├── BaseModal.vue # 基础弹窗
169
+ │ └── index.js # 统一导出
170
+ └── business/
171
+ ├── UserCard.vue # 用户卡片
172
+ ├── OrderItem.vue # 订单项
173
+ └── index.js
174
+ ```
175
+
176
+ ### 页面级组件
177
+
178
+ 页面特有的组件放在页面目录下的 `components/` 子目录中。
179
+
180
+ ```
181
+ pages/
182
+ └── order/
183
+ ├── index.vue
184
+ ├── detail.vue
185
+ └── components/
186
+ ├── OrderHeader.vue
187
+ ├── OrderItems.vue
188
+ └── OrderFooter.vue
189
+ ```
190
+
191
+ ## 状态管理
192
+
193
+ ### Vuex 模块化 (M8.3)
194
+
195
+ ```
196
+ store/
197
+ ├── index.js
198
+ └── modules/
199
+ ├── user.js
200
+ ├── cart.js
201
+ └── order.js
202
+ ```
203
+
204
+ ```javascript
205
+ // store/modules/user.js
206
+ export default {
207
+ namespaced: true,
208
+ state: () => ({
209
+ userInfo: null,
210
+ token: "",
211
+ }),
212
+ mutations: {
213
+ SET_USER_INFO(state, info) {
214
+ state.userInfo = info;
215
+ },
216
+ },
217
+ actions: {
218
+ async fetchUserInfo({ commit }) {
219
+ const result = await getUserInfo();
220
+ commit("SET_USER_INFO", result);
221
+ },
222
+ },
223
+ };
224
+ ```
225
+
226
+ ### Pinia 模块化 (M8.4)
227
+
228
+ ```
229
+ store/
230
+ ├── index.js
231
+ └── modules/
232
+ ├── useUserStore.js
233
+ ├── useCartStore.js
234
+ └── useOrderStore.js
235
+ ```
236
+
237
+ ```javascript
238
+ // store/modules/useUserStore.js
239
+ import { defineStore } from "pinia";
240
+
241
+ export const useUserStore = defineStore("user", {
242
+ state: () => ({
243
+ userInfo: null,
244
+ token: "",
245
+ }),
246
+ actions: {
247
+ async fetchUserInfo() {
248
+ const result = await getUserInfo();
249
+ this.userInfo = result;
250
+ },
251
+ },
252
+ });
253
+ ```
254
+
255
+ ## 样式组织
256
+
257
+ ### 全局样式
258
+
259
+ ```
260
+ assets/
261
+ └── styles/
262
+ ├── index.scss # 样式入口
263
+ ├── variables.scss # 变量定义
264
+ ├── mixins.scss # 混入
265
+ ├── reset.scss # 重置样式
266
+ └── utils.scss # 工具类
267
+ ```
268
+
269
+ ### 组件样式
270
+
271
+ 组件样式使用 scoped 或 CSS Modules。
272
+
273
+ ```vue
274
+ <!-- 使用 scoped -->
275
+ <style scoped lang="scss">
276
+ .user-card {
277
+ // ...
278
+ }
279
+ </style>
280
+
281
+ <!-- 或使用 CSS Modules -->
282
+ <style module lang="scss">
283
+ .userCard {
284
+ // ...
285
+ }
286
+ </style>
287
+ ```
288
+
289
+ ## 反模式
290
+
291
+ ### 避免过深的目录嵌套
292
+
293
+ ```
294
+ // ❌ 错误 - 嵌套过深
295
+ src/modules/user/pages/profile/components/header/UserAvatar.vue
296
+
297
+ // ✅ 正确 - 扁平化
298
+ src/pages/user/profile.vue
299
+ src/components/UserAvatar.vue
300
+ ```
301
+
302
+ ### 避免循环依赖
303
+
304
+ ```javascript
305
+ // ❌ 错误 - 循环依赖
306
+ // a.js
307
+ import { b } from "./b";
308
+ export const a = b + 1;
309
+
310
+ // b.js
311
+ import { a } from "./a";
312
+ export const b = a + 1;
313
+
314
+ // ✅ 正确 - 提取公共依赖
315
+ // constants.js
316
+ export const BASE = 1;
317
+
318
+ // a.js
319
+ import { BASE } from "./constants";
320
+ export const a = BASE + 1;
321
+
322
+ // b.js
323
+ import { BASE } from "./constants";
324
+ export const b = BASE + 2;
325
+ ```