diff --git a/docs/shopping.md b/docs/shopping.md
index 36144aeebf..09300e76b3 100644
--- a/docs/shopping.md
+++ b/docs/shopping.md
@@ -147,22 +147,6 @@ pageClass: routes
-## 甩甩尾巴
-
-### 分类
-
-
-
-| 全部 | 电脑 | 手机 | 平板 | 相机 | 影音 | 外设 | 生活 | 公告 |
-| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
-| 0 | 111 | 109 | 110 | 113 | 114 | 115 | 112 | 116 |
-
-
-
-### 关键词
-
-
-
## 淘宝众筹
### 众筹项目
diff --git a/docs/social-media.md b/docs/social-media.md
index e7d7d6e9a0..67fba73cab 100644
--- a/docs/social-media.md
+++ b/docs/social-media.md
@@ -544,6 +544,54 @@ pageClass: routes
+## 数字尾巴
+
+### 首页
+
+
+
+### 闲置(分类)
+
+
+
+| 全部 | 电脑 | 手机 | 平板 | 相机 | 影音 | 外设 | 生活 | 公告 |
+| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
+| 0 | 111 | 109 | 110 | 113 | 114 | 115 | 112 | 116 |
+
+
+
+### 闲置(关键词)
+
+
+
+### 鲸图(分类)
+
+
+
+| 精选 | 人物 | 静物 | 二次元 | 黑白 | 自然 | 美食 | 电影与游戏 | 科技与艺术 | 城市与建筑 | 萌物 | 美女 |
+| ---- | ---- | ---- | ------ | ---- | ---- | ---- | ---------- | ---------- | ---------- | ---- | ---- |
+| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+
+
+
+### 鲸图(排行榜)
+
+
+
+type
+
+| 下载排行榜 | 点赞排行榜 |
+| ---------- | ---------- |
+| download | like |
+
+rule
+
+| 日排行 | 周排行 | 月排行 | 总排行 |
+| ------ | ------ | ------ | ------ |
+| day | week | month | amount |
+
+
+
## 刷屏
### 最新
diff --git a/lib/router.js b/lib/router.js
index 7b4829226c..d2d254f526 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -828,7 +828,10 @@ router.get('/solidot/:type?', require('./routes/solidot/main'));
// Hermes UK
router.get('/parcel/hermesuk/:tracking', require('./routes/parcel/hermesuk'));
-// 甩甩尾巴
+// 数字尾巴
+router.get('/dgtle', require('./routes/dgtle/index'));
+router.get('/dgtle/whale/category/:category', require('./routes/dgtle/whale'));
+router.get('/dgtle/whale/rank/:type/:rule', require('./routes/dgtle/whale_rank'));
router.get('/dgtle/trade/:typeId?', require('./routes/dgtle/trade'));
router.get('/dgtle/trade/search/:keyword', require('./routes/dgtle/keyword'));
diff --git a/lib/routes/dgtle/index.js b/lib/routes/dgtle/index.js
new file mode 100644
index 0000000000..41f7080586
--- /dev/null
+++ b/lib/routes/dgtle/index.js
@@ -0,0 +1,57 @@
+const got = require('@/utils/got');
+
+module.exports = async (ctx) => {
+ const response = await got({
+ method: 'get',
+ url: 'https://opser.api.dgtle.com/v1/app/index?page=1',
+ });
+
+ const article_items = response.data.items.filter((item) => item.type in { 1: '', 4: '' });
+
+ const items = await Promise.all(
+ article_items.map(async (item) => {
+ let title = '';
+ let olink = ''; // 原始链接
+ let dlink = ''; // description 链接
+ let category = '';
+ let description = '';
+
+ if (1 === item.type) {
+ title = item.title;
+ dlink = `https://opser.api.dgtle.com/v1/article/view/${item.aid}`;
+ olink = `https://www.dgtle.com/article-${item.aid}-1.html`;
+ category = '文章';
+ description = await ctx.cache.tryGet(dlink, async () => {
+ const resp = await got.get(dlink);
+ return resp.data.content;
+ });
+ } else if (4 === item.type) {
+ title = item.summary;
+ dlink = `https://opser.api.dgtle.com/v1/feeds/inst/${item.aid}`;
+ olink = `https://www.dgtle.com/inst-${item.aid}-1.html`;
+ category = '兴趣动态';
+ description = await ctx.cache.tryGet(dlink, async () => {
+ const resp = await got.get(dlink);
+
+ return resp.data.imgs_url.reduce((content, dimg) => (content += `
`), resp.data.content);
+ });
+ }
+
+ return Promise.resolve({
+ title: title,
+ description,
+ pubDate: new Date(item.send_at * 1000).toUTCString(),
+ link: olink,
+ category: category,
+ author: item.author.username,
+ });
+ })
+ );
+
+ ctx.state.data = {
+ title: '数字尾巴 - 首页',
+ link: 'https://www.dgtle.com',
+ description: '数字尾巴首页内容',
+ item: items,
+ };
+};
diff --git a/lib/routes/dgtle/whale.js b/lib/routes/dgtle/whale.js
new file mode 100644
index 0000000000..33d30c59e5
--- /dev/null
+++ b/lib/routes/dgtle/whale.js
@@ -0,0 +1,29 @@
+const got = require('@/utils/got');
+
+module.exports = async (ctx) => {
+ const cid = Number(ctx.params.category);
+
+ const categories = ['精选', '人物', '静物', '二次元', '黑白', '自然', '美食', '电影与游戏', '科技与艺术', '城市与建筑', '萌物', '美女'];
+
+ const host = 'https://www.dgtle.com';
+
+ const response = await got({
+ method: 'get',
+ url: `https://opser.api.dgtle.com/v1/whale/index?category_id=${cid}&page=1&per-page=10`,
+ });
+
+ const items = response.data.items.map((item) => ({
+ title: item.content,
+ pubDate: new Date(item.updated_at * 1000).toUTCString(),
+ author: item.author.username,
+ description: `
`,
+ link: item.attachment.pic_url.split('?')[0],
+ }));
+
+ ctx.state.data = {
+ title: `数字尾巴 - 鲸图 - ${categories[cid]}`,
+ description: '分类鲸图',
+ link: host,
+ item: items,
+ };
+};
diff --git a/lib/routes/dgtle/whale_rank.js b/lib/routes/dgtle/whale_rank.js
new file mode 100644
index 0000000000..e247d6ab4c
--- /dev/null
+++ b/lib/routes/dgtle/whale_rank.js
@@ -0,0 +1,40 @@
+const got = require('@/utils/got');
+
+module.exports = async (ctx) => {
+ const type = ctx.params.type;
+ const rule = ctx.params.rule;
+
+ const stype = {
+ download: '下载',
+ like: '点赞',
+ };
+
+ const srule = {
+ day: '日排行',
+ week: '周排行',
+ month: '月排行',
+ amount: '总排行',
+ };
+
+ const host = 'https://www.dgtle.com';
+
+ const response = await got({
+ method: 'get',
+ url: `https://opser.api.dgtle.com/v1/whale-rank/list?rule=${rule}&type=${type}`,
+ });
+
+ const items = response.data.items.map((item) => ({
+ title: item.content,
+ pubDate: new Date(item.updated_at * 1000).toUTCString(),
+ author: item.author.username,
+ description: `
`,
+ link: item.attachment.pic_url.split('?')[0],
+ }));
+
+ ctx.state.data = {
+ title: `数字尾巴 - 鲸图 - ${stype[type]}${srule[rule]}`,
+ description: '鲸图排行榜',
+ link: host,
+ item: items,
+ };
+};