m8-codex-mcp 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.
- package/README.md +113 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/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
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/001-actionsheet/345/212/250/344/275/234/351/235/242/346/235/277.md +460 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/004-amap/345/234/260/345/233/276.md +285 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/005-button/346/214/211/351/222/256.md +211 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/008-cell/345/215/225/345/205/203/346/240/274.md +213 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/009-checkbox/345/244/215/351/200/211/346/241/206.md +501 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/010-circle/347/216/257/345/275/242/350/277/233/345/272/246/346/235/241.md +168 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/011-datepicker/346/227/245/346/234/237/351/200/211/346/213/251.md +617 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/013-field/350/276/223/345/205/245/346/241/206.md +539 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/015-form/350/241/250/345/215/225.md +999 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/018-header/345/244/264/351/203/250/345/257/274/350/210/252/346/240/217.md +150 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/019-icon/345/233/276/346/240/207.md +133 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/020-loading/345/212/240/350/275/275.md +117 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/021-noticebar/351/200/232/347/237/245/346/240/217.md +152 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/022-numberkeyboard/346/225/260/345/255/227/351/224/256/347/233/230.md +427 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/023-pagination/345/210/206/351/241/265.md +212 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/024-panel/351/235/242/346/235/277.md +85 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/025-passwordinput/345/257/206/347/240/201/350/276/223/345/205/245/346/241/206.md +175 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/026-picker/351/200/211/346/213/251/345/231/250.md +519 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/027-popup/345/274/271/345/207/272/345/261/202.md +152 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/028-progress/350/277/233/345/272/246/346/235/241.md +103 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/029-radio/345/215/225/351/200/211/346/241/206.md +285 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/030-rate/350/257/204/345/210/206.md +189 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/031-search/346/220/234/347/264/242.md +217 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/032-slider/346/273/221/345/235/227.md +166 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/033-stepper/346/255/245/350/277/233/345/231/250.md +340 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/035-swipecell/346/273/221/345/212/250/345/215/225/345/205/203/346/240/274.md +265 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/036-switch/345/274/200/345/205/263.md +196 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/037-switchcell/345/274/200/345/205/263/345/215/225/345/205/203/346/240/274.md +115 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/038-tag/346/240/207/350/256/260.md +232 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/039-treeselect/345/210/206/347/261/273/351/200/211/346/213/251.md +631 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/040-uploader/346/226/207/344/273/266/344/270/212/344/274/240.md +531 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/041-verifycode/351/252/214/350/257/201/347/240/201.md +111 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/042-minirefresh/344/270/213/346/213/211/345/210/267/346/226/260.md +337 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/043-layout/345/270/203/345/261/200.md +150 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/044-image/345/233/276/347/211/207.md +144 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/045-toast/350/275/273/346/217/220/347/244/272.md +429 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/046-calendar/346/227/245/345/216/206.md +467 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/047-area/347/234/201/345/270/202/345/214/272/351/200/211/346/213/251.md +295 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/048-tab/346/240/207/347/255/276/351/241/265.md +577 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/049-dialog/345/274/271/345/207/272/346/241/206.md +491 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/050-dropdownmenu/344/270/213/346/213/211/350/217/234/345/215/225.md +265 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/051-notify/346/266/210/346/201/257/351/200/232/347/237/245.md +203 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/052-overlay/351/201/256/347/275/251/345/261/202.md +139 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/053-collapse/346/212/230/345/217/240/351/235/242/346/235/277.md +199 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/054-grid/345/256/253/346/240/274.md +183 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/055-countdown/345/200/222/350/256/241/346/227/266.md +289 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/056-divider/345/210/206/345/211/262/347/272/277.md +97 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/057-empty/347/251/272/347/212/266/346/200/201.md +146 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/058-imagepreview/345/233/276/347/211/207/351/242/204/350/247/210.md +292 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/059-lazyload/346/207/222/345/212/240/350/275/275.md +120 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/060-skeleton/351/252/250/346/236/266/345/261/217.md +114 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/061-steps/346/255/245/351/252/244/346/235/241.md +119 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/062-sticky/347/262/230/346/200/247/345/270/203/345/261/200.md +208 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/063-indexbar/347/264/242/345/274/225/346/240/217.md +161 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/064-sidebar/344/276/247/350/276/271/345/257/274/350/210/252.md +248 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/065-tabbar/346/240/207/347/255/276/346/240/217.md +314 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/066-badge/345/276/275/346/240/207.md +162 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/067-popover/346/260/224/346/263/241/345/274/271/345/207/272/346/241/206.md +325 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/068-cascader/347/272/247/350/201/224/351/200/211/346/213/251.md +360 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/069-selectperson/351/200/211/344/272/272/347/273/204/344/273/266.md +595 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/070-swipe/350/275/256/346/222/255.md +262 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/071-/345/233/275/351/231/205/345/214/226.md +51 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/072-easycalendar/346/227/245/345/216/206.md +132 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/073-qrcode/344/272/214/347/273/264/347/240/201.md +1538 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/074-imagescale/345/233/276/347/211/207/350/243/201/345/211/252.md +261 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/075-dragsort/346/213/226/346/213/275/346/216/222/345/272/217.md +161 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/076-chart/345/233/276/350/241/250.md +381 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/077-rtc/351/237/263/350/247/206/351/242/221.md +531 -0
- package/data/m8mpdoc/UI/347/273/204/344/273/266/345/272/223/078-table/350/241/250/346/240/274.md +849 -0
- package/data/m8mpdoc//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
- package/data/m8mpdoc//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
- package/data/m8mpdoc//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
- package/data/m8mpdoc//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
- package/data/m8mpdoc//346/240/270/345/277/203/351/200/232/347/224/250Util/345/267/245/345/205/267/345/272/223/Ajax/344/270/216/346/226/207/344/273/266/344/270/212/344/274/240.md +456 -0
- package/data/m8mpdoc//346/240/270/345/277/203/351/200/232/347/224/250Util/345/267/245/345/205/267/345/272/223//345/267/245/345/205/267/345/207/275/346/225/260/345/272/223.md +398 -0
- package/data/standards/01-project/naming.md +158 -0
- package/data/standards/01-project/structure.md +106 -0
- package/data/standards/01-project/version-detection.md +195 -0
- package/data/standards/02-vue/basic.md +242 -0
- package/data/standards/02-vue/component.md +299 -0
- package/data/standards/02-vue/examples.md +240 -0
- package/data/standards/02-vue/performance.md +74 -0
- package/data/standards/02-vue/state-management.md +293 -0
- package/data/standards/03-css/index.md +165 -0
- package/data/standards/04-api/ajax.md +178 -0
- package/data/standards/04-api/ejs-api.md +192 -0
- package/data/standards/04-api/util.md +166 -0
- package/data/standards/05-typescript/index.md +166 -0
- package/data/standards/06-mock/index.md +154 -0
- package/data/standards/07-router/index.md +141 -0
- package/data/standards/README.md +82 -0
- package/data/standards/_index.md +215 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/knowledge/index.d.ts +36 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +1 -0
- package/dist/templates/vue2.d.ts +41 -0
- package/dist/templates/vue2.d.ts.map +1 -0
- package/dist/templates/vue2.js +1 -0
- package/dist/templates/vue3.d.ts +41 -0
- package/dist/templates/vue3.d.ts.map +1 -0
- package/dist/templates/vue3.js +1 -0
- package/dist/tools/generate_module_structure.d.ts +21 -0
- package/dist/tools/generate_module_structure.d.ts.map +1 -0
- package/dist/tools/generate_module_structure.js +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# EJS API 规范
|
|
2
|
+
|
|
3
|
+
> 定义 M8 框架 EJS API 的使用规范与示例。
|
|
4
|
+
|
|
5
|
+
## 🚀 路由类 API
|
|
6
|
+
|
|
7
|
+
### ejs.page.open - 打开新页面
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// 完整用法
|
|
11
|
+
ejs.page.open({
|
|
12
|
+
pageUrl: "./detail", // 页面地址
|
|
13
|
+
pageStyle: 1,
|
|
14
|
+
orientation: 1,
|
|
15
|
+
alive: 0, // 0不保活,1保活
|
|
16
|
+
data: {
|
|
17
|
+
// 传递参数
|
|
18
|
+
id: "12345",
|
|
19
|
+
},
|
|
20
|
+
useRouter: true,
|
|
21
|
+
success: function (result) {
|
|
22
|
+
// 目标页面关闭后回调
|
|
23
|
+
},
|
|
24
|
+
error: function (error) {},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// 快速调用
|
|
28
|
+
ejs.page.open("./detail", { id: "12345" });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**URL 规则**:
|
|
32
|
+
|
|
33
|
+
- 同模块跳转:`'./路由名称'`
|
|
34
|
+
- 跨模块跳转:`'../模块名称/路由名称'`
|
|
35
|
+
|
|
36
|
+
### ejs.page.close - 关闭页面
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
// 完整用法
|
|
40
|
+
ejs.page.close({
|
|
41
|
+
resultData: { key: "value" },
|
|
42
|
+
success: function (result) {},
|
|
43
|
+
error: function (error) {},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// 快速调用
|
|
47
|
+
ejs.page.close(JSON.stringify({ key: "value" }));
|
|
48
|
+
ejs.page.close();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### ejs.page.replace - 替换页面
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
ejs.page.replace({
|
|
55
|
+
url: "./new-page",
|
|
56
|
+
success: function (result) {},
|
|
57
|
+
error: function (error) {},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// 快速调用
|
|
61
|
+
ejs.page.replace("./new-page");
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### ejs.page.reload - 重新加载
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
ejs.page.reload();
|
|
68
|
+
// 注意:微信小程序请使用 uniapp API
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 💬 UI 类 API
|
|
72
|
+
|
|
73
|
+
### ejs.ui.toast - 轻提示
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
ejs.ui.toast("操作成功");
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### ejs.ui.alert - 弹窗提示
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
// 完整用法
|
|
83
|
+
ejs.ui.alert({
|
|
84
|
+
title: "提示",
|
|
85
|
+
message: "操作已完成",
|
|
86
|
+
buttonName: "确定",
|
|
87
|
+
cancelable: 1,
|
|
88
|
+
h5UI: false,
|
|
89
|
+
success: function (result) {
|
|
90
|
+
// 点击按钮后回调
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// 快速调用
|
|
95
|
+
ejs.ui.alert(message, title, buttonName);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### ejs.ui.confirm - 确认对话框
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
ejs.ui.confirm({
|
|
102
|
+
title: "确认操作",
|
|
103
|
+
message: "是否删除该记录?",
|
|
104
|
+
buttonLabels: ["取消", "确定"],
|
|
105
|
+
cancelable: 1,
|
|
106
|
+
h5UI: false,
|
|
107
|
+
success: function (result) {
|
|
108
|
+
// result.which: 0=取消, 1=确定
|
|
109
|
+
if (result.which === 1) {
|
|
110
|
+
// 确认操作
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### ejs.ui.showWaiting / closeWaiting - 加载提示
|
|
117
|
+
|
|
118
|
+
```javascript
|
|
119
|
+
// 显示加载
|
|
120
|
+
ejs.ui.showWaiting("正在加载...");
|
|
121
|
+
|
|
122
|
+
// 关闭加载
|
|
123
|
+
ejs.ui.closeWaiting();
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 📅 选择器 API
|
|
127
|
+
|
|
128
|
+
### ejs.ui.pickDate - 日期选择
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
ejs.ui.pickDate({
|
|
132
|
+
title: "选择日期",
|
|
133
|
+
datetime: "2024-01-01", // 默认日期
|
|
134
|
+
minDate: "2020-01-01", // 最小日期
|
|
135
|
+
maxDate: "2030-12-31", // 最大日期
|
|
136
|
+
h5UI: false,
|
|
137
|
+
success: function (result) {
|
|
138
|
+
console.log(result.date); // '2024-01-15'
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### ejs.ui.pickTime - 时间选择
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
ejs.ui.pickTime({
|
|
147
|
+
title: "选择时间",
|
|
148
|
+
datetime: "10:30",
|
|
149
|
+
minHour: 0,
|
|
150
|
+
maxHour: 23,
|
|
151
|
+
minMinute: 0,
|
|
152
|
+
maxMinute: 59,
|
|
153
|
+
h5UI: false,
|
|
154
|
+
success: function (result) {
|
|
155
|
+
console.log(result.time); // '14:30'
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### ejs.ui.pickDateTime - 日期时间选择
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
ejs.ui.pickDateTime({
|
|
164
|
+
title: "选择日期时间",
|
|
165
|
+
datetime: "2024-01-01 10:30",
|
|
166
|
+
minDate: "2020-01-01",
|
|
167
|
+
maxDate: "2030-12-31",
|
|
168
|
+
h5UI: false,
|
|
169
|
+
success: function (result) {
|
|
170
|
+
console.log(result.datetime); // '2024-01-15 14:30'
|
|
171
|
+
console.log(result.week); // '周一'
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## 📌 使用优先级
|
|
177
|
+
|
|
178
|
+
> **API 优先于组件使用**
|
|
179
|
+
|
|
180
|
+
| 场景 | 使用方案 |
|
|
181
|
+
| ---------- | -------------------- |
|
|
182
|
+
| 消息提示 | `ejs.ui.toast` |
|
|
183
|
+
| 确认对话框 | `ejs.ui.confirm` |
|
|
184
|
+
| 加载提示 | `ejs.ui.showWaiting` |
|
|
185
|
+
| 日期选择 | `ejs.ui.pickDate` |
|
|
186
|
+
| 时间选择 | `ejs.ui.pickTime` |
|
|
187
|
+
|
|
188
|
+
## ✅ 检查清单
|
|
189
|
+
|
|
190
|
+
- [ ] 优先使用 EJS API 而非组件
|
|
191
|
+
- [ ] 页面跳转使用正确的 URL 格式
|
|
192
|
+
- [ ] 加载提示成对使用 show/close
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Util 工具方法
|
|
2
|
+
|
|
3
|
+
> M8 框架全局工具方法使用规范。`Util` 已全局注入,直接使用即可。
|
|
4
|
+
|
|
5
|
+
## ⚠️ 重要提示
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
// ❌ 禁止 import
|
|
9
|
+
import { Util } from "@shared";
|
|
10
|
+
|
|
11
|
+
// ✅ 直接使用
|
|
12
|
+
Util.string.isMobile("18888888888");
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 📱 Util.string - 字符串验证
|
|
16
|
+
|
|
17
|
+
### 手机号验证
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
Util.string.isMobile("18962299766"); // true
|
|
21
|
+
Util.string.isMobile("1896229976"); // false
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 固定电话验证
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
Util.string.isTel("051258222222"); // true
|
|
28
|
+
Util.string.isTel("1896229976"); // false
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 电话号码验证(手机+固话)
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
Util.string.isPhone("18962299766"); // true
|
|
35
|
+
Util.string.isPhone("051258222222"); // true
|
|
36
|
+
Util.string.isPhone("1896229976"); // false
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 邮箱验证
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
Util.string.isEmail("test@qq.com"); // true
|
|
43
|
+
Util.string.isEmail("user.name@example.com"); // true
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 邮政编码验证
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
Util.string.isPostCode("215600"); // true
|
|
50
|
+
Util.string.isPostCode("21560"); // false
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 组织机构代码验证
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
Util.string.isOrgCode("91320582704068740Y"); // true
|
|
57
|
+
Util.string.isOrgCode("91320582704068740a"); // false
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 身份证验证
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
Util.string.isIdCard("320926195511175276"); // true
|
|
64
|
+
Util.string.isIdCard("320582199566666614"); // false
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 🔑 Util.uuid - 唯一标识生成
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
const id = Util.uuid();
|
|
71
|
+
// 返回: "550e8400-e29b-41d4-a716-446655440000"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 🍪 Util.cookie - Cookie 操作
|
|
75
|
+
|
|
76
|
+
### 设置 Cookie
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
// 基础设置
|
|
80
|
+
Util.cookie.set("token", "abc123");
|
|
81
|
+
|
|
82
|
+
// 设置过期时间(秒)
|
|
83
|
+
Util.cookie.set("token", "abc123", { "max-age": "3600" });
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 获取 Cookie
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const token = Util.cookie.get("token");
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 删除 Cookie
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
// 默认路径
|
|
96
|
+
Util.cookie.remove("token");
|
|
97
|
+
|
|
98
|
+
// 自定义路径
|
|
99
|
+
Util.cookie.remove("token", { path: "/" });
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 📡 Util.ajax - 网络请求
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
Util.ajax({
|
|
106
|
+
url: Config.serverUrl + "/api/data",
|
|
107
|
+
data: {
|
|
108
|
+
params: JSON.stringify({ id: "123" }),
|
|
109
|
+
},
|
|
110
|
+
})
|
|
111
|
+
.then((res) => {
|
|
112
|
+
console.log("成功:", res);
|
|
113
|
+
})
|
|
114
|
+
.catch((error) => {
|
|
115
|
+
console.error("失败:", error);
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## 📤 Util.upload - 文件上传
|
|
120
|
+
|
|
121
|
+
```javascript
|
|
122
|
+
Util.upload({
|
|
123
|
+
url: Config.serverUrl + "/api/upload",
|
|
124
|
+
filePath: file.path,
|
|
125
|
+
name: file.name,
|
|
126
|
+
formData: { userId: "user123" },
|
|
127
|
+
success: (res) => {
|
|
128
|
+
console.log("上传成功:", res);
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 📦 Util.getExtraDataByKey - 获取传参(Vue2)
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
// Vue2 created 中获取页面传参
|
|
137
|
+
created() {
|
|
138
|
+
const id = Util.getExtraDataByKey('id') || '';
|
|
139
|
+
this.loadDetail(id);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## 📋 常用方法速查
|
|
144
|
+
|
|
145
|
+
| 方法 | 说明 |
|
|
146
|
+
| ----------------------------- | --------------------- |
|
|
147
|
+
| `Util.string.isMobile(str)` | 验证手机号 |
|
|
148
|
+
| `Util.string.isTel(str)` | 验证固定电话 |
|
|
149
|
+
| `Util.string.isPhone(str)` | 验证电话(手机+固话) |
|
|
150
|
+
| `Util.string.isEmail(str)` | 验证邮箱 |
|
|
151
|
+
| `Util.string.isPostCode(str)` | 验证邮政编码 |
|
|
152
|
+
| `Util.string.isIdCard(str)` | 验证身份证 |
|
|
153
|
+
| `Util.string.isOrgCode(str)` | 验证组织机构代码 |
|
|
154
|
+
| `Util.uuid()` | 生成 UUID |
|
|
155
|
+
| `Util.cookie.set(key, value)` | 设置 Cookie |
|
|
156
|
+
| `Util.cookie.get(key)` | 获取 Cookie |
|
|
157
|
+
| `Util.cookie.remove(key)` | 删除 Cookie |
|
|
158
|
+
| `Util.ajax(options)` | 发起请求 |
|
|
159
|
+
| `Util.upload(options)` | 文件上传 |
|
|
160
|
+
| `Util.getExtraDataByKey(key)` | 获取页面传参 |
|
|
161
|
+
|
|
162
|
+
## ✅ 检查清单
|
|
163
|
+
|
|
164
|
+
- [ ] 未通过 import 导入 Util
|
|
165
|
+
- [ ] 优先使用 Util 提供的验证方法
|
|
166
|
+
- [ ] 表单验证使用 Util.string 系列方法
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# TypeScript 规范
|
|
2
|
+
|
|
3
|
+
> 定义 M8 项目中 TypeScript 的使用规范。
|
|
4
|
+
|
|
5
|
+
## 📝 类型声明规范
|
|
6
|
+
|
|
7
|
+
### 必须显式声明类型
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ 正确:显式声明
|
|
11
|
+
const userName: string = "admin";
|
|
12
|
+
const userAge: number = 25;
|
|
13
|
+
const isActive: boolean = true;
|
|
14
|
+
|
|
15
|
+
// ❌ 错误:依赖推断的复杂类型
|
|
16
|
+
const userData = fetchUserData(); // 类型不明确
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 禁止使用 any
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// ❌ 禁止
|
|
23
|
+
const data: any = response.data;
|
|
24
|
+
function process(item: any) {}
|
|
25
|
+
|
|
26
|
+
// ✅ 正确:使用具体类型或 unknown
|
|
27
|
+
const data: UserInfo = response.data;
|
|
28
|
+
function process(item: unknown) {
|
|
29
|
+
if (isUserInfo(item)) {
|
|
30
|
+
// 类型收窄后使用
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 📦 接口与类型定义
|
|
36
|
+
|
|
37
|
+
### 命名规范
|
|
38
|
+
|
|
39
|
+
| 类型 | 规则 | 示例 |
|
|
40
|
+
| -------- | ------------------- | ------------- |
|
|
41
|
+
| 接口 | PascalCase + I 前缀 | `IUserInfo` |
|
|
42
|
+
| 类型 | PascalCase + T 前缀 | `TStatus` |
|
|
43
|
+
| 枚举替代 | 常量对象 | `USER_STATUS` |
|
|
44
|
+
|
|
45
|
+
### 优先使用接口
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// ✅ 推荐:接口(支持扩展和合并)
|
|
49
|
+
interface IUserInfo {
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
age: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface IUserInfo {
|
|
56
|
+
avatar?: string; // 接口合并
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ⚠️ 次选:类型别名
|
|
60
|
+
type TUserInfo = {
|
|
61
|
+
id: string;
|
|
62
|
+
name: string;
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 避免使用枚举
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// ❌ 避免:枚举
|
|
70
|
+
enum UserStatus {
|
|
71
|
+
Active = 1,
|
|
72
|
+
Inactive = 0,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ✅ 推荐:常量对象
|
|
76
|
+
const USER_STATUS = {
|
|
77
|
+
ACTIVE: 1,
|
|
78
|
+
INACTIVE: 0,
|
|
79
|
+
} as const;
|
|
80
|
+
|
|
81
|
+
type TUserStatus = (typeof USER_STATUS)[keyof typeof USER_STATUS];
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 🧩 组件 Props 定义
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// Vue3 组件 Props
|
|
88
|
+
interface IProps {
|
|
89
|
+
userId: string; // 必填
|
|
90
|
+
userName?: string; // 可选
|
|
91
|
+
userAge?: number; // 可选
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const props = withDefaults(defineProps<IProps>(), {
|
|
95
|
+
userName: "默认用户",
|
|
96
|
+
userAge: 0,
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 📋 常用类型定义
|
|
101
|
+
|
|
102
|
+
### API 响应类型
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// 通用响应结构
|
|
106
|
+
interface IApiResponse<T> {
|
|
107
|
+
status: {
|
|
108
|
+
code: number;
|
|
109
|
+
message: string;
|
|
110
|
+
};
|
|
111
|
+
custom: T;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 列表响应
|
|
115
|
+
interface IListResponse<T> {
|
|
116
|
+
infolist: T[];
|
|
117
|
+
total: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 使用示例
|
|
121
|
+
type TUserListResponse = IApiResponse<IListResponse<IUserInfo>>;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 表单数据类型
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
interface ILoginForm {
|
|
128
|
+
username: string;
|
|
129
|
+
password: string;
|
|
130
|
+
remember?: boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const form = ref<ILoginForm>({
|
|
134
|
+
username: "",
|
|
135
|
+
password: "",
|
|
136
|
+
remember: false,
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## ⚡ 类型工具
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// Partial - 所有属性可选
|
|
144
|
+
type TPartialUser = Partial<IUserInfo>;
|
|
145
|
+
|
|
146
|
+
// Required - 所有属性必填
|
|
147
|
+
type TRequiredUser = Required<IUserInfo>;
|
|
148
|
+
|
|
149
|
+
// Pick - 选取部分属性
|
|
150
|
+
type TUserBasic = Pick<IUserInfo, "id" | "name">;
|
|
151
|
+
|
|
152
|
+
// Omit - 排除部分属性
|
|
153
|
+
type TUserWithoutId = Omit<IUserInfo, "id">;
|
|
154
|
+
|
|
155
|
+
// Record - 键值对类型
|
|
156
|
+
type TUserMap = Record<string, IUserInfo>;
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## ✅ TypeScript 检查清单
|
|
160
|
+
|
|
161
|
+
- [ ] 显式声明变量类型
|
|
162
|
+
- [ ] 未使用 any 类型
|
|
163
|
+
- [ ] 接口使用 I 前缀
|
|
164
|
+
- [ ] 类型使用 T 前缀
|
|
165
|
+
- [ ] 使用常量对象替代枚举
|
|
166
|
+
- [ ] Props 配合接口定义
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Mock 数据规范
|
|
2
|
+
|
|
3
|
+
> 定义 M8 项目中 Mock 数据的使用规范。
|
|
4
|
+
|
|
5
|
+
## 📁 文件位置
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/pages/[module_name]/
|
|
9
|
+
├── [module_name].vue
|
|
10
|
+
├── router.js
|
|
11
|
+
├── store.js
|
|
12
|
+
└── mock.js # Mock 数据定义
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
框架会自动引入模块下的 `mock.js` 文件。
|
|
16
|
+
|
|
17
|
+
## 📝 基础结构
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
import Mock from "@mock";
|
|
21
|
+
|
|
22
|
+
const resultData = [
|
|
23
|
+
{
|
|
24
|
+
methodUrl: "/rest/api/endpoint", // 接口地址
|
|
25
|
+
input: {}, // 入参(可选)
|
|
26
|
+
output: {}, // 出参(Mock 数据)
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export default resultData;
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 📋 列表数据示例
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
import Mock from "@mock";
|
|
37
|
+
|
|
38
|
+
const resultData = [
|
|
39
|
+
{
|
|
40
|
+
methodUrl: "/rest/mock/list",
|
|
41
|
+
input: {
|
|
42
|
+
keyword: "",
|
|
43
|
+
currentpageindex: "",
|
|
44
|
+
pagesize: "",
|
|
45
|
+
},
|
|
46
|
+
output: Mock.mock({
|
|
47
|
+
"infolist|10-20": [
|
|
48
|
+
{
|
|
49
|
+
title: () => Mock.Random.csentence(10),
|
|
50
|
+
date: () => Mock.Random.date(),
|
|
51
|
+
id: () => Mock.Random.guid(),
|
|
52
|
+
content: "来源:综合",
|
|
53
|
+
photo: () => Mock.Random.image("114x83", "#00405d", "#FFF", "Mock"),
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
}),
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
export default resultData;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 📄 详情数据示例
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
import Mock from "@mock";
|
|
67
|
+
|
|
68
|
+
const resultData = [
|
|
69
|
+
{
|
|
70
|
+
methodUrl: "/rest/mock/detail",
|
|
71
|
+
input: {
|
|
72
|
+
guid: "",
|
|
73
|
+
},
|
|
74
|
+
output: Mock.mock({
|
|
75
|
+
info: {
|
|
76
|
+
title: Mock.Random.csentence(5, 10),
|
|
77
|
+
content: Mock.Random.cparagraph(3, 5),
|
|
78
|
+
author: Mock.Random.cname(),
|
|
79
|
+
date: Mock.Random.date(),
|
|
80
|
+
views: Mock.Random.integer(100, 10000),
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
export default resultData;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 🎲 Mock.js 常用方法
|
|
90
|
+
|
|
91
|
+
| 方法 | 说明 | 示例 |
|
|
92
|
+
| ------------------------------- | ---------- | ---------------- |
|
|
93
|
+
| `Mock.Random.guid()` | 生成 GUID | `"550e8400-..."` |
|
|
94
|
+
| `Mock.Random.date()` | 随机日期 | `"2024-01-15"` |
|
|
95
|
+
| `Mock.Random.cname()` | 随机中文名 | `"张三"` |
|
|
96
|
+
| `Mock.Random.csentence(n)` | 中文句子 | `"这是一段..."` |
|
|
97
|
+
| `Mock.Random.cparagraph()` | 中文段落 | 多句话 |
|
|
98
|
+
| `Mock.Random.integer(min, max)` | 随机整数 | `256` |
|
|
99
|
+
| `Mock.Random.image(size)` | 随机图片 | URL |
|
|
100
|
+
|
|
101
|
+
### 数组生成语法
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// 生成 10-20 个元素的数组
|
|
105
|
+
'infolist|10-20': [{ ... }]
|
|
106
|
+
|
|
107
|
+
// 固定生成 5 个元素
|
|
108
|
+
'items|5': [{ ... }]
|
|
109
|
+
|
|
110
|
+
// 随机选择一个
|
|
111
|
+
'status|1': ['待处理', '处理中', '已完成']
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 📡 请求调用示例
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
Util.ajax({
|
|
118
|
+
url: `${Config.serverUrl}/rest/mock/list`,
|
|
119
|
+
data: {
|
|
120
|
+
params: JSON.stringify({
|
|
121
|
+
currentpageindex: 0,
|
|
122
|
+
pagesize: 10,
|
|
123
|
+
}),
|
|
124
|
+
},
|
|
125
|
+
})
|
|
126
|
+
.then((result) => {
|
|
127
|
+
if (result?.status?.code === 1) {
|
|
128
|
+
// 获取 mock 数据
|
|
129
|
+
console.log(result.custom.infolist);
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
.catch((err) => {
|
|
133
|
+
console.error(err);
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## ⚠️ 注意事项
|
|
138
|
+
|
|
139
|
+
1. **扁平结构**:直接导出 `info` 或 `infolist`,无需嵌套 `custom`/`status`
|
|
140
|
+
2. **数组导出**:`resultData` 必须是数组
|
|
141
|
+
3. **接口匹配**:`methodUrl` 用于匹配请求地址
|
|
142
|
+
4. **错误处理**:所有 mock 接口应包含错误处理
|
|
143
|
+
|
|
144
|
+
## 🔄 与真实接口切换
|
|
145
|
+
|
|
146
|
+
使用 `sdoc-mcp` 服务时,可检索真实接口替换 Mock。
|
|
147
|
+
|
|
148
|
+
## ✅ 检查清单
|
|
149
|
+
|
|
150
|
+
- [ ] mock.js 放在模块目录下
|
|
151
|
+
- [ ] resultData 为数组格式
|
|
152
|
+
- [ ] 包含 methodUrl、input、output
|
|
153
|
+
- [ ] 数据结构为扁平格式
|
|
154
|
+
- [ ] 使用 Mock.Random 生成随机数据
|