From 7159ada75d9cfc0374920d4772c87e5ea0223943 Mon Sep 17 00:00:00 2001 From: journey-ad Date: Sun, 17 Dec 2023 23:25:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=B0=8F=E8=AF=B4?= =?UTF-8?q?=E9=98=85=E8=AF=BB=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/api/index.js | 172 +++- src/assets/css/base.styl | 5 +- src/components/Nav.vue | 79 +- src/components/NovelCard.vue | 228 ++++++ src/components/TopBar.vue | 33 +- src/layouts/MainLayout.vue | 2 +- src/router/index.js | 6 + src/store/index.js | 8 +- src/svg/close.svg | 11 +- src/svg/novel.svg | 1 + src/views/Artwork/index.vue | 1 + src/views/Novel/chapter.vue | 743 ++++++++++++++++++ src/views/Novel/index.vue | 35 + src/views/Search/index.vue | 174 +++- src/views/Users/components/AuthorIllusts.vue | 10 +- src/views/Users/components/AuthorNovels.vue | 185 +++++ .../Users/components/FavoriteIllusts.vue | 114 ++- src/views/Users/index.vue | 36 +- 19 files changed, 1701 insertions(+), 143 deletions(-) create mode 100644 src/components/NovelCard.vue create mode 100644 src/svg/novel.svg create mode 100644 src/views/Novel/chapter.vue create mode 100644 src/views/Novel/index.vue create mode 100644 src/views/Users/components/AuthorNovels.vue diff --git a/README.md b/README.md index af98ac31..d1604578 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ - [x] 作品页面 - [x] 作者信息页面 - [x] 设置页面 + - [x] 小说阅读 - [x] 搜索功能 - [x] 以图搜图 - [x] 动图播放 diff --git a/src/api/index.js b/src/api/index.js index ba4b59df..ee26c056 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -100,6 +100,28 @@ const parseIllust = data => { return artwork } +const parseNovel = data => { + const result = { + ...data, + images: { + s: imgProxy(data.image_urls.square_medium), + m: imgProxy(data.image_urls.medium), + l: imgProxy(data.image_urls.large), + }, + author: { + id: data.user.id, + name: data.user.name, + avatar: imgProxy(data.user.profile_image_urls.medium) + }, + count: data.page_count, + view: data.total_view, + like: data.total_bookmarks, + } + result.user.profile_image_urls.medium = imgProxy(data.user.profile_image_urls.medium) + + return result +} + const api = { /** * @@ -265,21 +287,28 @@ const api = { * @param {String} word 关键词 * @param {Number} page 页数 */ - async search(word, page = 1) { - const cache_key = `searchList_${Base64.encode(word)}_${page}` + async search(word, page = 1, type = 'illust') { + const cache_key = `searchList_${type}_${Base64.encode(word)}_${page}` let searchList = await DBStorage.get(cache_key) if (!searchList) { let res = await get('/pixiv/', { - type: 'search', + type: type === 'novel' ? 'search_novel' : 'search', word, page }) - let data - if (res.illusts) { - data = res.illusts + if (res.illusts || res.novels) { + if (type === 'illust') { + if (res.illusts) { + searchList = res.illusts.map(parseIllust) + } + } else if (type === 'novel') { + if (res.novels) { + searchList = res.novels.map(parseNovel) + } + } } else if (res.error) { return { status: -1, @@ -292,10 +321,6 @@ const api = { } } - searchList = data.map(art => { - return parseIllust(art) - }) - DBStorage.set(cache_key, searchList, Expires.hour(3)) } @@ -538,6 +563,131 @@ const api = { } return { status: 0, data: tags } - } + }, + + /** + * 获取用户小说投稿 + * @param {Number} id 作者ID + * @param {Number} page 页数 + */ + async getMemberNovel(id, page = 1) { + const cache_key = `memberNovel_${id}_p${page}` + let memberNovel = await DBStorage.get(cache_key) + + if (!memberNovel) { + + let res = await get('/pixiv/', { + type: 'member_novel', + id, + page + }) + + let data + if (res.novels.length) { + data = res.novels + } else if (res.error) { + return { + status: -1, + msg: res.error.user_message || res.error.message + } + } else if (!res.next_url) { + return { + status: 0, + data: [], + finished: true + } + } else { + return { + status: -1, + msg: '未知错误' + } + } + + memberNovel = data.map(art => { + return parseNovel(art) + }) + + DBStorage.set(cache_key, memberNovel, Expires.hour(3)) + } + + return { status: 0, data: memberNovel } + }, + + /** + * 获取小说详情 + * @param {Number} id 小说ID + * @returns {Object} + */ + async getNovel(id) { + const cache_key = `novel_${id}` + let novel = await DBStorage.get(cache_key) + + if (!novel) { + + const reqArr = [ + get('/pixiv/', { type: 'novel_detail', id }), + get('/pixiv/', { type: 'novel_text', id }) + ] + + const [detail, text] = await Promise.all(reqArr) + + let data + if (detail.novel) { + data = { + ...detail.novel, + content: text.novel_text + } + } else if (detail.error) { + return { + status: -1, + msg: detail.error.user_message || detail.error.message + } + } else { + return { + status: -1, + msg: '未知错误' + } + } + + novel = parseNovel(data) + + DBStorage.set(cache_key, novel, Expires.MONTH) + } + + + return { status: 0, data: novel } + }, + + async getNovelText(id) { + const cache_key = `novel_text_${id}` + let novel = await DBStorage.get(cache_key) + + if (!novel) { + + let res = await get('/pixiv/', { + type: 'novel_text', + id + }) + + if (res.illust) { + novel = res.illust + } else if (res.error) { + return { + status: -1, + msg: res.error.user_message || res.error.message + } + } else { + return { + status: -1, + msg: '未知错误' + } + } + + DBStorage.set(cache_key, novel, Expires.MONTH) + } + + + return { status: 0, data: novel } + }, } export default api diff --git a/src/assets/css/base.styl b/src/assets/css/base.styl index 8ff81845..652daf61 100644 --- a/src/assets/css/base.styl +++ b/src/assets/css/base.styl @@ -20,7 +20,10 @@ html { overflow-y: scroll; box-sizing: border-box; overscroll-behavior: none; - scroll-behavior: smooth; + + &.no-scroll { + overflow: hidden; + } } @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;700&display=swap'); diff --git a/src/components/Nav.vue b/src/components/Nav.vue index 5b4cc061..ede5cab7 100644 --- a/src/components/Nav.vue +++ b/src/components/Nav.vue @@ -1,41 +1,20 @@