├── .github
└── ISSUE_TEMPLATE
│ ├── ✨-新功能建议.md
│ ├── 系统问题解答.md
│ └── 🐞-bug反馈.md
├── .gitignore
├── LICENSE
├── README.md
├── blog.sql
├── client
├── env
│ ├── .env
│ ├── .env.development
│ └── index.js
├── next-env.d.ts
├── next.config.ts
├── package.json
├── postcss.config.js
├── prettier.config.js
├── public
│ ├── favicon.ico
│ ├── favicon.svg
│ ├── icon
│ │ ├── admin
│ │ │ ├── QQ.svg
│ │ │ ├── fork.svg
│ │ │ ├── github.svg
│ │ │ ├── homepage.svg
│ │ │ ├── issues.svg
│ │ │ ├── star.svg
│ │ │ ├── watch.svg
│ │ │ ├── 数据看板.svg
│ │ │ └── 邮箱.svg
│ │ └── client
│ │ │ ├── briefcase.png
│ │ │ ├── collection-blue.png
│ │ │ ├── collection-fill.png
│ │ │ ├── collection.png
│ │ │ ├── comment.png
│ │ │ ├── comments.png
│ │ │ ├── delete-fill.png
│ │ │ ├── delete.png
│ │ │ ├── drafts.svg
│ │ │ ├── email-fill.png
│ │ │ ├── email.png
│ │ │ ├── emoji.png
│ │ │ ├── github-fill.png
│ │ │ ├── github.png
│ │ │ ├── likes-fill.png
│ │ │ ├── likes.png
│ │ │ ├── picture.png
│ │ │ ├── police.png
│ │ │ ├── postcard.png
│ │ │ ├── problem-collection-black.png
│ │ │ ├── problem-collection-white.png
│ │ │ ├── problem-follow-black.png
│ │ │ ├── problem-follow-white.png
│ │ │ ├── problem-like-black.png
│ │ │ ├── problem-like-white.png
│ │ │ ├── problem.svg
│ │ │ ├── qq.png
│ │ │ ├── share.png
│ │ │ ├── small-bell.png
│ │ │ ├── unit.png
│ │ │ ├── view-blue.png
│ │ │ ├── view-white.png
│ │ │ ├── view.png
│ │ │ ├── website.png
│ │ │ ├── wechat.png
│ │ │ └── write-article.svg
│ ├── image
│ │ ├── admin
│ │ │ ├── bg.svg
│ │ │ └── statistics
│ │ │ │ ├── bg.jpg
│ │ │ │ ├── border_bg.jpg
│ │ │ │ ├── title_left_bg.png
│ │ │ │ └── title_right_bg.png
│ │ └── client
│ │ │ ├── collection-bg.jpg
│ │ │ ├── github.jpg
│ │ │ ├── load-error.png
│ │ │ ├── qq-qrcode.jpg
│ │ │ └── wechat-qrcode.jpg
│ ├── robots-template.txt
│ └── vditor
│ │ ├── ant.js
│ │ ├── github.min.css
│ │ ├── highlight.min.js
│ │ ├── light.css
│ │ ├── lute.min.js
│ │ ├── third-languages.js
│ │ └── zh_CN.js
├── scripts
│ └── build-output
│ │ ├── index.js
│ │ └── nodemon.json
├── src
│ ├── app
│ │ ├── (main)
│ │ │ └── page.tsx
│ │ ├── (route)
│ │ │ ├── ads.txt
│ │ │ │ └── route.ts
│ │ │ ├── sitemap
│ │ │ │ └── [type]
│ │ │ │ │ ├── index.xml
│ │ │ │ │ └── route.tsx
│ │ │ │ │ └── index[index].xml
│ │ │ │ │ └── route.tsx
│ │ │ └── static
│ │ │ │ ├── antd
│ │ │ │ └── [name]
│ │ │ │ │ └── route.tsx
│ │ │ │ ├── editor
│ │ │ │ └── [...path]
│ │ │ │ │ └── route.tsx
│ │ │ │ ├── high-light
│ │ │ │ └── [type]
│ │ │ │ │ └── route.tsx
│ │ │ │ └── theme
│ │ │ │ └── [id]
│ │ │ │ └── route.tsx
│ │ ├── admin
│ │ │ ├── [...all]
│ │ │ │ └── page.tsx
│ │ │ ├── advertisement
│ │ │ │ ├── [id]
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── list
│ │ │ │ │ └── page.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── article
│ │ │ │ ├── [id]
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── list
│ │ │ │ │ └── page.tsx
│ │ │ │ └── write
│ │ │ │ │ └── page.tsx
│ │ │ ├── comment
│ │ │ │ └── page.tsx
│ │ │ ├── external-link
│ │ │ │ └── page.tsx
│ │ │ ├── friendly-link
│ │ │ │ ├── create
│ │ │ │ │ └── page.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── login
│ │ │ │ └── page.tsx
│ │ │ ├── oss
│ │ │ │ └── page.tsx
│ │ │ ├── page.tsx
│ │ │ ├── statistics
│ │ │ │ └── page.tsx
│ │ │ ├── theme
│ │ │ │ ├── create
│ │ │ │ │ └── page.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── type
│ │ │ │ ├── page.tsx
│ │ │ │ ├── tag
│ │ │ │ │ └── [id]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ └── type
│ │ │ │ │ └── [id]
│ │ │ │ │ └── page.tsx
│ │ │ └── user
│ │ │ │ ├── [id]
│ │ │ │ └── page.tsx
│ │ │ │ └── page.tsx
│ │ ├── article
│ │ │ ├── [id]
│ │ │ │ ├── (main)
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── not-found.tsx
│ │ │ └── editor
│ │ │ │ ├── [id]
│ │ │ │ └── page.tsx
│ │ │ │ └── page.tsx
│ │ ├── collection
│ │ │ └── [id]
│ │ │ │ ├── not-found.tsx
│ │ │ │ └── page.tsx
│ │ ├── creator
│ │ │ ├── content
│ │ │ │ ├── article
│ │ │ │ │ └── page.tsx
│ │ │ │ └── problem
│ │ │ │ │ └── page.tsx
│ │ │ └── page.tsx
│ │ ├── error.tsx
│ │ ├── forget-password
│ │ │ └── page.tsx
│ │ ├── friendly-link
│ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ ├── link
│ │ │ └── page.tsx
│ │ ├── not-found.tsx
│ │ ├── notification
│ │ │ ├── [type]
│ │ │ │ └── page.tsx
│ │ │ └── page.tsx
│ │ ├── oauth
│ │ │ └── github
│ │ │ │ └── page.tsx
│ │ ├── problem
│ │ │ ├── (main)
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── [id]
│ │ │ │ ├── (main)
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── not-found.tsx
│ │ │ └── editor
│ │ │ │ ├── [id]
│ │ │ │ └── page.tsx
│ │ │ │ └── page.tsx
│ │ ├── result
│ │ │ └── page.tsx
│ │ ├── robots.ts
│ │ ├── search
│ │ │ └── page.tsx
│ │ ├── sitemap
│ │ │ └── [type]
│ │ │ │ └── page.tsx
│ │ ├── tag
│ │ │ └── article
│ │ │ │ └── [id]
│ │ │ │ └── page.tsx
│ │ ├── theme
│ │ │ └── page.tsx
│ │ └── user
│ │ │ ├── [id]
│ │ │ └── page.tsx
│ │ │ └── settings
│ │ │ ├── account
│ │ │ └── page.tsx
│ │ │ ├── destroy
│ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ └── profile
│ │ │ └── page.tsx
│ ├── common
│ │ ├── hooks
│ │ │ ├── useComputed.ts
│ │ │ ├── useFetch.tsx
│ │ │ ├── useGetRawPath.tsx
│ │ │ └── useWatchEffect.tsx
│ │ ├── modules
│ │ │ ├── cookie
│ │ │ │ └── index.ts
│ │ │ ├── readingRecords
│ │ │ │ ├── index.ts
│ │ │ │ ├── redis.ts
│ │ │ │ ├── setReferer.ts
│ │ │ │ └── setSpider.ts
│ │ │ └── sitemap
│ │ │ │ ├── sitemap-index.ts
│ │ │ │ └── sitemap.ts
│ │ └── utils
│ │ │ ├── HtmlToMarkDown.ts
│ │ │ └── vw.ts
│ ├── components
│ │ ├── admin
│ │ │ ├── common
│ │ │ │ ├── Footer
│ │ │ │ │ └── index.tsx
│ │ │ │ └── Header
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── items.tsx
│ │ │ └── page
│ │ │ │ ├── advertisement
│ │ │ │ └── AdvertisementForm.tsx
│ │ │ │ ├── article
│ │ │ │ └── list
│ │ │ │ │ ├── Header.tsx
│ │ │ │ │ └── Table.tsx
│ │ │ │ ├── index
│ │ │ │ └── notice.tsx
│ │ │ │ ├── statistics
│ │ │ │ ├── Bottom
│ │ │ │ │ ├── Occupation.tsx
│ │ │ │ │ ├── Referer.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Container
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Statistics.tsx
│ │ │ │ └── Top
│ │ │ │ │ ├── Article.tsx
│ │ │ │ │ ├── ArticleRanking.tsx
│ │ │ │ │ ├── Header
│ │ │ │ │ ├── HeaderItem.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── Visits.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── theme
│ │ │ │ └── CodeEdite.tsx
│ │ │ │ └── type
│ │ │ │ ├── AddTagModal.tsx
│ │ │ │ ├── AddTypeModal.tsx
│ │ │ │ ├── TagForm.tsx
│ │ │ │ └── TypeForm.tsx
│ │ ├── common
│ │ │ ├── AdSense
│ │ │ │ ├── ADS.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Advertisement
│ │ │ │ └── index.tsx
│ │ │ ├── ArticleEditor
│ │ │ │ ├── DraftsButton.tsx
│ │ │ │ ├── Modal
│ │ │ │ │ ├── Cover.tsx
│ │ │ │ │ ├── Reprint.tsx
│ │ │ │ │ ├── Type.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── ArticleList
│ │ │ │ ├── ArticleItem.tsx
│ │ │ │ ├── Cover.tsx
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Avatar
│ │ │ │ ├── Menu.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── BackTop
│ │ │ │ └── index.tsx
│ │ │ ├── CollectionModal
│ │ │ │ ├── CreateFrom.tsx
│ │ │ │ ├── List.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── CreateTheme
│ │ │ │ └── index.tsx
│ │ │ ├── Editor
│ │ │ │ ├── LanguageListPlugin.tsx
│ │ │ │ ├── Skeleton.tsx
│ │ │ │ ├── StyleLink.tsx
│ │ │ │ ├── VditorEditor.tsx
│ │ │ │ ├── index.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── upload.ts
│ │ │ ├── Header
│ │ │ │ ├── Navigation.tsx
│ │ │ │ ├── News.tsx
│ │ │ │ ├── Search.tsx
│ │ │ │ ├── Sign
│ │ │ │ │ ├── ForgetPassword
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── LogIn
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── LogOn
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── User
│ │ │ │ │ ├── NotLogin
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── UserData
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── UpLoad
│ │ │ │ ├── Image.tsx
│ │ │ │ ├── Modal.tsx
│ │ │ │ ├── getCroppedImg.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── upload.ts
│ │ │ └── _Editor
│ │ │ │ ├── Editor.tsx
│ │ │ │ ├── MarkDownEditor
│ │ │ │ ├── LanguageListPlugin.tsx
│ │ │ │ ├── ThemeSelect.tsx
│ │ │ │ ├── UseRichTextPlugin.tsx
│ │ │ │ └── index.tsx
│ │ │ │ ├── RichTextEditor
│ │ │ │ ├── CodeEditor.tsx
│ │ │ │ └── index.tsx
│ │ │ │ ├── StyleLink.tsx
│ │ │ │ ├── index.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── upload.ts
│ │ ├── next
│ │ │ ├── ActiveLink.tsx
│ │ │ ├── Head.tsx
│ │ │ ├── Image.tsx
│ │ │ └── NoFollowLink.tsx
│ │ └── page
│ │ │ ├── article
│ │ │ ├── Aside
│ │ │ │ ├── Catalogue
│ │ │ │ │ ├── Catalogue.tsx
│ │ │ │ │ ├── index.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Repository
│ │ │ │ │ └── index.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Comments
│ │ │ │ ├── Comment
│ │ │ │ │ ├── Item.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Editor.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── ImagePreview
│ │ │ │ ├── index.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Layout.tsx
│ │ │ ├── NoFound.tsx
│ │ │ ├── Recommend.tsx
│ │ │ ├── Reprint.tsx
│ │ │ ├── Store.tsx
│ │ │ ├── ToolBar
│ │ │ │ ├── Collection
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Comment.tsx
│ │ │ │ ├── Like.tsx
│ │ │ │ ├── Share.tsx
│ │ │ │ ├── class.ts
│ │ │ │ └── index.tsx
│ │ │ ├── UserData
│ │ │ │ ├── FollowButton.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── View
│ │ │ │ └── index.tsx
│ │ │ └── editor
│ │ │ │ └── ArticleRemoveWarn.tsx
│ │ │ ├── collection
│ │ │ ├── Brow.tsx
│ │ │ ├── Collection.tsx
│ │ │ ├── FavoritesModal.tsx
│ │ │ └── ToolsBar.tsx
│ │ │ ├── creator
│ │ │ ├── ArticleList
│ │ │ │ ├── ArticleListItem.tsx
│ │ │ │ └── index.tsx
│ │ │ └── Layout
│ │ │ │ ├── Aside.tsx
│ │ │ │ ├── Header.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── friendly-link
│ │ │ └── FriendlyLink.tsx
│ │ │ ├── index
│ │ │ ├── Footer.tsx
│ │ │ ├── Layout.tsx
│ │ │ ├── Ranking
│ │ │ │ ├── AuthorRanking.tsx
│ │ │ │ ├── FunsRanking.tsx
│ │ │ │ ├── RankingList.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── SortSelect
│ │ │ │ └── index.tsx
│ │ │ ├── TypeHeader
│ │ │ │ └── index.tsx
│ │ │ ├── index.module.scss
│ │ │ └── index.tsx
│ │ │ ├── notification
│ │ │ ├── Layout.tsx
│ │ │ └── Notice
│ │ │ │ ├── Answer.tsx
│ │ │ │ ├── Comment.tsx
│ │ │ │ ├── Follow.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── problem
│ │ │ ├── Answer
│ │ │ │ └── index.tsx
│ │ │ ├── Aside.tsx
│ │ │ ├── Comments
│ │ │ │ ├── Editor.tsx
│ │ │ │ ├── Item.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Editor
│ │ │ │ ├── Message.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── Layout.tsx
│ │ │ ├── List
│ │ │ │ ├── Item.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── NoFound.tsx
│ │ │ ├── ProblemDetail.tsx
│ │ │ ├── ProblemList.tsx
│ │ │ ├── ToolBar
│ │ │ │ └── index.tsx
│ │ │ └── write
│ │ │ │ └── Tag.tsx
│ │ │ ├── tag
│ │ │ ├── Layout.tsx
│ │ │ └── List.tsx
│ │ │ └── user
│ │ │ ├── index
│ │ │ ├── NotFind.tsx
│ │ │ └── UserData
│ │ │ │ ├── Aside
│ │ │ │ └── index.tsx
│ │ │ │ ├── Header
│ │ │ │ ├── FollowButton.tsx
│ │ │ │ └── index.tsx
│ │ │ │ ├── Main
│ │ │ │ ├── Favorites
│ │ │ │ │ ├── Modal.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── FollowList
│ │ │ │ │ ├── FollowButton.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── index.tsx
│ │ │ │ └── index.tsx
│ │ │ └── setting
│ │ │ ├── UpdateEmailModal.tsx
│ │ │ ├── UpdatePasswordModal.tsx
│ │ │ └── UploadAvatar
│ │ │ └── index.tsx
│ ├── layout
│ │ ├── Admin
│ │ │ └── Base.tsx
│ │ ├── Base
│ │ │ └── index.tsx
│ │ ├── Content
│ │ │ ├── HightLight
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ └── index.tsx
│ │ ├── Main
│ │ │ └── index.tsx
│ │ └── Sidebar
│ │ │ └── index.tsx
│ ├── middleware.ts
│ ├── plugin
│ │ ├── antd.tsx
│ │ ├── axios.ts
│ │ └── dayjs.ts
│ ├── request
│ │ ├── advertisement.ts
│ │ ├── article
│ │ │ └── article-list.ts
│ │ ├── collection
│ │ │ ├── collection.ts
│ │ │ ├── index.ts
│ │ │ └── uncollection.ts
│ │ ├── follow
│ │ │ ├── follow.ts
│ │ │ ├── index.ts
│ │ │ └── unfollow.ts
│ │ ├── like
│ │ │ ├── index.ts
│ │ │ ├── like.ts
│ │ │ └── unlike.ts
│ │ ├── load-static.ts
│ │ └── type
│ │ │ ├── getTag.ts
│ │ │ ├── getTagArticleLData.ts
│ │ │ └── type-tree-index.ts
│ ├── store
│ │ ├── admin
│ │ │ ├── admin-article-list
│ │ │ │ └── index.ts
│ │ │ ├── admin-search-option
│ │ │ │ └── index.ts
│ │ │ ├── admin-statistics-data
│ │ │ │ ├── index.tsx
│ │ │ │ └── store.ts
│ │ │ └── admin-table-option
│ │ │ │ └── index.ts
│ │ ├── common
│ │ │ └── editor-mode
│ │ │ │ └── index.ts
│ │ └── user
│ │ │ ├── user-article-comment
│ │ │ └── index.ts
│ │ │ ├── user-current-article-data
│ │ │ └── index.ts
│ │ │ ├── user-data
│ │ │ ├── index.tsx
│ │ │ └── store.ts
│ │ │ ├── user-sign-model-state
│ │ │ └── index.ts
│ │ │ └── user-write-article
│ │ │ └── index.ts
│ └── styles
│ │ ├── content.module.scss
│ │ ├── genAntdCss.tsx
│ │ ├── globals.scss
│ │ └── reset.css
├── tailwind.config.js
├── tsconfig.json
├── types
│ ├── common
│ │ ├── response.ts
│ │ └── user-data.ts
│ ├── folder.ts
│ ├── index.d.ts
│ ├── model-attribute.ts
│ ├── model
│ │ ├── advertisement.ts
│ │ ├── article-comment.ts
│ │ ├── article-list-item.ts
│ │ ├── favorites-collection-list.ts
│ │ └── problem.ts
│ ├── response.ts
│ ├── statistics-type.ts
│ └── type.ts
└── yarn.lock
├── dev.bat
├── intall.bat
├── lint.bat
└── server
├── ecosystem.config.js
├── env
└── .env.template
├── package.json
├── prettier.config.js
├── public
├── prism.zip
└── robots.txt
├── scripts
├── build.ts
├── dev
│ └── index.ts
├── modules
│ ├── compile.ts
│ ├── copyDir.ts
│ ├── countFile.ts
│ └── deleteDir.ts
└── start.ts
├── src
├── app.ts
├── common
│ ├── middleware
│ │ ├── auth
│ │ │ ├── getUserId.ts
│ │ │ └── index.ts
│ │ ├── cache
│ │ │ └── index.ts
│ │ └── verify
│ │ │ ├── validator.ts
│ │ │ └── validatorAsync.ts
│ ├── modules
│ │ ├── article
│ │ │ ├── get
│ │ │ │ ├── external-link.ts
│ │ │ │ ├── html-to-markdown.ts
│ │ │ │ ├── img-add-prefix.ts
│ │ │ │ ├── set-code-block-language.ts
│ │ │ │ ├── set-description.ts
│ │ │ │ ├── set-tag-data.ts
│ │ │ │ └── set-title-id.ts
│ │ │ └── select
│ │ │ │ ├── getBloggerList.ts
│ │ │ │ ├── getTypeChildrenTag.ts
│ │ │ │ ├── option.ts
│ │ │ │ └── search.ts
│ │ ├── cache
│ │ │ ├── advertisement
│ │ │ │ └── index.ts
│ │ │ ├── email
│ │ │ │ └── index.ts
│ │ │ ├── external-link
│ │ │ │ └── index.ts
│ │ │ └── type
│ │ │ │ └── index.ts
│ │ ├── comment
│ │ │ └── get-comment-childrnen-list.ts
│ │ ├── getAllRouter.ts
│ │ ├── getFilePath.ts
│ │ ├── github
│ │ │ ├── getGithubName.ts
│ │ │ └── updata.ts
│ │ ├── notice
│ │ │ ├── answer.ts
│ │ │ ├── comment
│ │ │ │ ├── comment-answer.ts
│ │ │ │ ├── comment-article.ts
│ │ │ │ └── comment-problem.ts
│ │ │ ├── follow
│ │ │ │ ├── follow-article.ts
│ │ │ │ └── follow-problem.ts
│ │ │ └── index.ts
│ │ ├── tasks
│ │ │ ├── set-recommend-data.ts
│ │ │ └── sortArticleList.ts
│ │ └── user
│ │ │ ├── destroy.ts
│ │ │ └── isEmailDestroy.ts
│ ├── tasks
│ │ ├── advertisement.ts
│ │ ├── auto-delete-recommend.ts
│ │ ├── friendly-link-response-time.ts
│ │ ├── index.ts
│ │ ├── oss
│ │ │ └── delete-redis-cache.ts
│ │ ├── ranking
│ │ │ └── index.ts
│ │ ├── recommend
│ │ │ ├── cache-recommend-data.ts
│ │ │ └── index.ts
│ │ ├── set-article-view-count.ts
│ │ └── visualization
│ │ │ ├── github.ts
│ │ │ ├── history.ts
│ │ │ └── load.ts
│ ├── transaction
│ │ ├── answer
│ │ │ ├── create.ts
│ │ │ └── delete.ts
│ │ ├── article
│ │ │ ├── create-article.ts
│ │ │ └── delete-article.ts
│ │ ├── comment
│ │ │ ├── create-comment.ts
│ │ │ └── delete-comment.ts
│ │ ├── follow
│ │ │ └── unfollow
│ │ │ │ ├── index.ts
│ │ │ │ ├── problem.ts
│ │ │ │ └── user.ts
│ │ └── problem
│ │ │ ├── adopt.ts
│ │ │ ├── cancel.ts
│ │ │ └── delete.ts
│ ├── utils
│ │ ├── auth
│ │ │ ├── destroy-session.ts
│ │ │ ├── sign-jwt.ts
│ │ │ ├── sign-session.ts
│ │ │ ├── sign.ts
│ │ │ ├── verify-jwt.ts
│ │ │ ├── verify-session.ts
│ │ │ └── verify.ts
│ │ ├── email
│ │ │ └── index.ts
│ │ ├── id.ts
│ │ ├── map.ts
│ │ ├── random.ts
│ │ ├── redis.ts
│ │ ├── sha256.ts
│ │ ├── sleep.ts
│ │ ├── static
│ │ │ ├── ali
│ │ │ │ ├── deleteFile.ts
│ │ │ │ ├── exist.ts
│ │ │ │ ├── imageInfo.ts
│ │ │ │ ├── listPrefix.ts
│ │ │ │ ├── refreshUrls.ts
│ │ │ │ ├── upload.ts
│ │ │ │ └── utils
│ │ │ │ │ └── oss.ts
│ │ │ ├── folderList.ts
│ │ │ ├── index.ts
│ │ │ └── qiniu
│ │ │ │ ├── deleteFile.ts
│ │ │ │ ├── exist.ts
│ │ │ │ ├── imageInfo.ts
│ │ │ │ ├── listPrefix.ts
│ │ │ │ ├── refreshUrls.ts
│ │ │ │ ├── upload.ts
│ │ │ │ └── utils
│ │ │ │ ├── Mac.ts
│ │ │ │ ├── bucketManager.ts
│ │ │ │ └── zone.ts
│ │ └── xss
│ │ │ ├── article.ts
│ │ │ └── comment.ts
│ └── verify
│ │ ├── api-verify
│ │ ├── advertisement
│ │ │ └── create-update.ts
│ │ ├── answer
│ │ │ ├── create.ts
│ │ │ ├── delete.ts
│ │ │ ├── problem-md.ts
│ │ │ └── update.ts
│ │ ├── article
│ │ │ ├── common.module.ts
│ │ │ ├── create-article.ts
│ │ │ ├── list.ts
│ │ │ ├── search.ts
│ │ │ └── update-article.ts
│ │ ├── collection
│ │ │ ├── create.ts
│ │ │ └── update.ts
│ │ ├── comment
│ │ │ └── create.ts
│ │ ├── external-link
│ │ │ └── create.ts
│ │ ├── favorites
│ │ │ └── create.ts
│ │ ├── follow
│ │ │ └── create
│ │ │ │ ├── index.ts
│ │ │ │ └── map.ts
│ │ ├── friendly-link
│ │ │ └── create.ts
│ │ ├── like
│ │ │ └── create.ts
│ │ ├── problem
│ │ │ ├── adopt.ts
│ │ │ ├── cancel.ts
│ │ │ ├── create.ts
│ │ │ ├── list.ts
│ │ │ ├── questions.ts
│ │ │ └── update.ts
│ │ ├── theme
│ │ │ ├── create.ts
│ │ │ ├── remove.ts
│ │ │ └── update.ts
│ │ └── user
│ │ │ └── update.ts
│ │ ├── integer.ts
│ │ └── modules
│ │ ├── file-name.ts
│ │ ├── tag.ts
│ │ ├── type.ts
│ │ └── url.ts
├── db
│ ├── config
│ │ └── index.ts
│ ├── hooks
│ │ ├── advertisement.ts
│ │ ├── external-link.ts
│ │ ├── type.ts
│ │ └── utils
│ │ │ └── init.ts
│ ├── index.ts
│ ├── models
│ │ ├── advertisement.ts
│ │ ├── answer.ts
│ │ ├── article.ts
│ │ ├── article_tag.ts
│ │ ├── collection.ts
│ │ ├── comment.ts
│ │ ├── external_link.ts
│ │ ├── favorites.ts
│ │ ├── follow.ts
│ │ ├── friendly_link.ts
│ │ ├── init-models.ts
│ │ ├── likes.ts
│ │ ├── notice.ts
│ │ ├── problem.ts
│ │ ├── recommend.ts
│ │ ├── tag.ts
│ │ ├── theme.ts
│ │ └── user.ts
│ └── utils
│ │ └── stringArrayReplace.ts
├── index.ts
├── routes
│ ├── advertisement
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── get-all.ts
│ │ ├── id.ts
│ │ └── update.ts
│ ├── answer
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── problem-md.ts
│ │ └── update.ts
│ ├── article
│ │ ├── create.ts
│ │ ├── delete-article.ts
│ │ ├── get-data
│ │ │ ├── article-list-search.ts
│ │ │ ├── article-list-tag.ts
│ │ │ ├── article-list.ts
│ │ │ ├── get-id.ts
│ │ │ └── get-list-page.ts
│ │ ├── recommend.ts
│ │ └── update.ts
│ ├── auth
│ │ └── github.ts
│ ├── collection
│ │ ├── collection-state.ts
│ │ ├── collection-user-list.ts
│ │ ├── create.ts
│ │ ├── delete-favorites.ts
│ │ ├── delete.ts
│ │ ├── favorites-list.ts
│ │ └── update.ts
│ ├── comment
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── list-article.ts
│ │ ├── list.ts
│ │ └── review.ts
│ ├── external-link
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── find.ts
│ │ └── list.ts
│ ├── favorites
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── id.ts
│ │ ├── list.ts
│ │ └── update.ts
│ ├── follow
│ │ ├── follow.ts
│ │ ├── followers-list.ts
│ │ ├── following-list.ts
│ │ ├── unfollow.ts
│ │ └── user-follow-state.ts
│ ├── friendly-link
│ │ ├── adopt.ts
│ │ ├── apply.ts
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ └── list.ts
│ ├── high-light
│ │ ├── high-light.ts
│ │ └── language-list.ts
│ ├── like
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ └── state.ts
│ ├── notice
│ │ ├── list-notice.ts
│ │ ├── notice-count.ts
│ │ └── update-notice.ts
│ ├── problem
│ │ ├── adopt.ts
│ │ ├── cancel.ts
│ │ ├── create.ts
│ │ ├── delete.ts
│ │ ├── list-user.ts
│ │ ├── list.ts
│ │ ├── questions.ts
│ │ ├── read-update.ts
│ │ └── update.ts
│ ├── ranking
│ │ ├── author.ts
│ │ └── funs.ts
│ ├── sitemap
│ │ ├── index.ts
│ │ ├── list-xml.ts
│ │ └── list.ts
│ ├── static
│ │ └── upload-image.ts
│ ├── statistics
│ │ ├── index.ts
│ │ └── visualization.ts
│ ├── tag
│ │ ├── create-tag.ts
│ │ ├── delete-tag.ts
│ │ ├── get-data-id.ts
│ │ ├── list.ts
│ │ ├── reception-tag-tree.ts
│ │ └── update.ts
│ ├── theme
│ │ ├── create.ts
│ │ ├── item.ts
│ │ ├── list.ts
│ │ ├── remove.ts
│ │ └── update.ts
│ └── user
│ │ ├── destroy
│ │ ├── destroy-id.ts
│ │ ├── destroy.ts
│ │ └── recovery.ts
│ │ ├── forget-password
│ │ ├── email-update.ts
│ │ └── email.ts
│ │ ├── get-data
│ │ ├── achievement.ts
│ │ ├── user-data.ts
│ │ ├── user-info.ts
│ │ └── user-list.ts
│ │ ├── login
│ │ └── email-password.ts
│ │ ├── logon
│ │ ├── email-link.ts
│ │ └── logn-email-link.ts
│ │ ├── tools
│ │ └── location.ts
│ │ └── update
│ │ ├── email
│ │ ├── email-link.ts
│ │ └── email.ts
│ │ ├── password.ts
│ │ └── update.ts
├── socket
│ ├── index.ts
│ └── oss.ts
└── views
│ ├── forget-password.ejs
│ ├── friendly-apply.ejs
│ ├── friendly-fail.ejs
│ ├── logn-up.ejs
│ └── update-email.ejs
├── tsconfig.json
├── types
├── NodeJS
│ └── index.d.ts
├── identicon.js
│ └── index.d.ts
├── koa
│ └── index.d.ts
└── turndown-plugin-gfm
│ └── index.d.ts
└── yarn.lock
/.github/ISSUE_TEMPLATE/✨-新功能建议.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "✨ 新功能建议"
3 | about: 建议出一个XX新功能
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/系统问题解答.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 系统问题解答
3 | about: 对于系统内的功能实现,你有什么不懂的可以再这里提问
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | 1.管理系统、用户端、服务器哪里的哪个问题不懂
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/🐞-bug反馈.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F41E BUG反馈"
3 | about: 反馈系统漏洞
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ** 环境 **
11 | 1. 浏览器以及版本:
12 | 2. Node.js版本:
13 | 3. MySQL版本:
14 | 4. Redis版本:
15 |
16 | ** 报错情况 **
17 |
18 |
19 | ** 我该如何复现 **
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .next
4 | .idea
5 | .vscode
6 | .DS_Store
7 | *.local
8 |
9 | server/**/.env.development
10 | server/**/.env.production
11 | server/log
12 | server/blog_server
13 |
14 | client/env/.env.production
--------------------------------------------------------------------------------
/client/env/.env:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_SITE_NAME=网络日志
2 | # 站长信息配置
3 | QQ=1974109227
4 | EMAIL=1974109227@qq.com
5 | GITHUB=https://github.com/Lrunlin
6 | ICP=辽ICP备2020014377号
7 | # Google ADS
8 | NEXT_PUBLIC_GOOGLE_ADS_CLIENT_ID=1577114276814290
9 | NEXT_PUBLIC_GOOGLE_ADS_SLOT=3214779798
10 |
11 | # 上传图片最大多MB
12 | UPLOAD_MAX_SIZE=5
13 |
14 | # 鉴权方式
15 | AUTH_MODE=session
--------------------------------------------------------------------------------
/client/env/.env.development:
--------------------------------------------------------------------------------
1 | NEXT_PUBLIC_HOST=http://localhost:5678
2 | NEXT_PUBLIC_API_HOST=http://localhost:3000
3 | NEXT_PUBLIC_GITHUB_CLIENT_ID=b1099c9c62ebb6ff2d87
4 |
5 | CDN=http://localhost:5678
6 |
7 | # Redis配置
8 | REDIS_HOST=localhost
9 | REDIS_USER=
10 | REDIS_POST=6379
11 | REDIS_PASSWORD=""
12 |
13 |
--------------------------------------------------------------------------------
/client/env/index.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const path = require("path");
3 | const dotenv = require("dotenv");
4 | const md5 = require("md5");
5 | const { globSync } = require("glob");
6 |
7 | let envObject = dotenv.parse(
8 | `${fs.readFileSync(path.join(__dirname, "./.env"))}
9 | \n
10 | ${fs.readFileSync(
11 | path.join(
12 | __dirname,
13 | `./.env.${process.env.NEXT_PUBLIC_ISPRO ? "production" : "development"}`,
14 | ),
15 | )}
16 | `,
17 | );
18 |
19 | module.exports = {
20 | buildid: () => {
21 | return md5(
22 | globSync(["src/**/*.*", "./**.js", "./**.json", "./**.ts", "./**.lock"])
23 | .filter((item) => {
24 | const filePath = path.resolve(process.cwd(), item);
25 | return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
26 | })
27 | .map((item) => {
28 | let str = fs.readFileSync(item).toString();
29 | return md5(item + str);
30 | })
31 | .join(""),
32 | );
33 | },
34 | env: envObject,
35 | };
36 |
--------------------------------------------------------------------------------
/client/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
6 |
--------------------------------------------------------------------------------
/client/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | // autoprefixer: {},//自动前缀
5 | ...(process.env.NEXT_PUBLIC_ISPRO
6 | ? {
7 | cssnano: {},
8 | }
9 | : {}),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/icon/admin/QQ.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/icon/admin/fork.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/icon/admin/数据看板.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/icon/client/briefcase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/briefcase.png
--------------------------------------------------------------------------------
/client/public/icon/client/collection-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/collection-blue.png
--------------------------------------------------------------------------------
/client/public/icon/client/collection-fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/collection-fill.png
--------------------------------------------------------------------------------
/client/public/icon/client/collection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/collection.png
--------------------------------------------------------------------------------
/client/public/icon/client/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/comment.png
--------------------------------------------------------------------------------
/client/public/icon/client/comments.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/comments.png
--------------------------------------------------------------------------------
/client/public/icon/client/delete-fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/delete-fill.png
--------------------------------------------------------------------------------
/client/public/icon/client/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/delete.png
--------------------------------------------------------------------------------
/client/public/icon/client/email-fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/email-fill.png
--------------------------------------------------------------------------------
/client/public/icon/client/email.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/email.png
--------------------------------------------------------------------------------
/client/public/icon/client/emoji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/emoji.png
--------------------------------------------------------------------------------
/client/public/icon/client/github-fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/github-fill.png
--------------------------------------------------------------------------------
/client/public/icon/client/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/github.png
--------------------------------------------------------------------------------
/client/public/icon/client/likes-fill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/likes-fill.png
--------------------------------------------------------------------------------
/client/public/icon/client/likes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/likes.png
--------------------------------------------------------------------------------
/client/public/icon/client/picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/picture.png
--------------------------------------------------------------------------------
/client/public/icon/client/police.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/police.png
--------------------------------------------------------------------------------
/client/public/icon/client/postcard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/postcard.png
--------------------------------------------------------------------------------
/client/public/icon/client/problem-collection-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/problem-collection-black.png
--------------------------------------------------------------------------------
/client/public/icon/client/problem-collection-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/problem-collection-white.png
--------------------------------------------------------------------------------
/client/public/icon/client/problem-follow-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/problem-follow-black.png
--------------------------------------------------------------------------------
/client/public/icon/client/problem-follow-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/problem-follow-white.png
--------------------------------------------------------------------------------
/client/public/icon/client/problem-like-black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/problem-like-black.png
--------------------------------------------------------------------------------
/client/public/icon/client/problem-like-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/problem-like-white.png
--------------------------------------------------------------------------------
/client/public/icon/client/qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/qq.png
--------------------------------------------------------------------------------
/client/public/icon/client/share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/share.png
--------------------------------------------------------------------------------
/client/public/icon/client/small-bell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/small-bell.png
--------------------------------------------------------------------------------
/client/public/icon/client/unit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/unit.png
--------------------------------------------------------------------------------
/client/public/icon/client/view-blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/view-blue.png
--------------------------------------------------------------------------------
/client/public/icon/client/view-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/view-white.png
--------------------------------------------------------------------------------
/client/public/icon/client/view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/view.png
--------------------------------------------------------------------------------
/client/public/icon/client/website.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/website.png
--------------------------------------------------------------------------------
/client/public/icon/client/wechat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/icon/client/wechat.png
--------------------------------------------------------------------------------
/client/public/image/admin/statistics/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/admin/statistics/bg.jpg
--------------------------------------------------------------------------------
/client/public/image/admin/statistics/border_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/admin/statistics/border_bg.jpg
--------------------------------------------------------------------------------
/client/public/image/admin/statistics/title_left_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/admin/statistics/title_left_bg.png
--------------------------------------------------------------------------------
/client/public/image/admin/statistics/title_right_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/admin/statistics/title_right_bg.png
--------------------------------------------------------------------------------
/client/public/image/client/collection-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/client/collection-bg.jpg
--------------------------------------------------------------------------------
/client/public/image/client/github.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/client/github.jpg
--------------------------------------------------------------------------------
/client/public/image/client/load-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/client/load-error.png
--------------------------------------------------------------------------------
/client/public/image/client/qq-qrcode.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/client/qq-qrcode.jpg
--------------------------------------------------------------------------------
/client/public/image/client/wechat-qrcode.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lrunlin/blog/94c8e95f172520490e4f996b2bb6fde6657ef36e/client/public/image/client/wechat-qrcode.jpg
--------------------------------------------------------------------------------
/client/public/robots-template.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Allow:*
3 | # 文章修改和发布
4 | Disallow:/article/editor
5 | # 开发者中心
6 | Disallow:/creator
7 | # 文章搜索
8 | Disallow:/search
9 | # 用户信息
10 | Disallow:/user
11 | # 消息提示
12 | Disallow:/notification
13 | # oauth登录重定向
14 | Disallow:/oauth
15 | # 部分链接的结果展示
16 | Disallow:/result
17 | # 友链页面
18 | Disallow:/friendly-link
19 | #中转页面
20 | Disallow:/link
21 | # 提问
22 | Disallow:/problem/editor
23 | # 收藏页面
24 | Disallow:/collection
25 | # 管理员
26 | Disallow:/admin
27 | # 找回密码
28 | Disallow:/forget-password
29 |
30 | Sitemap:https://blogweb.cn/sitemap/index.xml
--------------------------------------------------------------------------------
/client/scripts/build-output/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": [],
3 | "ext": "js",
4 | "ignore": ["*"],
5 | "restartable": "rs",
6 | "exec": "node ./server.js",
7 | "env": {
8 | "PORT": "5678",
9 | "NEXT_PUBLIC_ISPRO": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/client/src/app/(route)/ads.txt/route.ts:
--------------------------------------------------------------------------------
1 | export async function GET() {
2 | if (process.env.NEXT_PUBLIC_GOOGLE_ADS_CLIENT_ID) {
3 | return new Response(
4 | `google.com, pub-${process.env.NEXT_PUBLIC_GOOGLE_ADS_CLIENT_ID}, DIRECT, f08c47fec0942fa0`,
5 | {
6 | status: 200,
7 | headers: {
8 | "content-type": "text/txt; charset=utf-8",
9 | },
10 | },
11 | );
12 | } else {
13 | return new Response(undefined, {
14 | status: 404,
15 | });
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/client/src/app/(route)/sitemap/[type]/index.xml/route.tsx:
--------------------------------------------------------------------------------
1 | import { NextRequest } from "next/server";
2 | import axios from "@axios";
3 | import setSiteMap from "@/common/modules/sitemap/sitemap-index";
4 |
5 | export async function GET(
6 | res: NextRequest,
7 | props: { params: Promise<{ type: string }> },
8 | ) {
9 | const params = await props.params;
10 | let xml = await axios
11 | .get("/sitemap/" + params.type)
12 | .then((res) => setSiteMap(res.data.data));
13 | return new Response(xml, {
14 | status: 200,
15 | headers: {
16 | "content-type": "text/xml; charset=utf-8",
17 | },
18 | });
19 | }
20 |
--------------------------------------------------------------------------------
/client/src/app/(route)/sitemap/[type]/index[index].xml/route.tsx:
--------------------------------------------------------------------------------
1 | import { NextRequest } from "next/server";
2 | import axios from "@axios";
3 | import setSiteMap from "@/common/modules/sitemap/sitemap";
4 |
5 | export async function GET(
6 | res: NextRequest,
7 | props: { params: Promise<{ type: string }> },
8 | ) {
9 | const params = await props.params;
10 | let match = res.nextUrl.pathname.match(/index(\d+)\.xml/);
11 |
12 | if (!match || !["article", "problem"].includes(params.type)) {
13 | return new Response(undefined, {
14 | status: 400,
15 | });
16 | }
17 |
18 | let sitemap = await axios
19 | .get(`/sitemap/${params.type}/${match[1]}`)
20 | .then((res) => setSiteMap(res.data.data))
21 | .catch((err) => {
22 | console.log(err);
23 | return ``;
24 | });
25 |
26 | return new Response(sitemap, {
27 | status: 200,
28 | headers: {
29 | "content-type": "text/xml; charset=utf-8",
30 | },
31 | });
32 | }
33 |
--------------------------------------------------------------------------------
/client/src/app/(route)/static/antd/[name]/route.tsx:
--------------------------------------------------------------------------------
1 | import { NextRequest } from "next/server";
2 | import fs from "fs";
3 |
4 | type Params = {
5 | name: string;
6 | };
7 |
8 | export async function GET(
9 | res: NextRequest,
10 | context: { params: Promise },
11 | ) {
12 | let name = (await context.params)!.name as string | undefined;
13 | if (typeof name == "string" && name?.endsWith(".css")) {
14 | try {
15 | let content = fs.readFileSync(`.next/css/${name}`).toString();
16 |
17 | return new Response(content, {
18 | status: 200,
19 | headers: {
20 | "content-type": "text/css; charset=utf-8",
21 | },
22 | });
23 | } catch (error) {
24 | console.log(error);
25 | return new Response(undefined, {
26 | status: 404,
27 | });
28 | }
29 | } else {
30 | return new Response(undefined, {
31 | status: 404,
32 | });
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/client/src/app/(route)/static/high-light/[type]/route.tsx:
--------------------------------------------------------------------------------
1 | import type { NextRequest } from "next/server";
2 | import axios from "@axios";
3 |
4 | export async function GET(
5 | res: NextRequest,
6 | props: { params: Promise<{ type: string }> },
7 | ) {
8 | const params = await props.params;
9 |
10 | const { type } = params;
11 |
12 | const searchParams = res.nextUrl.searchParams;
13 | const languages = searchParams.get("languages");
14 | if (["js", "css"].includes(String(type))) {
15 | let content = await axios
16 | .get(`/high-light/${type}`, {
17 | params: { languages: languages },
18 | })
19 | .then((res) => res.data);
20 | return new Response(content, {
21 | status: 200,
22 | headers: {
23 | "content-type": `text/${type}; charset=utf-8`,
24 | "Cache-Control": `public, max-age=9999999999, must-revalidate`,
25 | },
26 | });
27 | } else {
28 | return new Response(undefined, {
29 | status: 404,
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/client/src/app/(route)/static/theme/[id]/route.tsx:
--------------------------------------------------------------------------------
1 | import type { NextRequest } from "next/server";
2 | import axios from "@axios";
3 |
4 | export async function GET(
5 | res: NextRequest,
6 | props: { params: Promise<{ id: string }> },
7 | ) {
8 | const params = await props.params;
9 |
10 | const { id } = params;
11 |
12 | if (!(id as string).endsWith(".css")) {
13 | return new Response(undefined, {
14 | status: 404,
15 | });
16 | }
17 |
18 | let content = await axios
19 | .get(`/theme/${(id as string).replace(/.css/, "")}`)
20 | .then((res) => res.data?.data?.content)
21 | .catch(() => false);
22 |
23 | if (!content) {
24 | return new Response(undefined, {
25 | status: 404,
26 | });
27 | }
28 |
29 | return new Response(content, {
30 | status: 200,
31 | headers: {
32 | "content-type": `text/css; charset=utf-8`,
33 | "Cache-Control": `public, max-age=9999999999, must-revalidate`,
34 | },
35 | });
36 | }
37 |
--------------------------------------------------------------------------------
/client/src/app/admin/[...all]/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 | import { Button, Result } from "antd";
5 | import Head from "@/components/next/Head";
6 |
7 | const NoFound = () => {
8 | let router = useRouter();
9 | return (
10 | <>
11 |
12 | router.replace("/admin")}>
18 | 首页
19 |
20 | }
21 | />
22 | >
23 | );
24 | };
25 | export default NoFound;
26 |
--------------------------------------------------------------------------------
/client/src/app/admin/advertisement/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import { message } from "antd";
5 | import axios from "@axios";
6 | import AdvertisementForm from "@/components/admin/page/advertisement/AdvertisementForm";
7 |
8 | const APP = () => {
9 | const [key, setKey] = useState(`key-AdvertisementForm-1`);
10 |
11 | function onFinish(values: any) {
12 | axios.post("/advertisement", values).then((res) => {
13 | if (res.data.success) {
14 | message.success(res.data.message);
15 | setKey(`key-AdvertisementForm-${Math.random()}`);
16 | } else {
17 | message.error(res.data.message);
18 | }
19 | });
20 | }
21 | return (
22 | <>
23 |
26 | >
27 | );
28 | };
29 | export default APP;
30 |
--------------------------------------------------------------------------------
/client/src/app/admin/layout.tsx:
--------------------------------------------------------------------------------
1 | import { cookies, headers } from "next/headers";
2 | import AdminLayout from "@/layout/Admin/Base";
3 |
4 | export default async function RootLayout({
5 | children,
6 | }: Readonly<{
7 | children: React.ReactNode;
8 | }>) {
9 | let cookie = await cookies();
10 | let header = await headers();
11 |
12 | return header.get("x-pathname") ? (
13 |
14 | {children}
15 |
16 | ) : (
17 | <>{children}>
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/client/src/app/admin/theme/create/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import CreateTheme from "@/components/common/CreateTheme";
4 |
5 | export default () => (
6 | <>
7 |
8 | >
9 | );
10 |
--------------------------------------------------------------------------------
/client/src/app/article/[id]/(main)/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { FC, ReactNode } from "react";
2 | import Read from "@/layout/Content";
3 | import Aside from "@/components/page/article/Aside";
4 | import ToolBar from "@/components/page/article/ToolBar";
5 |
6 | const Layout: FC<{ children: ReactNode }> = ({ children }) => {
7 | return (
8 | <>
9 | } Aside={}>
10 | {children}
11 |
12 | >
13 | );
14 | };
15 | export default Layout;
16 |
--------------------------------------------------------------------------------
/client/src/app/article/[id]/not-found.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 | import { Button, Result } from "antd";
5 | import Header from "@/components/common/Header";
6 | import Head from "@/components/next/Head";
7 |
8 | const Error = () => {
9 | let router = useRouter();
10 |
11 | return (
12 | <>
13 |
18 |
19 | router.replace("/")}>
25 | 回到首页
26 |
27 | }
28 | />
29 | >
30 | );
31 | };
32 |
33 | export default Error;
34 |
--------------------------------------------------------------------------------
/client/src/app/collection/[id]/not-found.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 | import { Button, Result } from "antd";
5 | import Base from "@/layout/Base";
6 |
7 | const NoFound = () => {
8 | let router = useRouter();
9 |
10 | return (
11 | <>
12 |
13 |
14 | router.replace("/")}>
20 | 返回首页
21 |
22 | }
23 | />
24 |
25 |
26 | >
27 | );
28 | };
29 | export default NoFound;
30 |
--------------------------------------------------------------------------------
/client/src/app/error.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 | import { Button, Result } from "antd";
5 | import Header from "@/components/common/Header";
6 | import Head from "@/components/next/Head";
7 |
8 | const Error = (err: any) => {
9 | let router = useRouter();
10 |
11 | return (
12 | <>
13 |
14 |
15 | router.replace("/")}>
22 | 回到首页
23 |
24 | }
25 | >
26 | >
27 | );
28 | };
29 |
30 | export default Error;
31 |
--------------------------------------------------------------------------------
/client/src/app/friendly-link/page.tsx:
--------------------------------------------------------------------------------
1 | import axios from "@axios";
2 | import type { response } from "@type/common/response";
3 | import type { userDataType } from "@type/common/user-data";
4 | import type { LinkAttributes } from "@type/model-attribute";
5 | import Header from "@/components/common/Header";
6 | import Head from "@/components/next/Head";
7 | import FriendlyLink from "@/components/page/friendly-link/FriendlyLink";
8 |
9 | type linkItem = Pick<
10 | LinkAttributes,
11 | "id" | "name" | "logo_file_name" | "logo_url" | "url"
12 | > & {
13 | user_data?: userDataType;
14 | };
15 |
16 | const Links = async () => {
17 | let data = await axios
18 | .get>("/friendly-link")
19 | .then((res) => res.data.data);
20 |
21 | return (
22 | <>
23 |
24 |
25 |
26 | >
27 | );
28 | };
29 | export default Links;
30 |
--------------------------------------------------------------------------------
/client/src/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 | import { Button, Result } from "antd";
5 | import Header from "@/components/common/Header";
6 | import Head from "@/components/next/Head";
7 |
8 | const NotFound = () => {
9 | let router = useRouter();
10 |
11 | return (
12 | <>
13 |