diff --git a/docs/study.md b/docs/study.md
index 1edf9faf52..1116b3f794 100644
--- a/docs/study.md
+++ b/docs/study.md
@@ -73,6 +73,31 @@ pageClass: routes
+## Mind42
+
+### 分类
+
+
+
+| Overview | Popular | All |
+| -------- | ------- | ------ |
+| mindmaps | popular | public |
+
+
+
+### 标签
+
+
+
+| in | online | cleaning | buy | best | services | for | carpet | service | india | company | and | de | mapa | control | malware | online-dating-website-reviews | virus | international-online-dating-sites-review | repair |
+| -- | ------ | -------- | --- | ---- | -------- | --- | ------ | ------- | ----- | ------- | --- | -- | ---- | ------- | ------- | ----------------------------- | ----- | ---------------------------------------- | ------ |
+
+
+
+### 搜索
+
+
+
## NEEA 中国教育考试网
### 国家教育考试
diff --git a/lib/router.js b/lib/router.js
index 11c6bbec2a..dd18399fd7 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -3512,6 +3512,11 @@ router.get('/uisdc/news', require('./routes/uisdc/news'));
router.get('/uisdc/zt/:title?', require('./routes/uisdc/zt'));
router.get('/uisdc/topic/:title?/:sort?', require('./routes/uisdc/topic'));
+// Mind42
+router.get('/mind42/tag/:id', require('./routes/mind42/tag'));
+router.get('/mind42/search/:keyword', require('./routes/mind42/search'));
+router.get('/mind42/:caty?', require('./routes/mind42/index'));
+
// 幕布网
router.get('/mubu/explore/:tagId/:title?', require('./routes/mubu/explore'));
diff --git a/lib/routes/mind42/index.js b/lib/routes/mind42/index.js
new file mode 100644
index 0000000000..fa2abe0d14
--- /dev/null
+++ b/lib/routes/mind42/index.js
@@ -0,0 +1,7 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ const currentUrl = ctx.params.caty || 'mindmaps';
+
+ ctx.state.data = await utils(ctx, currentUrl);
+};
diff --git a/lib/routes/mind42/search.js b/lib/routes/mind42/search.js
new file mode 100644
index 0000000000..8cf7f4748e
--- /dev/null
+++ b/lib/routes/mind42/search.js
@@ -0,0 +1,5 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.state.data = await utils(ctx, `search?q=${ctx.params.keyword}`);
+};
diff --git a/lib/routes/mind42/tag.js b/lib/routes/mind42/tag.js
new file mode 100644
index 0000000000..685a9816dd
--- /dev/null
+++ b/lib/routes/mind42/tag.js
@@ -0,0 +1,5 @@
+const utils = require('./utils');
+
+module.exports = async (ctx) => {
+ ctx.state.data = await utils(ctx, `tag/${ctx.params.id}`);
+};
diff --git a/lib/routes/mind42/utils.js b/lib/routes/mind42/utils.js
new file mode 100644
index 0000000000..5ac7e88c7a
--- /dev/null
+++ b/lib/routes/mind42/utils.js
@@ -0,0 +1,48 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+
+module.exports = async (ctx, currentUrl) => {
+ const rootUrl = `https://mind42.com`;
+ currentUrl = `${rootUrl}/${currentUrl}`;
+
+ const response = await got({
+ method: 'get',
+ url: currentUrl,
+ });
+ const $ = cheerio.load(response.data);
+
+ const list = $('.title a.title')
+ .slice(0, 10)
+ .map((_, item) => {
+ item = $(item);
+ return {
+ link: `${rootUrl}${item.attr('href')}`,
+ };
+ })
+ .get();
+
+ const items = await Promise.all(
+ list.map(
+ async (item) =>
+ await ctx.cache.tryGet(item.link, async () => {
+ const detailResponse = await got({
+ method: 'get',
+ url: item.link,
+ });
+ const content = cheerio.load(detailResponse.data);
+
+ item.title = content('h1 a[name="info"]').text();
+ item.author = content('.creator').text().trim().replace('by', '');
+ item.description = `[1]}&size=gallery)
${content('.description').text()}
`;
+
+ return item;
+ })
+ )
+ );
+
+ return {
+ title: $('title').text().split(' - ')[0],
+ link: currentUrl,
+ item: items,
+ };
+};