├── logs └── .gitkeep ├── public ├── placeholder-qr.png ├── icon │ ├── web │ │ ├── favicon.ico │ │ ├── icon-192.png │ │ ├── icon-512.png │ │ ├── apple-touch-icon.png │ │ ├── icon-192-maskable.png │ │ ├── icon-512-maskable.png │ │ └── README.txt │ ├── ios │ │ ├── AppIcon-29.png │ │ ├── AppIcon@2x.png │ │ ├── AppIcon@3x.png │ │ ├── AppIcon~ipad.png │ │ ├── AppIcon-20@2x.png │ │ ├── AppIcon-20@3x.png │ │ ├── AppIcon-20~ipad.png │ │ ├── AppIcon-29@2x.png │ │ ├── AppIcon-29@3x.png │ │ ├── AppIcon-29~ipad.png │ │ ├── AppIcon-40@2x.png │ │ ├── AppIcon-40@3x.png │ │ ├── AppIcon-40~ipad.png │ │ ├── AppIcon@2x~ipad.png │ │ ├── AppIcon-60@2x~car.png │ │ ├── AppIcon-60@3x~car.png │ │ ├── AppIcon-20@2x~ipad.png │ │ ├── AppIcon-29@2x~ipad.png │ │ ├── AppIcon-40@2x~ipad.png │ │ ├── AppIcon-83.5@2x~ipad.png │ │ └── AppIcon~ios-marketing.png │ └── android │ │ ├── play_store_512.png │ │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_monochrome.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_monochrome.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_monochrome.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_monochrome.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_monochrome.png │ │ └── mipmap-anydpi-v26 │ │ └── ic_launcher.xml ├── images │ ├── default-qrcode.png │ └── default-thumbnail.png ├── vercel.svg ├── uploads │ ├── 0bad1549-227b-462b-b500-5c40cf346f29.png │ ├── 1b65d6d3-6ef8-4fbe-a242-afe60c2136b0.png │ ├── 20ddc0c2-a981-404c-bd25-5acc8b5d6e54.png │ ├── 304bb973-5262-4074-99f2-ce2cce282dda.png │ ├── 33611009-b45e-4f5e-85cc-ab75da2541a9.png │ ├── 373a5d7f-4a9c-4f79-b4bf-144485bc60e1.png │ ├── 3971a0c0-2c9b-4cec-85fd-c613742a0a7d.png │ ├── 51a94123-3c24-431d-9a08-bc88a3be0d11.png │ ├── 51e92ef1-7c54-40a3-82a5-5e4d7ae41f47.png │ ├── 5a3c2bd2-e0fc-4890-a902-64039547cf2d.png │ ├── 5aa0c80f-b23d-4081-af5d-55c4b9f8e7c3.png │ ├── 5b13b0c7-8363-4d2d-a156-c37c46287df1.png │ ├── 5bcec724-4c3b-4545-9c95-f183698296d4.png │ ├── 6321e5b7-5866-44d8-98b6-8eb4e8531407.png │ ├── 6413a9bf-35ee-4fba-b6bd-f260d5543f95.png │ ├── 64ee3e69-f676-4ccb-b353-28f64095a362.png │ ├── 684f0a84-4d8b-4d57-bb71-b7451c7504d2.png │ ├── 686bee4c-67db-4f63-a623-8a291f06f30e.png │ ├── 6b1b3100-d856-4ffb-a033-280356beaf3d.png │ ├── 6bb144cc-a10a-44b0-acbb-a56f10dcd16a.png │ ├── 70d744cd-85df-4cbd-95d7-3efb3ba6b983.png │ ├── 7d0f6464-d3ad-480f-8963-25e9f442da42.png │ ├── 7e849ea9-76b5-4481-8af4-57dd0c1606f7.png │ ├── 8147285b-d577-43c0-a161-bfdcbb08e1e1.png │ ├── 875f2cbc-c88f-4b29-adf6-734530ccbc0e.png │ ├── 87b63bc7-96e2-4982-a47d-c6ea65b8efc3.png │ ├── 90733c3c-6d6d-4894-8c37-90dc8cf0a816.png │ ├── 9161c3b8-6daa-4e51-a3f1-f71d597e326d.png │ ├── 94deca3e-6e7d-4efd-8ebd-3755bb723ed0.png │ ├── 97d41ef4-cc7b-4d20-b1a5-47546288c2a7.png │ ├── 999bf369-8477-4add-8384-4c4abda1df6a.png │ ├── 9bb06850-815d-4834-8a3e-474c9e1d1e6b.png │ ├── a80ff25a-4a5b-45c2-97b6-2c2a8d31894d.png │ ├── aab9ba5b-3dd9-4f61-9130-00582184beca.png │ ├── abb91af5-0edd-4459-a37f-a30cc2e616b0.png │ ├── abf2ae63-7c74-465e-958c-7b39bd43478f.png │ ├── b6a65458-8256-402b-9a6b-67c203229de3.png │ ├── b7772814-5698-4902-9d31-6fd10453b673.png │ ├── bc982ea5-1909-486d-a7d2-ae591744126c.png │ ├── cc3a296e-5e6f-40e9-820d-5d49add696d0.png │ ├── cc978f5b-c4a6-4f3c-9242-a2e8b790b9a1.png │ ├── dc32267f-895c-49f9-a03e-4bb861abeead.png │ ├── e3f66a31-9000-4cf0-a1cb-44939aa69117.png │ ├── e8a76490-4fdb-411c-a996-01c3d896e7c0.png │ ├── f0a78892-ca47-4753-a5ff-369674b5e19c.png │ ├── f69badfa-94f4-4509-a70c-7338511697a4.png │ ├── f8eec96f-5d65-46b5-9648-b729eb4c54d9.png │ ├── f985396d-8d7a-4d65-8501-8a4bcad61929.png │ ├── fa48845d-46e4-48e9-a53c-2a41d7488a34.png │ ├── contact │ │ ├── 05547404-c0cc-4229-bb42-ed4eb28de871.jpeg │ │ ├── 3e5464e1-f6cd-4600-b9dc-6f9552547d29.png │ │ └── ca46cdc3-6463-4794-a27b-174aa373f15e.jpeg │ └── donation │ │ └── 63a278f4-8927-4123-b95c-4dffb5ea7430.png ├── window.svg ├── file.svg ├── icons │ ├── twitter.svg │ ├── github.svg │ └── wechat.svg ├── test.html ├── globe.svg ├── next.svg ├── js │ ├── mobile-menu.js │ └── theme.js └── placeholder-qr.svg ├── src ├── types │ ├── uuid.d.ts │ ├── index.ts │ └── yaireo__tagify.d.ts ├── app │ ├── favicon.ico │ ├── api │ │ ├── auth │ │ │ └── [...nextauth] │ │ │ │ └── route.ts │ │ ├── admin │ │ │ ├── stats │ │ │ │ └── route.ts │ │ │ ├── posts │ │ │ │ └── route.ts │ │ │ └── create-admin │ │ │ │ └── route.ts │ │ ├── create-user │ │ │ └── route.ts │ │ ├── settings │ │ │ ├── donation │ │ │ │ └── route.ts │ │ │ ├── contact │ │ │ │ └── route.ts │ │ │ ├── scripts │ │ │ │ ├── route.ts │ │ │ │ └── position │ │ │ │ │ └── route.ts │ │ │ ├── route.ts │ │ │ └── general │ │ │ │ └── route.ts │ │ ├── links │ │ │ ├── route.ts │ │ │ ├── webhook │ │ │ │ └── route.ts │ │ │ └── [id] │ │ │ │ └── route.ts │ │ ├── register │ │ │ └── route.ts │ │ ├── logout │ │ │ └── route.ts │ │ ├── users │ │ │ └── route.ts │ │ ├── categories │ │ │ ├── list │ │ │ │ └── route.ts │ │ │ └── reset │ │ │ │ └── route.ts │ │ ├── admin-bypass │ │ │ └── route.ts │ │ ├── tags │ │ │ └── all │ │ │ │ └── route.ts │ │ ├── webhooks │ │ │ └── route.ts │ │ ├── login │ │ │ └── route.ts │ │ └── debug-auth │ │ │ └── route.ts │ ├── (main) │ │ └── layout.tsx │ ├── admin │ │ └── layout.tsx │ ├── (frontend) │ │ └── layout.tsx │ ├── login │ │ └── layout.tsx │ ├── tags │ │ ├── [slug] │ │ │ └── page.tsx │ │ └── page.tsx │ ├── categories │ │ └── [slug] │ │ │ └── page.tsx │ ├── direct-login │ │ └── page.tsx │ ├── simple │ │ └── page.tsx │ ├── links │ │ └── page.tsx │ ├── search │ │ └── page.tsx │ ├── posts │ │ └── page.tsx │ └── page.tsx ├── lib │ ├── mock-modules │ │ └── nodejieba.js │ ├── migrations │ │ ├── meta │ │ │ └── _journal.json │ │ ├── 0000_init_schema.sql │ │ └── 0000_init_schema.ts │ ├── links-db.ts │ ├── utils │ │ └── menu-adapters.ts │ ├── reset-password.ts │ ├── db │ │ └── migrations │ │ │ └── 0007_add_head_scripts_table.ts │ ├── migrate.ts │ ├── schema │ │ └── links.ts │ └── utils.ts ├── components │ ├── providers │ │ └── SessionProvider.tsx │ ├── AdminCheck.tsx │ ├── ScriptLoaderWrapper.tsx │ ├── ScriptLoader.tsx │ ├── ui │ │ ├── link.tsx │ │ ├── label.tsx │ │ ├── textarea.tsx │ │ ├── separator.tsx │ │ ├── input.tsx │ │ ├── checkbox.tsx │ │ ├── toaster.tsx │ │ ├── tooltip.tsx │ │ ├── switch.tsx │ │ ├── badge.tsx │ │ ├── icons.tsx │ │ ├── alert.tsx │ │ ├── button.tsx │ │ ├── modal.tsx │ │ ├── tabs.tsx │ │ ├── card.tsx │ │ └── toggle-group.tsx │ ├── EditPostLink.tsx │ ├── Avatar.tsx │ ├── AdminPublishLink.tsx │ ├── NextScriptLoader.tsx │ ├── admin │ │ └── header.tsx │ └── MainLayout.tsx ├── scripts │ ├── migrations │ │ └── add-menus-table.ts │ ├── update-password.ts │ └── check-users.ts ├── middleware.ts ├── utils │ └── html-sanitizer.ts └── hooks │ └── useSettings.ts ├── blog.db ├── links.db ├── postcss.config.js ├── postcss.config.mjs ├── .env ├── docker-compose.yml ├── .env.example ├── Dockerfile ├── vercel.json ├── start-dev.sh ├── eslint.config.mjs ├── ecosystem.config.js ├── .gitignore ├── tsconfig.json ├── migrations └── add_page_type_to_posts.js ├── scripts ├── start-dev.bat ├── start-dev.sh ├── run-migration.js ├── add-is-visible-to-links.js ├── insert-test-menus.sql ├── init-links-db.js ├── create-admin.js ├── create-demo-db.js └── reset-admin.js ├── next.config.ts ├── copy-static-assets.sh ├── deploy-standalone.sh ├── test-password.js ├── rebuild.sh ├── setup.bat ├── backup ├── delete-user.js └── reset-admin-account.js ├── next.config.js.bak ├── update-posts-add-cover.js ├── IMPLEMENTATION_NOTES.md ├── setup.sh ├── .github └── workflows │ └── deploy-to-bt.yml ├── reset-categories.js ├── start-standalone.js ├── next.config.js └── NAMING_CONVENTIONS.md /logs/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /public/placeholder-qr.png: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/types/uuid.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'uuid'; 2 | -------------------------------------------------------------------------------- /blog.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/blog.db -------------------------------------------------------------------------------- /links.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/links.db -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /public/icon/web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/web/favicon.ico -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-29.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon@2x.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon@3x.png -------------------------------------------------------------------------------- /public/icon/web/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/web/icon-192.png -------------------------------------------------------------------------------- /public/icon/web/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/web/icon-512.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /public/icon/ios/AppIcon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon~ipad.png -------------------------------------------------------------------------------- /public/images/default-qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/images/default-qrcode.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-20@2x.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-20@3x.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-20~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-20~ipad.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-29@2x.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-29@3x.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-29~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-29~ipad.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-40@2x.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-40@3x.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-40~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-40~ipad.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon@2x~ipad.png -------------------------------------------------------------------------------- /public/images/default-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/images/default-thumbnail.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-60@2x~car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-60@2x~car.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-60@3x~car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-60@3x~car.png -------------------------------------------------------------------------------- /public/icon/web/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/web/apple-touch-icon.png -------------------------------------------------------------------------------- /public/icon/web/icon-192-maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/web/icon-192-maskable.png -------------------------------------------------------------------------------- /public/icon/web/icon-512-maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/web/icon-512-maskable.png -------------------------------------------------------------------------------- /public/icon/android/play_store_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/play_store_512.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-20@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-20@2x~ipad.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-29@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-29@2x~ipad.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-40@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-40@2x~ipad.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon-83.5@2x~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon-83.5@2x~ipad.png -------------------------------------------------------------------------------- /public/icon/ios/AppIcon~ios-marketing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/ios/AppIcon~ios-marketing.png -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /public/uploads/0bad1549-227b-462b-b500-5c40cf346f29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/0bad1549-227b-462b-b500-5c40cf346f29.png -------------------------------------------------------------------------------- /public/uploads/1b65d6d3-6ef8-4fbe-a242-afe60c2136b0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/1b65d6d3-6ef8-4fbe-a242-afe60c2136b0.png -------------------------------------------------------------------------------- /public/uploads/20ddc0c2-a981-404c-bd25-5acc8b5d6e54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/20ddc0c2-a981-404c-bd25-5acc8b5d6e54.png -------------------------------------------------------------------------------- /public/uploads/304bb973-5262-4074-99f2-ce2cce282dda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/304bb973-5262-4074-99f2-ce2cce282dda.png -------------------------------------------------------------------------------- /public/uploads/33611009-b45e-4f5e-85cc-ab75da2541a9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/33611009-b45e-4f5e-85cc-ab75da2541a9.png -------------------------------------------------------------------------------- /public/uploads/373a5d7f-4a9c-4f79-b4bf-144485bc60e1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/373a5d7f-4a9c-4f79-b4bf-144485bc60e1.png -------------------------------------------------------------------------------- /public/uploads/3971a0c0-2c9b-4cec-85fd-c613742a0a7d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/3971a0c0-2c9b-4cec-85fd-c613742a0a7d.png -------------------------------------------------------------------------------- /public/uploads/51a94123-3c24-431d-9a08-bc88a3be0d11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/51a94123-3c24-431d-9a08-bc88a3be0d11.png -------------------------------------------------------------------------------- /public/uploads/51e92ef1-7c54-40a3-82a5-5e4d7ae41f47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/51e92ef1-7c54-40a3-82a5-5e4d7ae41f47.png -------------------------------------------------------------------------------- /public/uploads/5a3c2bd2-e0fc-4890-a902-64039547cf2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/5a3c2bd2-e0fc-4890-a902-64039547cf2d.png -------------------------------------------------------------------------------- /public/uploads/5aa0c80f-b23d-4081-af5d-55c4b9f8e7c3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/5aa0c80f-b23d-4081-af5d-55c4b9f8e7c3.png -------------------------------------------------------------------------------- /public/uploads/5b13b0c7-8363-4d2d-a156-c37c46287df1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/5b13b0c7-8363-4d2d-a156-c37c46287df1.png -------------------------------------------------------------------------------- /public/uploads/5bcec724-4c3b-4545-9c95-f183698296d4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/5bcec724-4c3b-4545-9c95-f183698296d4.png -------------------------------------------------------------------------------- /public/uploads/6321e5b7-5866-44d8-98b6-8eb4e8531407.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/6321e5b7-5866-44d8-98b6-8eb4e8531407.png -------------------------------------------------------------------------------- /public/uploads/6413a9bf-35ee-4fba-b6bd-f260d5543f95.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/6413a9bf-35ee-4fba-b6bd-f260d5543f95.png -------------------------------------------------------------------------------- /public/uploads/64ee3e69-f676-4ccb-b353-28f64095a362.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/64ee3e69-f676-4ccb-b353-28f64095a362.png -------------------------------------------------------------------------------- /public/uploads/684f0a84-4d8b-4d57-bb71-b7451c7504d2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/684f0a84-4d8b-4d57-bb71-b7451c7504d2.png -------------------------------------------------------------------------------- /public/uploads/686bee4c-67db-4f63-a623-8a291f06f30e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/686bee4c-67db-4f63-a623-8a291f06f30e.png -------------------------------------------------------------------------------- /public/uploads/6b1b3100-d856-4ffb-a033-280356beaf3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/6b1b3100-d856-4ffb-a033-280356beaf3d.png -------------------------------------------------------------------------------- /public/uploads/6bb144cc-a10a-44b0-acbb-a56f10dcd16a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/6bb144cc-a10a-44b0-acbb-a56f10dcd16a.png -------------------------------------------------------------------------------- /public/uploads/70d744cd-85df-4cbd-95d7-3efb3ba6b983.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/70d744cd-85df-4cbd-95d7-3efb3ba6b983.png -------------------------------------------------------------------------------- /public/uploads/7d0f6464-d3ad-480f-8963-25e9f442da42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/7d0f6464-d3ad-480f-8963-25e9f442da42.png -------------------------------------------------------------------------------- /public/uploads/7e849ea9-76b5-4481-8af4-57dd0c1606f7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/7e849ea9-76b5-4481-8af4-57dd0c1606f7.png -------------------------------------------------------------------------------- /public/uploads/8147285b-d577-43c0-a161-bfdcbb08e1e1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/8147285b-d577-43c0-a161-bfdcbb08e1e1.png -------------------------------------------------------------------------------- /public/uploads/875f2cbc-c88f-4b29-adf6-734530ccbc0e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/875f2cbc-c88f-4b29-adf6-734530ccbc0e.png -------------------------------------------------------------------------------- /public/uploads/87b63bc7-96e2-4982-a47d-c6ea65b8efc3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/87b63bc7-96e2-4982-a47d-c6ea65b8efc3.png -------------------------------------------------------------------------------- /public/uploads/90733c3c-6d6d-4894-8c37-90dc8cf0a816.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/90733c3c-6d6d-4894-8c37-90dc8cf0a816.png -------------------------------------------------------------------------------- /public/uploads/9161c3b8-6daa-4e51-a3f1-f71d597e326d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/9161c3b8-6daa-4e51-a3f1-f71d597e326d.png -------------------------------------------------------------------------------- /public/uploads/94deca3e-6e7d-4efd-8ebd-3755bb723ed0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/94deca3e-6e7d-4efd-8ebd-3755bb723ed0.png -------------------------------------------------------------------------------- /public/uploads/97d41ef4-cc7b-4d20-b1a5-47546288c2a7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/97d41ef4-cc7b-4d20-b1a5-47546288c2a7.png -------------------------------------------------------------------------------- /public/uploads/999bf369-8477-4add-8384-4c4abda1df6a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/999bf369-8477-4add-8384-4c4abda1df6a.png -------------------------------------------------------------------------------- /public/uploads/9bb06850-815d-4834-8a3e-474c9e1d1e6b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/9bb06850-815d-4834-8a3e-474c9e1d1e6b.png -------------------------------------------------------------------------------- /public/uploads/a80ff25a-4a5b-45c2-97b6-2c2a8d31894d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/a80ff25a-4a5b-45c2-97b6-2c2a8d31894d.png -------------------------------------------------------------------------------- /public/uploads/aab9ba5b-3dd9-4f61-9130-00582184beca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/aab9ba5b-3dd9-4f61-9130-00582184beca.png -------------------------------------------------------------------------------- /public/uploads/abb91af5-0edd-4459-a37f-a30cc2e616b0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/abb91af5-0edd-4459-a37f-a30cc2e616b0.png -------------------------------------------------------------------------------- /public/uploads/abf2ae63-7c74-465e-958c-7b39bd43478f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/abf2ae63-7c74-465e-958c-7b39bd43478f.png -------------------------------------------------------------------------------- /public/uploads/b6a65458-8256-402b-9a6b-67c203229de3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/b6a65458-8256-402b-9a6b-67c203229de3.png -------------------------------------------------------------------------------- /public/uploads/b7772814-5698-4902-9d31-6fd10453b673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/b7772814-5698-4902-9d31-6fd10453b673.png -------------------------------------------------------------------------------- /public/uploads/bc982ea5-1909-486d-a7d2-ae591744126c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/bc982ea5-1909-486d-a7d2-ae591744126c.png -------------------------------------------------------------------------------- /public/uploads/cc3a296e-5e6f-40e9-820d-5d49add696d0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/cc3a296e-5e6f-40e9-820d-5d49add696d0.png -------------------------------------------------------------------------------- /public/uploads/cc978f5b-c4a6-4f3c-9242-a2e8b790b9a1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/cc978f5b-c4a6-4f3c-9242-a2e8b790b9a1.png -------------------------------------------------------------------------------- /public/uploads/dc32267f-895c-49f9-a03e-4bb861abeead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/dc32267f-895c-49f9-a03e-4bb861abeead.png -------------------------------------------------------------------------------- /public/uploads/e3f66a31-9000-4cf0-a1cb-44939aa69117.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/e3f66a31-9000-4cf0-a1cb-44939aa69117.png -------------------------------------------------------------------------------- /public/uploads/e8a76490-4fdb-411c-a996-01c3d896e7c0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/e8a76490-4fdb-411c-a996-01c3d896e7c0.png -------------------------------------------------------------------------------- /public/uploads/f0a78892-ca47-4753-a5ff-369674b5e19c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/f0a78892-ca47-4753-a5ff-369674b5e19c.png -------------------------------------------------------------------------------- /public/uploads/f69badfa-94f4-4509-a70c-7338511697a4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/f69badfa-94f4-4509-a70c-7338511697a4.png -------------------------------------------------------------------------------- /public/uploads/f8eec96f-5d65-46b5-9648-b729eb4c54d9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/f8eec96f-5d65-46b5-9648-b729eb4c54d9.png -------------------------------------------------------------------------------- /public/uploads/f985396d-8d7a-4d65-8501-8a4bcad61929.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/f985396d-8d7a-4d65-8501-8a4bcad61929.png -------------------------------------------------------------------------------- /public/uploads/fa48845d-46e4-48e9-a53c-2a41d7488a34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/fa48845d-46e4-48e9-a53c-2a41d7488a34.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-hdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-hdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-hdpi/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-hdpi/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-mdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-mdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-mdpi/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-mdpi/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /src/lib/mock-modules/nodejieba.js: -------------------------------------------------------------------------------- 1 | // 模拟 nodejieba 模块 2 | module.exports = { 3 | cut: function(text) { 4 | // 简单的分词实现,按空格分割 5 | return text.split(/\s+/); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xhdpi/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xhdpi/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxhdpi/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxhdpi/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-xxxhdpi/ic_launcher_monochrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/icon/android/res/mipmap-xxxhdpi/ic_launcher_monochrome.png -------------------------------------------------------------------------------- /public/uploads/contact/05547404-c0cc-4229-bb42-ed4eb28de871.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/contact/05547404-c0cc-4229-bb42-ed4eb28de871.jpeg -------------------------------------------------------------------------------- /public/uploads/contact/3e5464e1-f6cd-4600-b9dc-6f9552547d29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/contact/3e5464e1-f6cd-4600-b9dc-6f9552547d29.png -------------------------------------------------------------------------------- /public/uploads/contact/ca46cdc3-6463-4794-a27b-174aa373f15e.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/contact/ca46cdc3-6463-4794-a27b-174aa373f15e.jpeg -------------------------------------------------------------------------------- /public/uploads/donation/63a278f4-8927-4123-b95c-4dffb5ea7430.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeseesun/qiaomu-blog3/HEAD/public/uploads/donation/63a278f4-8927-4123-b95c-4dffb5ea7430.png -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # 认证相关 2 | NEXTAUTH_SECRET=joe-s 3 | NEXTAUTH_URL=http://localhost:3008 4 | 5 | # JWT密钥(用于管理员登录) 6 | JWT_SECRET=joe-k 7 | 8 | # 上传文件存储路径 9 | UPLOAD_DIR=public/uploads 10 | 11 | # 网站URL(用于生成绝对URL) 12 | NEXT_PUBLIC_SITE_URL=http://localhost:3008 -------------------------------------------------------------------------------- /src/app/api/auth/[...nextauth]/route.ts: -------------------------------------------------------------------------------- 1 | import { authOptions } from '@/auth/options'; 2 | import NextAuth from 'next-auth'; 3 | 4 | // 使用 NextAuth 创建处理程序 5 | const handler = NextAuth(authOptions); 6 | 7 | // 确保导出正确的处理函数 8 | export { handler as GET, handler as POST }; 9 | -------------------------------------------------------------------------------- /src/lib/migrations/meta/_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "5", 3 | "dialect": "sqlite", 4 | "entries": [ 5 | { 6 | "idx": 0, 7 | "when": "1714727482882", 8 | "tag": "0000_init_schema", 9 | "breakpoints": true 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /src/lib/links-db.ts: -------------------------------------------------------------------------------- 1 | // This file is kept for compatibility with existing imports 2 | // The actual database connection is now handled in src/lib/actions/links.ts 3 | 4 | // Placeholder exports to maintain compatibility 5 | export const db = null; 6 | export const sqlite = null; 7 | -------------------------------------------------------------------------------- /src/app/(main)/layout.tsx: -------------------------------------------------------------------------------- 1 | import MainLayout from "@/components/MainLayout"; 2 | 3 | export default function MainAppLayout({ 4 | children, 5 | }: Readonly<{ 6 | children: React.ReactNode; 7 | }>) { 8 | return ( 9 | 10 | {children} 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | qiaomu-blog: 5 | build: . 6 | ports: 7 | - "3000:3000" 8 | volumes: 9 | - ./demo.db:/app/demo.db 10 | - ./public/uploads:/app/public/uploads 11 | restart: unless-stopped 12 | environment: 13 | - NODE_ENV=production 14 | - PORT=3000 15 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # 认证相关 2 | NEXTAUTH_SECRET=your-nextauth-secret 3 | NEXTAUTH_URL=https://your-vercel-url.vercel.app 4 | 5 | # JWT密钥(用于管理员登录) 6 | JWT_SECRET=your-jwt-secret-key 7 | 8 | # 上传文件存储路径 9 | UPLOAD_DIR=public/uploads 10 | 11 | # 数据库连接 12 | DATABASE_URL="file:./demo.db" 13 | 14 | # 网站URL 15 | NEXT_PUBLIC_SITE_URL="https://blog.qiaomu.life" 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine 2 | 3 | WORKDIR /app 4 | 5 | # 复制package.json和package-lock.json 6 | COPY package*.json ./ 7 | 8 | # 安装依赖 9 | RUN npm ci 10 | 11 | # 复制源代码 12 | COPY . . 13 | 14 | # 设置环境变量 15 | ENV NODE_ENV=production 16 | ENV PORT=3000 17 | 18 | # 构建应用 19 | RUN npm run build 20 | 21 | # 暴露端口 22 | EXPOSE 3000 23 | 24 | # 启动命令 25 | CMD ["npm", "start"] 26 | -------------------------------------------------------------------------------- /public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/icon/android/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "buildCommand": "npm run build", 4 | "devCommand": "npm run dev", 5 | "installCommand": "npm install", 6 | "outputDirectory": ".next", 7 | "framework": "nextjs", 8 | "regions": ["hnd1"], 9 | "env": { 10 | "NEXTAUTH_SECRET": "your-nextauth-secret-change-me-in-production", 11 | "JWT_SECRET": "your-jwt-secret-change-me-in-production" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/providers/SessionProvider.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { SessionProvider as NextAuthSessionProvider } from 'next-auth/react'; 4 | import { ReactNode } from 'react'; 5 | 6 | type SessionProviderProps = { 7 | children: ReactNode; 8 | }; 9 | 10 | export function SessionProvider({ children }: SessionProviderProps) { 11 | return {children}; 12 | } -------------------------------------------------------------------------------- /start-dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 设置固定端口 4 | PORT=3099 5 | 6 | # 检查端口是否被占用 7 | pid=$(lsof -ti :$PORT) 8 | if [ ! -z "$pid" ]; then 9 | echo "Port $PORT is in use by process $pid. Killing it..." 10 | kill -9 $pid 11 | fi 12 | 13 | # 清理旧的构建文件 14 | echo "Cleaning..." 15 | rm -rf .next 16 | 17 | # 重新构建项目 18 | echo "Building..." 19 | npm run build 20 | 21 | # 启动服务器 22 | echo "Starting server on port $PORT..." 23 | PORT=$PORT npm run start -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /src/components/AdminCheck.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useState, useEffect } from 'react'; 4 | 5 | // 客户端检查管理员状态 6 | export default function useAdminCheck() { 7 | const [isAdmin, setIsAdmin] = useState(false); 8 | 9 | useEffect(() => { 10 | // 检查cookie中是否有管理员标记 11 | const hasAdminCookie = document.cookie.split(';').some(item => item.trim().startsWith('admin_logged_in=')); 12 | setIsAdmin(hasAdminCookie); 13 | }, []); 14 | 15 | return isAdmin; 16 | } 17 | -------------------------------------------------------------------------------- /src/app/api/admin/stats/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from 'next/server'; 2 | 3 | export interface StatsResponse { 4 | posts: number; 5 | categories: number; 6 | tags: number; 7 | views: number; 8 | recentPosts: any[]; 9 | } 10 | 11 | export async function GET(): Promise> { 12 | // 返回空的统计数据 13 | return NextResponse.json({ 14 | posts: 0, 15 | categories: 0, 16 | tags: 0, 17 | views: 0, 18 | recentPosts: [] 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /src/components/ScriptLoaderWrapper.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import React from 'react'; 4 | import NextScriptLoader from './NextScriptLoader'; 5 | 6 | type ScriptLoaderWrapperProps = { 7 | position: 'head' | 'body_start' | 'body_end'; 8 | }; 9 | 10 | export default function ScriptLoaderWrapper({ position }: ScriptLoaderWrapperProps) { 11 | // Temporarily disabled to troubleshoot navigation menu issues 12 | console.log(`ScriptLoader for ${position} temporarily disabled`); 13 | return null; 14 | } 15 | -------------------------------------------------------------------------------- /public/icons/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | // 通用的Post类型定义 2 | export type Post = { 3 | id: number; 4 | title: string; 5 | slug: string; 6 | excerpt: string | null; 7 | coverImage: string | null; 8 | createdAt: string; 9 | pinned?: number | boolean; 10 | author?: { 11 | id: number; 12 | email: string | null; 13 | }; 14 | category?: { 15 | id: number; 16 | name: string | null; 17 | slug: string | null; 18 | }; 19 | tags?: { 20 | id: number; 21 | name: string; 22 | slug: string; 23 | }[]; 24 | }; 25 | 26 | // 其他类型定义可以在此添加 27 | -------------------------------------------------------------------------------- /ecosystem.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apps: [ 3 | { 4 | name: 'qiaomu-blog', 5 | script: 'npm', 6 | args: 'start', 7 | cwd: './', 8 | instances: 1, 9 | autorestart: true, 10 | watch: false, 11 | max_memory_restart: '500M', 12 | env: { 13 | NODE_ENV: 'production', 14 | PORT: 3009 15 | }, 16 | merge_logs: true, 17 | log_date_format: "YYYY-MM-DD HH:mm:ss Z", 18 | error_file: "./logs/error.log", 19 | out_file: "./logs/output.log" 20 | } 21 | ] 22 | }; 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | /.pnp 4 | .pnp.js 5 | 6 | # testing 7 | /coverage 8 | 9 | # next.js 10 | /.next/ 11 | /out/ 12 | 13 | # production 14 | /build 15 | 16 | # misc 17 | .DS_Store 18 | *.pem 19 | 20 | # debug 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # local env files 26 | .env*.local 27 | 28 | # vercel 29 | .vercel 30 | 31 | # typescript 32 | *.tsbuildinfo 33 | next-env.d.ts 34 | 35 | # database 36 | !demo.db 37 | *.sqlite 38 | *.sqlite3 39 | 40 | # IDE 41 | .idea/ 42 | .vscode/ 43 | demo.db 44 | Send2qiaomu/ 45 | 46 | -------------------------------------------------------------------------------- /src/app/admin/layout.tsx: -------------------------------------------------------------------------------- 1 | import { AdminLayout } from "@/components/admin/layout"; 2 | import type { Metadata } from "next"; 3 | import { SessionProvider } from "@/components/providers/SessionProvider"; 4 | 5 | export const metadata: Metadata = { 6 | title: "博客管理后台 - 向阳乔木的个人博客", 7 | description: "博客管理后台", 8 | }; 9 | 10 | export default function AdminRootLayout({ 11 | children, 12 | }: Readonly<{ 13 | children: React.ReactNode; 14 | }>) { 15 | return ( 16 | 17 | {children} 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /src/components/ScriptLoader.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from 'react'; 4 | 5 | type ScriptLoaderProps = { 6 | position: 'head' | 'body_start' | 'body_end'; 7 | key?: string; 8 | }; 9 | 10 | /** 11 | * 简化版ScriptLoader组件 12 | * 使用 fetchCache = 'force-no-store' 配置代替 dynamic = 'force-dynamic' 13 | * 这种方法在数据获取层面禁用缓存,而不是渲染层面,因此不会与客户端组件冲突 14 | */ 15 | export default function ScriptLoader({ position }: ScriptLoaderProps) { 16 | // 在服务器端渲染时返回null 17 | if (typeof window === 'undefined') { 18 | return null; 19 | } 20 | 21 | // 暂时返回空元素,避免与动态渲染冲突 22 | return null; 23 | } 24 | -------------------------------------------------------------------------------- /src/components/ui/link.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import NextLink from 'next/link'; 4 | import { forwardRef } from 'react'; 5 | 6 | export interface LinkProps extends React.ComponentPropsWithoutRef { 7 | className?: string; 8 | children: React.ReactNode; 9 | } 10 | 11 | export const Link = forwardRef( 12 | ({ className, children, ...props }, ref) => { 13 | return ( 14 | 15 | {children} 16 | 17 | ); 18 | } 19 | ); 20 | 21 | Link.displayName = 'Link'; 22 | -------------------------------------------------------------------------------- /src/app/(frontend)/layout.tsx: -------------------------------------------------------------------------------- 1 | import Navigation from "@/components/Navigation"; 2 | import Footer from "@/components/Footer"; 3 | 4 | export default function FrontendLayout({ 5 | children, 6 | }: { 7 | children: React.ReactNode; 8 | }) { 9 | return ( 10 | <> 11 |
12 | 13 |
14 |
15 | {children} 16 |
17 |