外观
路由
路由
路由定义文件应当简洁,主要定义路由及对应的参数和权限校验规则。参考示例如下:
其中 bodyValidateMiddleware、userMiddleware、authMiddleware 都是中间件。
typescript
import express from "express";
import { cGetTodoList, sQueryTodoList } from "#controllers/todo";
import { userMiddleware } from "#middlewares/UserMiddleware";
import { authMiddleware } from "#middlewares/AuthMiddleware";
import { bodyValidateMiddleware } from "#middlewares/BodyValidateMiddleware";
const router = express.Router();
// 查询待办项列表
router.get(
"/list",
bodyValidateMiddleware({ query: sQueryTodoList }),
userMiddleware(),
authMiddleware(),
cGetTodoList,
);
// ...
export default router;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
路由的应用是在 src/app.mts 中生效的。
src/app.mts 中对路由的使用
typescript
app.use("/", sessionMiddleware, routerRoot);
// Express looks up the files in the order in which you set the static directories with the express.static middleware function.
app.use(express.static(joinPath(PATH_PUBLIC)));
registerRoutesExceptForRoot(app);1
2
3
4
5
6
2
3
4
5
6
可以看到,主要有 2 类路由:根路由和其他路由。
根路由
根路由主要是服务端 SSR 输出页面的请求,其路由是单独定义在 src/routes/root.mts 文件中的。
src/routes/root.mts
typescript
import express from "express";
import { siteDownMiddleware } from "#middlewares/SiteDownMiddleware";
import { userMiddleware } from "#middlewares/UserMiddleware";
import { bodyValidateMiddleware } from "#middlewares/BodyValidateMiddleware";
import { HEALTH_CHECK_PATH, NODE_ENV } from "#utils/ConstantUtils";
import {
cCheckHealth,
cLogout,
cPostContact,
cRedirectArticles,
cRedirectUrl,
cVisit404,
cVisitAbout,
cVisitArticleDetail,
cVisitArticles,
cVisitContact,
cVisitCopyright,
cVisitIndex,
cVisitLogin,
cVisitMaintenance,
cVisitPrivacyPolicy,
cVisitTermsCondition,
cVisitUndefinedView,
cVisitSharesPreview,
cVisitSharesView,
cVisitDomains,
cVisitSitemap,
sQueryLogin,
sRedirectUrl,
cVisitFeedback,
cVisitDonation,
} from "#controllers/root";
import { authMiddleware } from "#middlewares/AuthMiddleware";
const router = express.Router();
router.get("/", siteDownMiddleware(), userMiddleware(), cVisitIndex);
router.get(HEALTH_CHECK_PATH, cCheckHealth);
router.get("/sitemap.xml", cVisitSitemap);
router.get("/login", bodyValidateMiddleware({ query: sQueryLogin }), cVisitLogin);
router.get("/about", siteDownMiddleware(), userMiddleware(), cVisitAbout);
router.get(
"/redirect",
bodyValidateMiddleware({ query: sRedirectUrl }),
siteDownMiddleware(),
cRedirectUrl,
);
router.get("/articles", cRedirectArticles);
// 1. 文章列表页:匹配 /articles/1、/articles/10 等数字路径(页码)
// 路由参数 :pageNum 后添加 (\d+) 正则,仅匹配1个及以上数字
router.get("/articles/:pageNum(\\d+)", siteDownMiddleware(), userMiddleware(), cVisitArticles);
// 文章详情页:匹配 /articles/how-to-do-it 等字符串路径(slug)
// 由于定义在数字路由之后,不会拦截数字路径
router.get("/articles/:name", siteDownMiddleware(), userMiddleware(), cVisitArticleDetail);
router.get("/contact", cVisitContact);
router.get("/feedback", cVisitFeedback);
router.get("/donation", cVisitDonation);
router.post("/contact", siteDownMiddleware(), cPostContact);
router.get("/maintenance", userMiddleware(), cVisitMaintenance);
// 条款约定
router.get("/copyright", userMiddleware(), cVisitCopyright);
// 隐私政策
router.get("/privacy-policy", userMiddleware(), cVisitPrivacyPolicy);
// 服务协议
router.get("/terms-condition", userMiddleware(), cVisitTermsCondition);
// 码上分享 - 预览页面(仅自己可见)
router.get("/shares/preview/*", siteDownMiddleware(), userMiddleware(), cVisitSharesPreview);
// 码上分享 - 正式发布页面(公开访问)
router.get("/shares/view/*", siteDownMiddleware(), userMiddleware(), cVisitSharesView);
// 退出登录
router.get("/logout", userMiddleware(), authMiddleware(), cLogout);
router.get("/404", userMiddleware(), cVisit404);
router.get("/domains", siteDownMiddleware(), userMiddleware(), cVisitDomains);
if (NODE_ENV === "development") {
router.get("/:view", userMiddleware(), cVisitUndefinedView);
}
export default router;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
其他路由
其他路由在 src/routes/index.mts 中集中注册,按业务模块划分:
src/routes/index.mts
typescript
import { sessionMiddleware } from "#middlewares/SessionMiddleware";
import routerUsers from "#routes/users";
import routerArticles from "#routes/articles";
import routerProducts from "#routes/products";
import routerFile from "#routes/file";
import routerStatistics from "#routes/statistics";
import routerMails from "#routes/mails";
import routerMessages from "#routes/messages";
import routerChat from "#routes/chat";
import routerSms from "#routes/sms";
import routerEmail from "#routes/email";
import routerAdmin from "#routes/admin";
import routerTodo from "#routes/todo";
import routerRole from "#routes/role";
import routerWechat from "#routes/wechat";
import routerOauth from "#routes/oauth";
import routerBugsAction from "#routes/bugs/action";
import routerBugsApi from "#routes/bugs/api";
import routerBugsBug from "#routes/bugs/bug";
import routerBugsHome from "#routes/bugs/home";
import routerBugsProject from "#routes/bugs/project";
import routerBugsView from "#routes/bugs/view";
import routerBugsEvent from "#routes/bugs/event";
import routerBugsAlert from "#routes/bugs/alert";
import routerDesignProject from "#routes/design/project";
import routerPPT from "#routes/ppt";
import routerBalance from "#routes/balance";
import routerBalanceWithdrawAudit from "#routes/balanceWithdrawAudit";
import routerBalanceWithdrawAccount from "#routes/balanceWithdrawAccount";
import routerArticleCategory from "#routes/articleCategory";
import routerArticleTag from "#routes/articleTag";
import routerNavCategory from "#routes/navCategory";
import routerNavSetting from "#routes/navSetting";
import routerNavWebsite from "#routes/navWebsite";
import routerNavUserCollect from "#routes/navUserCollect";
import routerNavSearchEngine from "#routes/navSearchEngine";
import routerNavQuickLink from "#routes/navQuickLink";
import routerNavUserWebsite from "#routes/navUserWebsite";
import routerHealth from "#routes/health";
import routerAlbum from "#routes/album";
import routerShares from "#routes/shares";
import routerBookingRoom from "#routes/bookingRoom";
import routerBookingEquipment from "#routes/bookingEquipment";
import routerBooking from "#routes/booking";
import routerBookingAudit from "#routes/bookingAudit";
import routerBookingNotification from "#routes/bookingNotification";
import routerLlm from "#routes/llm";
import routerPrompt from "#routes/prompt";
import routerTunerPad from "#routes/mock/tunerPad";
import routerAiDiagnose from "#routes/mock/aiDiagnose";
import routerSSL from "#routes/ssl";
import routerPaperSummarizer from "#routes/paperSummarizer";
import routerDictation from "#routes/dictation";
import routerCrs from "#routes/crs";
import routerAiChat from "#routes/aiChat";
import routerPdfToolbox from "#routes/pdfToolbox";
import routerAiConfig from "#routes/aiConfig";
export const registerRoutesExceptForRoot = (app: ExpressApp): void => {
app.use(`/api/users`, sessionMiddleware, routerUsers);
app.use(`/api/articles`, sessionMiddleware, routerArticles);
app.use(`/api/articles`, sessionMiddleware, routerArticleCategory);
app.use(`/api/articles`, sessionMiddleware, routerArticleTag);
app.use(`/api/products`, sessionMiddleware, routerProducts);
app.use(`/api/file`, sessionMiddleware, routerFile);
app.use(`/api/statistics`, sessionMiddleware, routerStatistics);
app.use(`/api/mails`, sessionMiddleware, routerMails);
app.use(`/api/messages`, sessionMiddleware, routerMessages);
app.use(`/api/chat`, sessionMiddleware, routerChat);
app.use(`/api/sms`, sessionMiddleware, routerSms);
app.use(`/api/email`, sessionMiddleware, routerEmail);
app.use(`/api/admin`, sessionMiddleware, routerAdmin);
app.use(`/api/todo`, sessionMiddleware, routerTodo);
app.use(`/api/role`, sessionMiddleware, routerRole);
app.use(`/api/wechat`, sessionMiddleware, routerWechat);
app.use(`/api/oauth`, sessionMiddleware, routerOauth);
app.use(`/api/bugs/action`, routerBugsAction);
app.use(`/api/bugs/api`, routerBugsApi);
app.use(`/api/bugs/bug`, routerBugsBug);
app.use(`/api/bugs/home`, routerBugsHome);
app.use(`/api/bugs/project`, routerBugsProject);
app.use(`/api/bugs/view`, routerBugsView);
app.use(`/api/bugs/event`, routerBugsEvent);
app.use(`/api/bugs/alert`, routerBugsAlert);
app.use(`/api/design/project`, routerDesignProject);
app.use(`/api/ppt`, routerPPT);
app.use(`/api/balance`, routerBalance);
app.use(`/api/balance/withdraw-audit`, sessionMiddleware, routerBalanceWithdrawAudit);
app.use(`/api/balance/withdraw-account`, sessionMiddleware, routerBalanceWithdrawAccount);
app.use(`/api/nav`, sessionMiddleware, routerNavCategory);
app.use(`/api/nav`, sessionMiddleware, routerNavSetting);
app.use(`/api/nav`, sessionMiddleware, routerNavWebsite);
app.use(`/api/nav`, sessionMiddleware, routerNavUserCollect);
app.use(`/api/nav`, sessionMiddleware, routerNavSearchEngine);
app.use(`/api/nav`, sessionMiddleware, routerNavQuickLink);
app.use(`/api/nav`, sessionMiddleware, routerNavUserWebsite);
app.use(`/api/health`, sessionMiddleware, routerHealth);
app.use(`/api/album`, sessionMiddleware, routerAlbum);
app.use(`/api/shares`, sessionMiddleware, routerShares);
app.use(`/api`, sessionMiddleware, routerBookingRoom);
app.use(`/api`, sessionMiddleware, routerBookingEquipment);
app.use(`/api`, sessionMiddleware, routerBooking);
app.use(`/api`, sessionMiddleware, routerBookingAudit);
app.use(`/api`, sessionMiddleware, routerBookingNotification);
app.use(`/api/llm`, sessionMiddleware, routerLlm);
app.use(`/api/prompt`, sessionMiddleware, routerPrompt);
app.use("/api/mock/tunerpad", routerTunerPad);
app.use("/api/mock/ai-diagnose", routerAiDiagnose);
app.use("/api/ssl", sessionMiddleware, routerSSL);
app.use("/api/paper-summarizer", sessionMiddleware, routerPaperSummarizer);
app.use("/api/dictation", sessionMiddleware, routerDictation);
app.use("/api/crs", sessionMiddleware, routerCrs);
app.use("/api/ai-chat", sessionMiddleware, routerAiChat);
app.use("/api/pdf-toolbox", sessionMiddleware, routerPdfToolbox);
app.use("/api/ai-config", sessionMiddleware, routerAiConfig);
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117