├── .all-contributorsrc ├── LICENSE ├── README.md ├── assets ├── code-nav-doc.png ├── code-nav-home.png ├── code-nav-mini.png ├── code-nav-mp-server.png ├── code-nav-mp.jpg ├── code-nav-recommend.png ├── mind-map.png └── wechat.jpg ├── code-nav-doc ├── .editorconfig ├── .fatherrc.ts ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .umirc.ts ├── README.md ├── docs │ ├── Author │ │ └── index.md │ ├── GitHub │ │ └── index.md │ ├── Guide │ │ ├── captcha.md │ │ ├── feedback.md │ │ ├── index.md │ │ ├── qa.md │ │ └── setNav.md │ ├── Prize │ │ └── index.md │ ├── Project │ │ ├── codeNavDoc.md │ │ ├── codeNavHome.md │ │ ├── codeNavMain.md │ │ ├── codeNavMini.md │ │ ├── codeNavMpServer.md │ │ └── index.md │ ├── Release │ │ └── index.md │ ├── Roadmap │ │ ├── frontend.md │ │ ├── index.md │ │ └── java.md │ ├── assets │ │ ├── code-nav-comment.png │ │ ├── code-nav-detail.png │ │ ├── code-nav-doc.png │ │ ├── code-nav-favour.png │ │ ├── code-nav-home-cover-random.png │ │ ├── code-nav-home-cover.png │ │ ├── code-nav-home-covers.png │ │ ├── code-nav-home-search.png │ │ ├── code-nav-home-searchAll.png │ │ ├── code-nav-home-white.png │ │ ├── code-nav-home.png │ │ ├── code-nav-recommend.png │ │ ├── code-nav-resources.png │ │ ├── login.jpeg │ │ ├── qrcode.jpg │ │ └── wechat.jpg │ └── index.md ├── package.json ├── tsconfig.json └── typings.d.ts ├── code-nav-home ├── .babelrc ├── .editorconfig ├── .env ├── .eslintrc ├── .gitignore ├── LICENSE ├── README.md ├── assets │ ├── code-nav-home-cover-random.png │ ├── code-nav-home-cover.png │ ├── code-nav-home-covers.png │ ├── code-nav-home-search.png │ ├── code-nav-home-searchAll.png │ ├── code-nav-home-white.png │ ├── code-nav-home.png │ └── logo.png ├── cloudbaserc.json ├── covers │ ├── comic │ │ ├── cover_1.jpg │ │ ├── cover_10.jpg │ │ ├── cover_11.jpg │ │ ├── cover_12.jpg │ │ ├── cover_2.jpg │ │ ├── cover_3.jpg │ │ ├── cover_4.jpg │ │ ├── cover_5.jpg │ │ ├── cover_6.jpg │ │ ├── cover_7.jpg │ │ ├── cover_8.jpg │ │ ├── cover_9.jpg │ │ └── preview │ │ │ ├── cover_1.jpg │ │ │ ├── cover_10.jpg │ │ │ ├── cover_11.jpg │ │ │ ├── cover_12.jpg │ │ │ ├── cover_2.jpg │ │ │ ├── cover_3.jpg │ │ │ ├── cover_4.jpg │ │ │ ├── cover_5.jpg │ │ │ ├── cover_6.jpg │ │ │ ├── cover_7.jpg │ │ │ ├── cover_8.jpg │ │ │ └── cover_9.jpg │ ├── dynamic │ │ ├── 02-七彩云雾 │ │ │ ├── LDR_RGB1_0.png │ │ │ ├── dat.gui.min.js │ │ │ ├── index.html │ │ │ ├── preview.jpg │ │ │ └── script.js │ │ ├── 14-炫彩泡泡 │ │ │ ├── css │ │ │ │ └── style.css │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── sketch.min.js │ │ │ └── preview.gif │ │ ├── cover-01 │ │ │ ├── 1.jpg │ │ │ ├── creat picture.html │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── index.js │ │ │ └── preview.jpg │ │ ├── cover-02 │ │ │ ├── index.html │ │ │ ├── particle.js │ │ │ └── preview.jpg │ │ ├── cover-03 │ │ │ ├── image │ │ │ │ ├── gg.jpg │ │ │ │ └── snow.png │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── jquery.min.js │ │ │ │ └── snow.js │ │ │ └── preview.jpg │ │ ├── cover-04 │ │ │ ├── 1.jpg │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── index.js │ │ │ ├── preview.jpg │ │ │ └── shaders │ │ │ │ └── blobsSM40 │ │ │ │ ├── blur_h_bloom.dxs │ │ │ │ ├── combine.dxs │ │ │ │ ├── downsample_eighth_blur_v.dxs │ │ │ │ ├── downsample_quarter.dxs │ │ │ │ └── fade.dxs │ │ ├── cover-05 │ │ │ ├── 1.jpg │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── index.js │ │ │ ├── preview.jpg │ │ │ └── shaders │ │ │ │ └── blobsSM40 │ │ │ │ ├── blur_h_bloom.dxs │ │ │ │ ├── combine.dxs │ │ │ │ ├── downsample_eighth_blur_v.dxs │ │ │ │ ├── downsample_quarter.dxs │ │ │ │ └── fade.dxs │ │ ├── cover-06 │ │ │ ├── O.jpg │ │ │ ├── index.html │ │ │ └── preview.png │ │ ├── cover-07 │ │ │ ├── 1.jpg │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── index.js │ │ │ └── preview.jpg │ │ ├── cover-08 │ │ │ ├── 1.jpg │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── index.js │ │ │ ├── preview.jpg │ │ │ └── shaders │ │ │ │ └── blobsSM40 │ │ │ │ ├── blur_h_bloom.dxs │ │ │ │ ├── combine.dxs │ │ │ │ ├── downsample_eighth_blur_v.dxs │ │ │ │ ├── downsample_quarter.dxs │ │ │ │ └── fade.dxs │ │ ├── cover-09 │ │ │ ├── 1.jpg │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── index.js │ │ │ └── preview.jpg │ │ ├── cover-10 │ │ │ ├── images │ │ │ │ ├── 1.png │ │ │ │ └── Mask.png │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── glUtils.js │ │ │ │ ├── main.js │ │ │ │ └── sylvester.js │ │ │ ├── preview.jpg │ │ │ └── shaders │ │ │ │ └── blobsSM40 │ │ │ │ ├── 17c2a4938150c8cd48d3e8fb072494e164286e08.dxs │ │ │ │ ├── 4cd8da74ae3b96e190fd87440e015e76c32cb805.dxs │ │ │ │ ├── 6a5e0fde4a01ee99d94e166f7d38c5d152f2c1e6.dxs │ │ │ │ ├── 78166c9f658faa0027cb8535eab9195aedb52f98.dxs │ │ │ │ └── 815f979888d7a7d3cb622eee67d445c0fc94469b.dxs │ │ ├── cover-11 │ │ │ ├── 1.jpg │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ └── index.js │ │ │ └── preview.jpg │ │ ├── cover-12 │ │ │ ├── assets │ │ │ │ ├── css │ │ │ │ │ ├── bootstrap.min.css │ │ │ │ │ └── stylesheet.css │ │ │ │ ├── fonts │ │ │ │ │ ├── Adequate-ExtraLight.ttf │ │ │ │ │ ├── MicroExtendFLF-Bold.ttf │ │ │ │ │ ├── MicroExtendFLF-BoldItalic.ttf │ │ │ │ │ ├── MicroExtendFLF-Italic.ttf │ │ │ │ │ └── MicroExtendFLF.ttf │ │ │ │ ├── img │ │ │ │ │ └── bg.jpg │ │ │ │ └── js │ │ │ │ │ ├── app.js │ │ │ │ │ ├── bootstrap.min.js │ │ │ │ │ ├── jquery-3.1.1.min.js │ │ │ │ │ └── particles.min.js │ │ │ ├── index.html │ │ │ └── preview.jpg │ │ ├── fireBlackHole │ │ │ ├── img │ │ │ │ └── 24ac8094-7dc0-40c4-9956-f69c5fb45896.jpg │ │ │ ├── index.html │ │ │ └── preview.png │ │ ├── sakura │ │ │ ├── bg.jpg │ │ │ ├── index.html │ │ │ ├── preview.jpg │ │ │ └── sakura.js │ │ └── stars │ │ │ ├── index.html │ │ │ ├── preview.png │ │ │ └── starBg.js │ ├── interact │ │ ├── 3dCube │ │ │ ├── index.html │ │ │ ├── media │ │ │ │ └── static-cube.png │ │ │ ├── preview.png │ │ │ ├── scripts │ │ │ │ ├── ResizeableTextBox.3.js │ │ │ │ ├── certificate.js │ │ │ │ ├── cuber.min.js │ │ │ │ ├── deviceMotion.js │ │ │ │ ├── divBox.js │ │ │ │ ├── frames.js │ │ │ │ ├── iecss3d.js │ │ │ │ ├── ierenderer.js │ │ │ │ ├── locked.js │ │ │ │ ├── main3.js │ │ │ │ ├── textBox.js │ │ │ │ ├── three.js │ │ │ │ └── tween.r12.js │ │ │ └── styles │ │ │ │ ├── certificate2.css │ │ │ │ ├── cube.css │ │ │ │ └── doodle2.css │ │ ├── 3dPhoto │ │ │ ├── imgs │ │ │ │ ├── img-01.jpg │ │ │ │ ├── img-02.jpg │ │ │ │ ├── img-03.jpg │ │ │ │ ├── img-04.jpg │ │ │ │ ├── img-05.jpg │ │ │ │ ├── img-06.jpg │ │ │ │ ├── img-07.jpg │ │ │ │ ├── img-08.jpg │ │ │ │ └── img-09.jpg │ │ │ ├── index.html │ │ │ └── preview.png │ │ ├── 3dPlane │ │ │ ├── index.html │ │ │ ├── preview.png │ │ │ └── three.min.js │ │ ├── rocket │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── OrbitControls.js │ │ │ │ ├── Tween.min.js │ │ │ │ └── three.js │ │ │ └── preview.png │ │ ├── starCircle │ │ │ ├── css │ │ │ │ └── style.css │ │ │ ├── index.html │ │ │ ├── js │ │ │ │ ├── dat.gui.min.js │ │ │ │ └── index.js │ │ │ └── preview.jpg │ │ └── techHexagon │ │ │ ├── index.html │ │ │ └── preview.png │ ├── pool │ │ ├── cover_1.jpg │ │ ├── cover_10.jpg │ │ ├── cover_11.jpg │ │ ├── cover_12.jpg │ │ ├── cover_2.jpg │ │ ├── cover_3.jpg │ │ ├── cover_4.jpg │ │ ├── cover_5.jpg │ │ ├── cover_6.jpg │ │ ├── cover_7.jpg │ │ ├── cover_8.jpg │ │ ├── cover_9.jpg │ │ └── preview │ │ │ ├── cover_1.jpg │ │ │ ├── cover_10.jpg │ │ │ ├── cover_11.jpg │ │ │ ├── cover_12.jpg │ │ │ ├── cover_2.jpg │ │ │ ├── cover_3.jpg │ │ │ ├── cover_4.jpg │ │ │ ├── cover_5.jpg │ │ │ ├── cover_6.jpg │ │ │ ├── cover_7.jpg │ │ │ ├── cover_8.jpg │ │ │ └── cover_9.jpg │ ├── random │ │ ├── dongman-preview.jpg │ │ ├── fengjing-preview.jpg │ │ ├── meizi-preview.jpg │ │ └── random-preview.jpg │ ├── scenery │ │ ├── cover_1.jpg │ │ ├── cover_10.jpg │ │ ├── cover_11.jpg │ │ ├── cover_12.jpg │ │ ├── cover_2.jpg │ │ ├── cover_3.jpg │ │ ├── cover_4.jpg │ │ ├── cover_5.jpg │ │ ├── cover_6.jpg │ │ ├── cover_7.jpg │ │ ├── cover_8.jpg │ │ ├── cover_9.jpg │ │ └── preview │ │ │ ├── cover_1.jpg │ │ │ ├── cover_10.jpg │ │ │ ├── cover_11.jpg │ │ │ ├── cover_12.jpg │ │ │ ├── cover_2.jpg │ │ │ ├── cover_3.jpg │ │ │ ├── cover_4.jpg │ │ │ ├── cover_5.jpg │ │ │ ├── cover_6.jpg │ │ │ ├── cover_7.jpg │ │ │ ├── cover_8.jpg │ │ │ └── cover_9.jpg │ └── star │ │ ├── cover_1.jpg │ │ ├── cover_10.jpg │ │ ├── cover_11.jpg │ │ ├── cover_12.jpg │ │ ├── cover_2.jpg │ │ ├── cover_3.jpg │ │ ├── cover_4.jpg │ │ ├── cover_5.jpg │ │ ├── cover_6.jpg │ │ ├── cover_7.jpg │ │ ├── cover_8.jpg │ │ ├── cover_9.jpg │ │ └── preview │ │ ├── cover_1.jpg │ │ ├── cover_10.jpg │ │ ├── cover_11.jpg │ │ ├── cover_12.jpg │ │ ├── cover_2.jpg │ │ ├── cover_3.jpg │ │ ├── cover_4.jpg │ │ ├── cover_5.jpg │ │ ├── cover_6.jpg │ │ ├── cover_7.jpg │ │ ├── cover_8.jpg │ │ └── cover_9.jpg ├── package.json ├── public │ ├── baiduAnalyze.js │ ├── favicon.ico │ └── robots.txt ├── src │ ├── App.js │ ├── app.css │ ├── assets │ │ ├── baidu.png │ │ ├── google.png │ │ ├── logo.png │ │ └── qrcode.jpg │ ├── components │ │ └── Router.js │ ├── constant │ │ ├── defaultHome.js │ │ ├── defaultTabPane.js │ │ └── index.js │ ├── index.js │ └── pages │ │ ├── 404.js │ │ ├── ghost.css │ │ ├── index.css │ │ ├── index.jsx │ │ └── search │ │ └── index.jsx └── static.config.js ├── code-nav-main ├── .editorconfig ├── .env ├── .env.test ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── .stylelintrc.js ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── Dockerfile.build ├── README.md ├── assets │ ├── umiButton.png │ └── umiTmp.png ├── baidu │ └── urls.txt ├── cloudbaserc.json ├── cloudfunctions │ ├── .gitignore │ ├── README.md │ ├── comment │ │ ├── addComment │ │ │ └── package.json │ │ ├── reviewComment │ │ │ └── package.json │ │ ├── searchComments │ │ │ └── package.json │ │ └── thumbUpComment │ │ │ └── package.json │ ├── common │ │ ├── getTags │ │ │ └── package.json │ │ ├── parseURL │ │ │ └── package.json │ │ ├── redisService │ │ │ ├── index.js │ │ │ └── package.json │ │ └── sendEmail │ │ │ ├── index.js │ │ │ ├── package.json │ │ │ └── transporter.json │ ├── getCaptcha │ │ └── package.json │ ├── home │ │ └── updateHome │ │ │ ├── index.js │ │ │ └── package.json │ ├── login │ │ └── package.json │ ├── message │ │ ├── addMessage │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── countMyMessages │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── searchMessages │ │ │ ├── index.js │ │ │ └── package.json │ │ └── updateMessage │ │ │ ├── index.js │ │ │ └── package.json │ ├── notice │ │ ├── addNotice │ │ │ ├── index.js │ │ │ └── package.json │ │ └── updateNotice │ │ │ ├── index.js │ │ │ └── package.json │ ├── report │ │ ├── addReport │ │ │ └── package.json │ │ └── reviewReport │ │ │ └── package.json │ ├── resource │ │ ├── addResource │ │ │ └── package.json │ │ ├── addShareNum │ │ │ └── package.json │ │ ├── batchAdd │ │ │ └── package.json │ │ ├── likeResource │ │ │ └── package.json │ │ ├── listRecommendResources │ │ │ └── package.json │ │ ├── refreshResource │ │ │ └── package.json │ │ ├── reviewResource │ │ │ └── package.json │ │ ├── updateResource │ │ │ └── package.json │ │ ├── updateTags │ │ │ └── package.json │ │ └── viewResource │ │ │ ├── index.js │ │ │ └── package.json │ ├── user │ │ ├── doDailyLogin │ │ │ └── package.json │ │ ├── getSimpleUser │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── getUser │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── getUserRank │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── listUserCycleRank │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── listUserTotalRank │ │ │ ├── index.js │ │ │ └── package.json │ │ └── updateUserInterests │ │ │ ├── index.js │ │ │ └── package.json │ ├── userIntroduce │ │ ├── addOrUpdateUserIntroduce │ │ │ └── package.json │ │ ├── searchUserIntroduces │ │ │ ├── index.js │ │ │ └── package.json │ │ └── thumbUpUserIntroduce │ │ │ ├── index.js │ │ │ └── package.json │ └── userScore │ │ ├── addUserScore │ │ ├── index.js │ │ └── package.json │ │ └── countUserScoreRank │ │ ├── index.js │ │ └── package.json ├── config │ ├── config.ts │ ├── defaultSettings.ts │ ├── menu.tsx │ ├── proxy.ts │ └── routes.ts ├── doc │ └── db.md ├── docker │ └── nginx.conf ├── jsconfig.json ├── mock │ └── index.ts ├── package.json ├── public │ ├── logo.png │ └── robots.txt ├── src │ ├── assets │ │ ├── default.jpg │ │ ├── defaultCover.png │ │ ├── logo.png │ │ ├── qrcode.jpg │ │ └── wechat.jpeg │ ├── cardList.less │ ├── components │ │ ├── Authorized │ │ │ ├── Authorized.tsx │ │ │ ├── AuthorizedRoute.tsx │ │ │ ├── CheckPermissions.tsx │ │ │ ├── PromiseRender.tsx │ │ │ ├── Secured.tsx │ │ │ ├── index.tsx │ │ │ └── renderAuthorize.ts │ │ ├── GlobalFooter │ │ │ └── index.tsx │ │ ├── GlobalHeader │ │ │ ├── AvatarDropdown.tsx │ │ │ ├── RightContent.tsx │ │ │ └── index.less │ │ ├── HeaderSearch │ │ │ ├── index.less │ │ │ └── index.tsx │ │ ├── NoAuth │ │ │ └── index.tsx │ │ ├── PicUploader │ │ │ ├── index.less │ │ │ ├── index.tsx │ │ │ └── service.ts │ │ ├── ReportModal │ │ │ └── index.tsx │ │ ├── ResourceCard │ │ │ ├── index.less │ │ │ └── index.tsx │ │ ├── ResourceRejectModal │ │ │ └── index.tsx │ │ ├── SelectTags │ │ │ ├── index.less │ │ │ └── index.tsx │ │ └── TagList │ │ │ ├── index.less │ │ │ └── index.tsx │ ├── constant │ │ ├── categoryMap.ts │ │ ├── index.ts │ │ ├── level.ts │ │ ├── message.ts │ │ ├── reportReasonEnum.ts │ │ ├── reportTypeEnum.ts │ │ └── reviewStatusEnum.ts │ ├── global.less │ ├── global.tsx │ ├── layouts │ │ ├── BasicLayout.less │ │ ├── BasicLayout.tsx │ │ ├── LoadingLayout.tsx │ │ ├── UserLayout.less │ │ └── UserLayout.tsx │ ├── manifest.json │ ├── models │ │ ├── comment.d.ts │ │ ├── connect.d.ts │ │ ├── login.ts │ │ ├── message.d.ts │ │ ├── notice.d.ts │ │ ├── report.d.ts │ │ ├── resource.ts │ │ ├── tag.ts │ │ ├── user.ts │ │ └── userIntroduce.ts │ ├── pages │ │ ├── 404.tsx │ │ ├── AccountCenter │ │ │ ├── MyAddResources │ │ │ │ └── index.tsx │ │ │ ├── MyInfo │ │ │ │ ├── Center.less │ │ │ │ └── index.tsx │ │ │ ├── MyLikeResources │ │ │ │ └── index.tsx │ │ │ ├── MyMessages │ │ │ │ ├── index.tsx │ │ │ │ └── style.less │ │ │ ├── index.tsx │ │ │ └── style.less │ │ ├── AddResource │ │ │ ├── index.tsx │ │ │ └── style.less │ │ ├── AddSucceed │ │ │ ├── index.less │ │ │ └── index.tsx │ │ ├── Friend │ │ │ ├── MyFriendModal │ │ │ │ ├── index.tsx │ │ │ │ └── style.less │ │ │ ├── index.tsx │ │ │ └── style.less │ │ ├── Ranking │ │ │ ├── index.tsx │ │ │ └── style.less │ │ ├── Recommend │ │ │ ├── index.tsx │ │ │ ├── style.less │ │ │ └── utils │ │ │ │ └── utils.less │ │ ├── ResourceDetail │ │ │ ├── components │ │ │ │ ├── CommentList │ │ │ │ │ ├── index.less │ │ │ │ │ └── index.tsx │ │ │ │ └── SimilarResources │ │ │ │ │ └── index.tsx │ │ │ ├── index.less │ │ │ └── index.tsx │ │ ├── Resources │ │ │ ├── TagSelect │ │ │ │ ├── index.less │ │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ └── style.less │ │ ├── ReviewCenter │ │ │ ├── ManageNotice │ │ │ │ └── index.tsx │ │ │ ├── ReviewComment │ │ │ │ └── index.tsx │ │ │ ├── ReviewReport │ │ │ │ └── index.tsx │ │ │ └── ReviewResource │ │ │ │ └── index.tsx │ │ ├── document.ejs │ │ └── user │ │ │ └── login │ │ │ ├── index.less │ │ │ └── index.tsx │ ├── service-worker.js │ ├── services │ │ ├── comment.ts │ │ ├── login.ts │ │ ├── message.ts │ │ ├── notice.ts │ │ ├── report.ts │ │ ├── resource.ts │ │ ├── searchHistory.ts │ │ ├── tag.ts │ │ ├── user.ts │ │ └── userIntroduce.ts │ ├── tcb.js │ ├── typings.d.ts │ └── utils │ │ ├── Authorized.ts │ │ ├── authority.ts │ │ ├── businessUtils.ts │ │ ├── request.ts │ │ ├── utils.less │ │ ├── utils.test.ts │ │ └── utils.ts └── tsconfig.json └── code-nav-mp-server ├── .gitignore ├── Dockerfile ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src └── main ├── java └── com │ └── codenav │ └── mp │ └── server │ ├── MyApplication.java │ ├── bean │ └── WxMsgRouter.java │ ├── constant │ └── CommonConstant.java │ ├── controller │ └── WxController.java │ ├── handler │ ├── LoginHandler.java │ ├── MessageHandler.java │ └── SubscribeHandler.java │ ├── model │ ├── GetCaptchaResponse.java │ └── UserInfo.java │ ├── service │ ├── CommonService.java │ └── CommonServiceImpl.java │ └── utils │ └── HttpUtils.java └── resources ├── application-dev.properties ├── application-prod.properties ├── application.properties └── logback.xml /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 编程导航 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/code-nav-doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/code-nav-doc.png -------------------------------------------------------------------------------- /assets/code-nav-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/code-nav-home.png -------------------------------------------------------------------------------- /assets/code-nav-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/code-nav-mini.png -------------------------------------------------------------------------------- /assets/code-nav-mp-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/code-nav-mp-server.png -------------------------------------------------------------------------------- /assets/code-nav-mp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/code-nav-mp.jpg -------------------------------------------------------------------------------- /assets/code-nav-recommend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/code-nav-recommend.png -------------------------------------------------------------------------------- /assets/mind-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/mind-map.png -------------------------------------------------------------------------------- /assets/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/assets/wechat.jpg -------------------------------------------------------------------------------- /code-nav-doc/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /code-nav-doc/.fatherrc.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | esm: 'rollup', 3 | cjs: 'rollup', 4 | }; 5 | -------------------------------------------------------------------------------- /code-nav-doc/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | /docs-dist 13 | 14 | # misc 15 | .DS_Store 16 | 17 | # umi 18 | .umi 19 | .umi-production 20 | .umi-test 21 | .env.local 22 | 23 | # ide 24 | /.vscode 25 | /.idea 26 | 27 | .vercel 28 | -------------------------------------------------------------------------------- /code-nav-doc/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.svg 2 | **/*.ejs 3 | **/*.html 4 | package.json 5 | .umi 6 | .umi-production 7 | .umi-test 8 | -------------------------------------------------------------------------------- /code-nav-doc/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /code-nav-doc/.umirc.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'dumi'; 2 | 3 | export default defineConfig({ 4 | title: '编程导航', 5 | favicon: 'https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/logo.png', 6 | logo: 'https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/logo.png', 7 | outputPath: 'docs-dist', 8 | mode: 'site', 9 | analytics: { 10 | baidu: 'eb44917eec45fb8f09c3ae111c5e62bc', 11 | }, 12 | metas: [ 13 | { 14 | name: 'keywords', 15 | content: '编程,程序员,导航,编程资源,自学编程,编程导航,编程学习' 16 | }, 17 | { 18 | name: 'description', 19 | content: '编程导航文档,最专业的程序员导航网站,发现优质编程学习资源,定制你的程序员必备主页,公众号编程导航' 20 | }, 21 | ], 22 | }); 23 | -------------------------------------------------------------------------------- /code-nav-doc/README.md: -------------------------------------------------------------------------------- 1 | # 编程导航文档 2 | 3 | [在线访问](https://doc.code-nav.cn) 4 | 5 | 编程导航项目的使用指南和详细介绍。 6 | 7 | ## 项目展示 8 | 9 | 主页 10 | 11 | ![编程导航文档主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-doc.png) 12 | 13 | ## 快速开始 14 | 15 | **请保证 Node.js 版本 > 10** ⚠️ 16 | 17 | 1. 下载项目到本地 18 | 19 | ```bash 20 | git clone https://github.com/liyupi/code-nav.git 21 | ``` 22 | 23 | 2. 进入目录,安装依赖 24 | 25 | ```bash 26 | cd code-nav-doc 27 | npm install 28 | ``` 29 | 30 | 3. 本地启动项目 31 | 32 | ```bash 33 | npm run start 34 | ``` 35 | 36 | 4. 打包构建 37 | 38 | ```bash 39 | npm run docs:build 40 | ``` 41 | 42 | 会生成 `docs-dist` 目录,可以通过 [serve 工具](https://www.npmjs.com/package/serve) 本地启动 server 快速浏览。 43 | 44 | 5. 部署 45 | 46 | 利用腾讯云静态站点托管:可以直接将 `docs-dist` 目录发布到 [静态站点托管](https://cloud.tencent.com/document/product/876/46900) 中,有 CDN 支持 47 | 48 | ```bash 49 | tcb hosting deploy . -e envId 50 | ``` 51 | 52 | ## 技术选型 53 | 54 | ### 前端 55 | 56 | 基于 [dumi](https://d.umijs.org/zh-CN) 文档生成工具 57 | 58 | ### 后端 59 | 60 | 1. [腾讯云云存储](https://cloud.tencent.com/document/product/876/19352) 存放图片,CDN 加速 61 | 2. [Vercel](https://vercel.com/) 部署静态文档网站 62 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Author/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: 作者 4 | path: /author 5 | order: 6 6 | toc: menu 7 | --- 8 | 9 | # 关于作者 10 | 11 | 您好,我是鱼皮,一名正在腾讯打工的全栈工程师,致力技术分享。 12 | 13 | 全网昵称:程序员鱼皮 14 | 15 | [我的 GitHub](https://github.com/liyupi/code-nav) 16 | 17 | 我的微信公众号 - 程序员鱼皮 18 | 19 | ![](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/yupi_wechat.png) 20 | 21 | ## 联系作者 22 | 23 | 项目贡献、合作共进、交个朋友,戳作者微信叭,请备注来意!(上班比较忙未及时回复还请见谅) 24 | 25 | **编程导航微信** 26 | 27 | ![编程导航微信](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/code-nav-wechat.jpeg) 28 | 29 | **编程导航公众号** 30 | 31 | ![编程导航公众号](https://qiniuyun.code-nav.cn/qrcode_for_gh_885a2912dab4_430(2).jpg) 32 | 33 | 34 | -------------------------------------------------------------------------------- /code-nav-doc/docs/GitHub/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: GitHub 4 | path: https://github.com/liyupi/code-nav 5 | order: 7 6 | --- 7 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Guide/captcha.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: menu 3 | order: 1 4 | --- 5 | 6 | # 获取动态码 7 | 8 | 动态码用于登录编程导航、永久解锁主页模板等。 9 | 10 | **1. 扫码关注微信公众号『 编程导航 』** 11 | 12 | ![编程导航二维码](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/qrcode.jpg) 13 | 14 | **2. 在公众号内点击 "一键登录" 或回复 "登录" 获取** 15 | 16 | 如果点了后没反应,请再点一次 😢 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Guide/feedback.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: menu 3 | order: 5 4 | --- 5 | 6 | # 意见反馈 7 | 8 | 欢迎 [联系作者](/author) 或 [直接提交产品反馈意见](https://support.qq.com/products/303921) 9 | 10 | 感之不尽! 11 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Guide/qa.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: menu 3 | order: 3 4 | --- 5 | 6 | # QA 7 | 8 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Guide/setNav.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: menu 3 | order: 2 4 | --- 5 | 6 | # 设置主页 7 | 8 | ## Chrome 9 | 10 | [请参考这篇文章](https://zhidao.baidu.com/question/694090304443706004.html) 11 | 12 | ## Firefox 火狐 13 | 14 | [请参考这篇文章](https://support.mozilla.org/zh-CN/kb/%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E4%B8%BB%E9%A1%B5) 15 | 16 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Prize/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: 激励 4 | path: /prize 5 | order: 5 6 | toc: menu 7 | --- 8 | 9 | # 激励 10 | 11 | 好的编程生态需要大家的共同努力!⛽️️ 12 | 13 | 为鼓励大家分享编程资源,我们设定了积分等级系统,可以通过如下途径获取积分,达到指定等级后可以领取对应奖励。 14 | 15 | 也期待有更多志同道合的朋友加入项目团队或贡献。 16 | 您的大名将会出现在致谢名单中、收获更多积分、专属称号、可在简历中写上项目、得到更多的资源和流量扶持等。 17 | 最关键的是,能提升技术实力! 18 | 19 | 20 | 21 | ## 获取积分 22 | 23 | - 每日登录 +1 24 | - 推荐资源 +5 25 | - 发表评论 +1 26 | - 举报资源 +2 27 | - 首次填写自我介绍 +5 28 | 29 | 30 | ## 等级特权 31 | 32 | > 奖励请联系微信:liyupi66 领取 33 | 34 | | 等级 | 需要积分 | 特权 | 35 | | ---- | -------- | -------- | 36 | | 1 | 0 | 无 | 37 | | 2 | 30 | 无 | 38 | | 3 | 100 | 暂无 | 39 | | 4 | 200 | 领取称号 | 40 | | 5 | 500 | 红包 🧧 | 41 | | 6 | 1000 | 红包 🧧🧧 | 42 | | 7 | 2000 | 红包 🧧🧧🧧 | 43 | | 8 | 5000 | 暂无 | 44 | | 9 | 10000 | 暂无 | 45 | | 10 | 30000 | 暂无 | 46 | 47 | 48 | 49 | ## 贡献方式 50 | 51 | 目前有下面几种贡献方式,欢迎 [联系作者](./author) 进行贡献! 52 | 53 | 1. 推荐资源 54 | 2. 积极推广 55 | 3. 成为某类资源版主 56 | 4. [提交产品反馈意见](https://support.qq.com/products/303921) 57 | 58 | 59 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Project/codeNavDoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: menu 3 | --- 4 | 5 | # 编程导航文档 6 | 7 | [在线访问](https://doc.code-nav.cn) 8 | 9 | 编程导航项目的使用指南和详细介绍。 10 | 11 | ## 项目展示 12 | 13 | 文档主页 14 | 15 | ![编程导航文档主页](https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/assets/code-nav-doc.png) 16 | 17 | 阅读文档 18 | 19 | ![阅读文档](https://qiniuyun.code-nav.cn/%E9%98%85%E8%AF%BB%E6%96%87%E6%A1%A3.png) 20 | 21 | 22 | ## 快速开始 23 | 24 | **请保证 Node.js 版本 > 10** ⚠️ 25 | 26 | 1. 下载项目到本地 27 | 28 | ```bash 29 | git clone https://github.com/liyupi/code-nav.git 30 | ``` 31 | 32 | 2. 进入目录,安装依赖 33 | 34 | ```bash 35 | cd code-nav-doc 36 | npm install 37 | ``` 38 | 39 | 3. 本地启动项目 40 | 41 | ```bash 42 | npm run start 43 | ``` 44 | 45 | 4. 打包构建 46 | 47 | ```bash 48 | npm run docs:build 49 | ``` 50 | 51 | 会生成 `docs-dist` 目录,可以通过 [serve 工具](https://www.npmjs.com/package/serve) 本地启动 server 快速浏览。 52 | 53 | 5. 部署 54 | 55 | 利用腾讯云静态站点托管:可以直接将 `docs-dist` 目录发布到 [静态站点托管](https://cloud.tencent.com/document/product/876/46900) 中,有 CDN 支持 56 | 57 | ```bash 58 | tcb hosting deploy . -e envId 59 | ``` 60 | 61 | ## 技术选型 62 | 63 | ### 前端 64 | 65 | 基于 [dumi](https://d.umijs.org/zh-CN) 文档生成工具 66 | 67 | ### 后端 68 | 69 | 1. [腾讯云云存储](https://cloud.tencent.com/document/product/876/19352) 存放图片,CDN 加速 70 | 2. [Vercel](https://vercel.com/) 部署静态文档网站 71 | 72 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Project/codeNavMini.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: menu 3 | --- 4 | 5 | # 编程导航小程序 6 | 7 | 方便用户在微信中直接搜索编程资源、浏览优质编程资源推荐文章。 8 | 9 | **扫码在线体验:** 10 | 11 | ![](https://qiniuyun.code-nav.cn/gh_5532199b4db0_430-20210527001904645.jpg) 12 | 13 | 14 | 15 | ## 已有功能 16 | 17 | ### 主页 18 | 19 | **分类浏览资源** 20 | 21 | 支持按照热榜、编程语言、方向等分类浏览资源。 22 | 23 | 24 | 25 | **查看优质资源推荐文章** 26 | 27 | 主页大图轮播【编程导航】公众号中发布过的优质资源推荐文章,点击可直接跳转至公众号文章。 28 | 29 | ![小程序主页](https://qiniuyun.code-nav.cn/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%B8%BB%E9%A1%B5.png) 30 | 31 | 32 | 33 | **搜索资源** 34 | 35 | ![搜索资源](https://qiniuyun.code-nav.cn/%E6%90%9C%E7%B4%A2%E8%B5%84%E6%BA%90.png) 36 | 37 | 38 | 39 | **查看资源详情** 40 | 41 | ![资源详情页](https://qiniuyun.code-nav.cn/%E8%B5%84%E6%BA%90%E8%AF%A6%E6%83%85%E9%A1%B5.png) 42 | 43 | 44 | 45 | **复制资源链接** 46 | 47 | ![复制链接](https://qiniuyun.code-nav.cn/%E5%A4%8D%E5%88%B6%E9%93%BE%E6%8E%A5.png) 48 | 49 | 50 | 51 | **资源分享** 52 | 53 | ![资源分享](https://qiniuyun.code-nav.cn/%E8%B5%84%E6%BA%90%E5%88%86%E4%BA%AB.png) 54 | 55 | 56 | 57 | ## 技术选型 58 | 59 | ### 前端 60 | 61 | 1. Uniapp(Vue)框架 62 | 2. uview-ui 组件库 63 | 64 | 65 | 66 | 67 | ### 后端 68 | 69 | 使用 [腾讯云云开发](https://cloud.tencent.com/product/tcb),打通已有 Web 项目的云开发环境,共享云数据库、云函数、云存储等资源。 70 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Project/codeNavMpServer.md: -------------------------------------------------------------------------------- 1 | --- 2 | toc: menu 3 | --- 4 | 5 | # 微信公众号服务端 6 | 7 | 对接编程导航公众号,提供获取动态码、关注回复、动态菜单等功能。 8 | 9 | 10 | ## 已有功能 11 | 12 | **关注后回复消息** 13 | 14 | **收到消息后回复消息** 15 | 16 | ![公众号回复消息](https://qiniuyun.code-nav.cn/%E5%85%AC%E4%BC%97%E5%8F%B7%E5%9B%9E%E5%A4%8D%E6%B6%88%E6%81%AF.png) 17 | 18 | **自定义菜单项** 19 | 20 | **点击菜单获取动态码** 21 | 22 | ![](https://qiniuyun.code-nav.cn/%E5%85%AC%E4%BC%97%E5%8F%B7%E4%B8%80%E9%94%AE%E7%99%BB%E5%BD%95-20210527012441318.png) 23 | 24 | 25 | 26 | 27 | 28 | ## 快速开始 29 | 30 | 1. 下载项目 31 | 32 | 2. 使用 IDEA 打开项目,修改 `resources/application` 文件的公众号配置,进入公众号后台获取: 33 | 34 | ```properties 35 | wx.mp.appId= 36 | wx.mp.secret= 37 | wx.mp.token= 38 | wx.mp.aesKey= 39 | ``` 40 | 41 | 3. 使用 Maven `spring-boot:build-image` 构建,在 target 目录下能看到生成的 jar 包 42 | 43 | 4. 可以在服务器启动 jar 包,或直接用 Dockerfile 构建镜像部署在容器中(推荐腾讯云云托管) 44 | 45 | 46 | 47 | ## 技术选型 48 | 49 | 1. Java 编程语言 50 | 2. [WxJava](https://github.com/Wechat-Group/WxJava) 微信公众号后台开发类库 51 | 3. SpringBoot 52 | 4. Maven 包管理 53 | 5. 腾讯云开发云函数 54 | 6. 腾讯云开发云托管部署 55 | 7. Logback 日志 56 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Project/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: 项目 4 | path: /project 5 | order: 3 6 | toc: menu 7 | order: 0 8 | --- 9 | 10 | # 项目 11 | 12 | 编程导航不仅仅是一个项目,而是以 "帮助大家发现优质编程资源,提升效率" 为目标的完整生态。 13 | 14 | 下面介绍编程导航生态的整体技术选型,以及每个子项目的技术架构和本地运行构建方式,便于大家学习,**甚至可以直接轻松地自行搭建类似站点!** 15 | 16 | 17 | ## 整体技术选型 18 | 19 | 项目前端采用 React 框架,后端全量上腾讯云,充分利用云开发提供的云函数、云数据库、云存储、静态站点 CDN、云托管动态扩缩容等能力。 20 | 21 | 22 | ## 子项目 23 | 24 | > 点击下方标题链接查看子项目详情 25 | 26 | 27 | 1. [编程导航主站](project/code-nav-main) 🔍 28 | 29 | 发现优质编程学习资源。可以检索自己需要的资源、分享好的资源,并对他人推荐的资源进行评价。好的资源会被更多人发现,让更多同学感受到技术带来的美好。 30 | 31 | 2. [编程导航主页](project/code-nav-home) 🏡 32 | 33 | 极简的浏览器主页,支持万能搜索,提升效率,还可以定制壁纸和主页站点。 34 | 35 | 3. [编程导航文档](project/code-nav-doc) 📚 36 | 37 | 编程导航项目的使用指南和详细介绍。 38 | 39 | 4. [微信公众号服务端](project/code-nav-mp-server) 💻 40 | 41 | 对接编程导航公众号,提供获取动态码、关注回复、动态菜单等功能。 42 | 43 | 5. 编程导航微信公众号 44 | 45 | 定期分享、介绍和评测优质编程资源,不要错过! 46 | 47 | 扫码关注: 48 | 49 | ![扫码关注](../assets/qrcode.jpg) 50 | 51 | 6. [编程导航小程序](project/code-nav-mini) 52 | 53 | 方便用户在微信中直接搜索编程资源、浏览优质编程资源推荐文章。 54 | 55 | 扫码体验: 56 | 57 | ![扫码在线体验](https://qiniuyun.code-nav.cn/gh_5532199b4db0_430-20210527001904645.jpg) 58 | 59 | ## 全部功能 60 | 61 | 一张思维导图足矣。 62 | 63 | ![](https://qiniuyun.code-nav.cn/%E7%BC%96%E7%A8%8B%E5%AF%BC%E8%88%AA%E6%89%80%E6%9C%89%E5%8A%9F%E8%83%BD%E6%A2%B3%E7%90%86.png) 64 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Release/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: 更新日志 4 | path: https://github.com/liyupi/code-nav/releases/ 5 | order: 10 6 | --- 7 | 8 | ## Foo 9 | 10 | Demo: 11 | 12 | More skills for writing demo: https://d.umijs.org/guide/demo-principle 13 | -------------------------------------------------------------------------------- /code-nav-doc/docs/Roadmap/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | nav: 3 | title: 路线 4 | path: /roadmap 5 | order: 2 6 | toc: menu 7 | order: 0 8 | --- 9 | 10 | # 学习路线 11 | 12 | - [前端学习路线](roadmap/frontend) 13 | - [Java 学习路线](roadmap/java) 14 | -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-comment.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-detail.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-doc.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-favour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-favour.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-home-cover-random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-home-cover-random.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-home-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-home-cover.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-home-covers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-home-covers.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-home-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-home-search.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-home-searchAll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-home-searchAll.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-home-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-home-white.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-home.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-recommend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-recommend.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/code-nav-resources.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/code-nav-resources.png -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/login.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/login.jpeg -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/qrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/qrcode.jpg -------------------------------------------------------------------------------- /code-nav-doc/docs/assets/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-doc/docs/assets/wechat.jpg -------------------------------------------------------------------------------- /code-nav-doc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "code-nav-doc", 4 | "version": "1.0.0", 5 | "scripts": { 6 | "start": "dumi dev", 7 | "docs:build": "dumi build", 8 | "docs:deploy": "gh-pages -d docs-dist", 9 | "build": "father-build", 10 | "deploy": "npm run docs:build && npm run docs:deploy", 11 | "release": "npm run build && npm publish", 12 | "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", 13 | "test": "umi-test", 14 | "test:coverage": "umi-test --coverage" 15 | }, 16 | "main": "dist/index.js", 17 | "module": "dist/index.esm.js", 18 | "typings": "dist/index.d.ts", 19 | "gitHooks": { 20 | "pre-commit": "lint-staged" 21 | }, 22 | "lint-staged": { 23 | "*.{js,jsx,less,md,json}": [ 24 | "prettier --write" 25 | ], 26 | "*.ts?(x)": [ 27 | "prettier --parser=typescript --write" 28 | ] 29 | }, 30 | "dependencies": { 31 | "@umijs/plugin-analytics": "^0.2.2", 32 | "react": "^16.12.0" 33 | }, 34 | "devDependencies": { 35 | "@umijs/test": "^3.0.5", 36 | "dumi": "^1.1.2", 37 | "father-build": "^1.19.1", 38 | "gh-pages": "^3.0.0", 39 | "lint-staged": "^10.0.7", 40 | "prettier": "^1.19.1", 41 | "yorkie": "^2.0.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /code-nav-doc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "jsx": "react", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "baseUrl": "./", 11 | "strict": true, 12 | "paths": { 13 | "@/*": ["src/*"], 14 | "@@/*": ["src/.umi/*"] 15 | }, 16 | "allowSyntheticDefaultImports": true 17 | }, 18 | "exclude": [ 19 | "node_modules", 20 | "lib", 21 | "es", 22 | "dist", 23 | "typings", 24 | "**/__test__", 25 | "test", 26 | "docs", 27 | "tests" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /code-nav-doc/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | -------------------------------------------------------------------------------- /code-nav-home/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-static/babel-preset.js"] 3 | } 4 | -------------------------------------------------------------------------------- /code-nav-home/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /code-nav-home/.env: -------------------------------------------------------------------------------- 1 | ENV_ID=你的云开发环境ID 2 | -------------------------------------------------------------------------------- /code-nav-home/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "react-app" 3 | } 4 | -------------------------------------------------------------------------------- /code-nav-home/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | tmp 4 | artifacts 5 | 6 | # dependencies 7 | **/node_modules 8 | # roadhog-api-doc ignore 9 | /src/utils/request-temp.js 10 | _roadhog-api-doc 11 | 12 | # production 13 | /dist 14 | /.vscode 15 | 16 | # misc 17 | .DS_Store 18 | npm-debug.log* 19 | yarn-error.log 20 | 21 | /coverage 22 | .idea 23 | yarn.lock 24 | package-lock.json 25 | *bak 26 | .vscode 27 | 28 | # visual studio code 29 | .history 30 | *.log 31 | functions/* 32 | .temp/** 33 | 34 | # umi 35 | .umi 36 | .umi-production 37 | 38 | # screenshot 39 | screenshot 40 | .firebase 41 | .eslintcache 42 | 43 | build 44 | -------------------------------------------------------------------------------- /code-nav-home/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 编程导航 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /code-nav-home/assets/code-nav-home-cover-random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/code-nav-home-cover-random.png -------------------------------------------------------------------------------- /code-nav-home/assets/code-nav-home-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/code-nav-home-cover.png -------------------------------------------------------------------------------- /code-nav-home/assets/code-nav-home-covers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/code-nav-home-covers.png -------------------------------------------------------------------------------- /code-nav-home/assets/code-nav-home-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/code-nav-home-search.png -------------------------------------------------------------------------------- /code-nav-home/assets/code-nav-home-searchAll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/code-nav-home-searchAll.png -------------------------------------------------------------------------------- /code-nav-home/assets/code-nav-home-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/code-nav-home-white.png -------------------------------------------------------------------------------- /code-nav-home/assets/code-nav-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/code-nav-home.png -------------------------------------------------------------------------------- /code-nav-home/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/assets/logo.png -------------------------------------------------------------------------------- /code-nav-home/cloudbaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "envId": "{{env.ENV_ID}}", 3 | "$schema": "https://framework-1258016615.tcloudbaseapp.com/schema/latest.json", 4 | "version": "2.0", 5 | "framework": { 6 | "name": "code-nav-home", 7 | "plugins": { 8 | "client": { 9 | "use": "@cloudbase/framework-plugin-website", 10 | "inputs": { 11 | "buildCommand": "npm run build", 12 | "outputPath": "dist" 13 | } 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/comic/preview/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/comic/preview/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/02-七彩云雾/LDR_RGB1_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/02-七彩云雾/LDR_RGB1_0.png -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/02-七彩云雾/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/02-七彩云雾/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/14-炫彩泡泡/css/style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | 3 | background: #f2f2f2; 4 | overflow: hidden; 5 | margin: 0; 6 | } 7 | -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/14-炫彩泡泡/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/14-炫彩泡泡/preview.gif -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-01/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-01/1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-01/creat picture.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 创建图片 7 | 8 | 9 | 10 | 无法显示 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-01/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-01/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-02/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-02/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-03/image/gg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-03/image/gg.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-03/image/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-03/image/snow.png -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-03/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 雪花初音 8 | 9 | 10 | 11 | 12 | 13 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-03/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-03/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-04/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-04/1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-04/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-04/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/blur_h_bloom.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/blur_h_bloom.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/combine.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/combine.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_eighth_blur_v.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_eighth_blur_v.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_quarter.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/downsample_quarter.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/fade.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-04/shaders/blobsSM40/fade.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-05/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-05/1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-05/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-05/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/blur_h_bloom.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/blur_h_bloom.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/combine.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/combine.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_eighth_blur_v.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_eighth_blur_v.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_quarter.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/downsample_quarter.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/fade.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-05/shaders/blobsSM40/fade.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-06/O.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-06/O.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-06/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-06/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-07/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-07/1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-07/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-07/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-08/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-08/1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-08/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-08/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/blur_h_bloom.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/blur_h_bloom.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/combine.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/combine.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_eighth_blur_v.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_eighth_blur_v.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_quarter.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/downsample_quarter.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/fade.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-08/shaders/blobsSM40/fade.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-09/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-09/1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-09/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-09/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/images/1.png -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/images/Mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/images/Mask.png -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/17c2a4938150c8cd48d3e8fb072494e164286e08.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/17c2a4938150c8cd48d3e8fb072494e164286e08.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/4cd8da74ae3b96e190fd87440e015e76c32cb805.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/4cd8da74ae3b96e190fd87440e015e76c32cb805.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/6a5e0fde4a01ee99d94e166f7d38c5d152f2c1e6.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/6a5e0fde4a01ee99d94e166f7d38c5d152f2c1e6.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/78166c9f658faa0027cb8535eab9195aedb52f98.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/78166c9f658faa0027cb8535eab9195aedb52f98.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/815f979888d7a7d3cb622eee67d445c0fc94469b.dxs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-10/shaders/blobsSM40/815f979888d7a7d3cb622eee67d445c0fc94469b.dxs -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-11/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-11/1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-11/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-11/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/assets/css/stylesheet.css: -------------------------------------------------------------------------------- 1 | @font-face { font-family: "Digital"; src: url('../fonts/Adequate-ExtraLight.ttf'); } 2 | @font-face { font-family: "Micro"; src: url('../fonts/MicroExtendFLF.ttf'); } 3 | body { 4 | background-image: url(../img/bg.jpg); 5 | background-size: cover; 6 | background-position: top center; 7 | background-color:#FFF; 8 | } 9 | 10 | .content { 11 | display: absolute; 12 | width: 100%; 13 | top: 0; 14 | left: 0; 15 | display: table; 16 | vertical-align: middle; 17 | height: 100vh; 18 | } 19 | 20 | .content .inner { 21 | display:table-cell; 22 | vertical-align: middle; 23 | font-family: "Muli-Light"; 24 | } 25 | .time, .date, .seconds { 26 | font-family: "Micro"; 27 | color:#FFF; 28 | } 29 | .timeblock { 30 | margin: 0 auto; 31 | border: solid 1px rgba(255,255,255,0.5); 32 | line-height: 100px; 33 | border-radius: 300px; 34 | padding-top: 110px; 35 | width: 300px; 36 | height: 300px; 37 | box-shadow: inset 0 0 30px rgba(255,255,255,0.5); 38 | 39 | } 40 | #particles-js{ 41 | position: fixed; 42 | top: 0; 43 | left: 0; 44 | right: 0; 45 | bottom: 0; 46 | } 47 | -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/assets/fonts/Adequate-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-12/assets/fonts/Adequate-ExtraLight.ttf -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Bold.ttf -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-BoldItalic.ttf -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF-Italic.ttf -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-12/assets/fonts/MicroExtendFLF.ttf -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/assets/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-12/assets/img/bg.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 编程导航 - 雪之仙境 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/cover-12/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/cover-12/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/fireBlackHole/img/24ac8094-7dc0-40c4-9956-f69c5fb45896.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/fireBlackHole/img/24ac8094-7dc0-40c4-9956-f69c5fb45896.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/fireBlackHole/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/fireBlackHole/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/sakura/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/sakura/bg.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/sakura/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 编程导航 - 樱花飞舞 7 | 8 | 9 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/sakura/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/sakura/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/stars/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 编程导航 - 满天繁星 7 | 8 | 9 | 16 | 17 | 18 | 您的浏览器不支持 canvas,请更换浏览器! 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /code-nav-home/covers/dynamic/stars/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/dynamic/stars/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dCube/media/static-cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dCube/media/static-cube.png -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dCube/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dCube/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dCube/scripts/divBox.js: -------------------------------------------------------------------------------- 1 | DivBox = function(cube, name){ 2 | THREE.Object3D.call( this ); 3 | this.cube = cube; 4 | this.name = name; 5 | this.cube.object3D.add( this ); 6 | var domElement = document.createElement( 'div' ); 7 | domElement.classList.add( 'DivBox' ); 8 | domElement.id = name; 9 | this.css3DObject = new THREE.CSS3DObject( domElement ); 10 | this.css3DObject.name = 'css3DObject-' + name; 11 | this.add( this.css3DObject ); 12 | } 13 | DivBox.prototype = Object.create( THREE.Object3D.prototype ); 14 | ERNO.extend( DivBox.prototype, { 15 | setText: function(text){ 16 | this.css3DObject.element.innerHTML = text; 17 | this.text = text; 18 | return this; 19 | }, 20 | setOpacity: function(opacity){ 21 | this.opacity = opacity; 22 | this.css3DObject.element.style.opacity = opacity; 23 | return this; 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dCube/scripts/textBox.js: -------------------------------------------------------------------------------- 1 | TextBox = function(cube, name, text, min, max){ 2 | THREE.Object3D.call( this ); 3 | this.cube = cube; 4 | this.name = name; 5 | this.text = text; 6 | this.opacity = 1.0; 7 | this.cube.object3D.add( this ); 8 | var domElement = document.createElement( 'div' ); 9 | domElement.classList.add( 'textBox' ); 10 | domElement.id = name; 11 | this.css3DObject = new THREE.CSS3DObject( domElement ); 12 | domElement.innerHTML = text; 13 | this.css3DObject.name = 'css3DObject-' + name; 14 | this.domElement = domElement; 15 | this.add( this.css3DObject ); 16 | } 17 | TextBox.prototype = Object.create( THREE.Object3D.prototype ); 18 | ERNO.extend( TextBox.prototype, { 19 | setText: function(text){ 20 | this.css3DObject.element.innerHTML = text; 21 | this.text = text; 22 | return this; 23 | }, 24 | setOpacity: function(opacity){ 25 | this.opacity = opacity; 26 | this.css3DObject.element.style.opacity = opacity; 27 | return this; 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-01.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-02.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-03.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-04.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-05.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-06.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-07.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-08.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/imgs/img-09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/imgs/img-09.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPhoto/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPhoto/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/interact/3dPlane/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/3dPlane/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/interact/rocket/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/rocket/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/interact/starCircle/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | 3 | overflow: hidden; 4 | } 5 | canvas { 6 | 7 | position: absolute; 8 | top: 0; 9 | left: 0; 10 | background-color: black; 11 | } 12 | 13 | a { 14 | 15 | width: 200px; 16 | height: 200px; 17 | position: absolute; 18 | left: calc( 100% - 200px ); 19 | top: calc( 100% - 130px ); 20 | } 21 | img { 22 | width: 200px; 23 | } -------------------------------------------------------------------------------- /code-nav-home/covers/interact/starCircle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 编程导航 - 星空之环 8 | 9 | 10 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /code-nav-home/covers/interact/starCircle/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/starCircle/preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/interact/techHexagon/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/interact/techHexagon/preview.png -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/pool/preview/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/pool/preview/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/random/dongman-preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/random/dongman-preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/random/fengjing-preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/random/fengjing-preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/random/meizi-preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/random/meizi-preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/random/random-preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/random/random-preview.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/scenery/preview/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/scenery/preview/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_1.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_10.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_11.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_12.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_2.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_3.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_4.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_5.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_6.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_7.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_8.jpg -------------------------------------------------------------------------------- /code-nav-home/covers/star/preview/cover_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/covers/star/preview/cover_9.jpg -------------------------------------------------------------------------------- /code-nav-home/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-static-example-basic", 3 | "private": true, 4 | "scripts": { 5 | "start": "react-static start", 6 | "stage": "react-static build --staging", 7 | "build": "react-static build", 8 | "analyze": "react-static build --analyze", 9 | "serve": "serve dist -p 3000" 10 | }, 11 | "dependencies": { 12 | "@reach/router": "^1.2.1", 13 | "antd": "^4.10.2", 14 | "axios": "^0.21.1", 15 | "query-string": "^6.13.8", 16 | "react": "^16.9.0", 17 | "react-dom": "^16.9.0", 18 | "react-hot-loader": "^4.13.0", 19 | "react-static": "^7.2.0", 20 | "react-static-plugin-reach-router": "^7.2.0", 21 | "react-static-plugin-sitemap": "^7.2.0", 22 | "react-static-plugin-source-filesystem": "^7.2.0" 23 | }, 24 | "devDependencies": { 25 | "babel-eslint": "^10.0.2", 26 | "eslint": "^6.1.0", 27 | "eslint-config-react-app": "^5.0.1", 28 | "eslint-config-react-tools": "^1.1.7", 29 | "eslint-plugin-flowtype": "^4.2.0", 30 | "eslint-plugin-import": "^2.18.2", 31 | "eslint-plugin-jsx-a11y": "^6.2.3", 32 | "eslint-plugin-react": "^7.14.3", 33 | "eslint-plugin-react-hooks": "^4.0.2", 34 | "serve": "^11.1.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /code-nav-home/public/baiduAnalyze.js: -------------------------------------------------------------------------------- 1 | var _hmt = _hmt || []; 2 | (function () { 3 | var hm = document.createElement("script"); 4 | hm.src = "https://hm.baidu.com/hm.js?6e0626c0821ff3cf84e26ce36ca8c492"; 5 | var s = document.getElementsByTagName("script")[0]; 6 | s.parentNode.insertBefore(hm, s); 7 | })(); 8 | 9 | // 禁止右键 10 | document.addEventListener("contextmenu", function () { 11 | return false; 12 | }); 13 | document.oncontextmenu = function () { 14 | return false; 15 | }; 16 | // 禁止 F12 17 | document.onkeydown = function (event) { 18 | if (window.event && window.event.keyCode === 123) { 19 | event.keyCode = 0; 20 | event.returnValue = false; 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /code-nav-home/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/public/favicon.ico -------------------------------------------------------------------------------- /code-nav-home/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | -------------------------------------------------------------------------------- /code-nav-home/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Root, Routes} from 'react-static' 3 | import {Router} from 'components/Router' 4 | import {Spin} from "antd"; 5 | import 'antd/dist/antd.min.css' 6 | import './app.css' 7 | 8 | function App() { 9 | 10 | // loading 11 | const fallbackView =
; 12 | 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ) 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /code-nav-home/src/app.css: -------------------------------------------------------------------------------- 1 | /*全局样式*/ 2 | .center-container { 3 | width: 100vw; 4 | height: 100vh; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | background: #f5f5f5; 9 | } 10 | -------------------------------------------------------------------------------- /code-nav-home/src/assets/baidu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/src/assets/baidu.png -------------------------------------------------------------------------------- /code-nav-home/src/assets/google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/src/assets/google.png -------------------------------------------------------------------------------- /code-nav-home/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/src/assets/logo.png -------------------------------------------------------------------------------- /code-nav-home/src/assets/qrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-home/src/assets/qrcode.jpg -------------------------------------------------------------------------------- /code-nav-home/src/components/Router.js: -------------------------------------------------------------------------------- 1 | export { Link, Router } from '@reach/router' 2 | -------------------------------------------------------------------------------- /code-nav-home/src/constant/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 网站域名 3 | * @type {string} 4 | */ 5 | export const WEB_HOST = 'https://www.code-nav.cn'; 6 | 7 | /** 8 | * 封面域名 9 | * @type {string} 10 | */ 11 | export const COVER_HOST = 'https://636f-codenav-8grj8px727565176-1256524210.tcb.qcloud.la/covers'; 12 | 13 | /** 14 | * GitHub 地址 15 | * @type {string} 16 | */ 17 | export const PROJECT_GITHUB = 'https://github.com/liyupi/code-nav'; 18 | 19 | /** 20 | * 当前封面 键名 21 | */ 22 | export const CURRENT_COVER = 'currentCover'; 23 | 24 | /** 25 | * 是否开启万能搜索 键名 26 | */ 27 | export const SEARCH_ALL_OPEN = 'searchAllOpen'; 28 | 29 | /** 30 | * 是否开启透明模式 键名 31 | */ 32 | export const GHOST_OPEN = 'ghostOpen'; 33 | -------------------------------------------------------------------------------- /code-nav-home/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import {AppContainer} from 'react-hot-loader' 4 | 5 | // Your top level component 6 | import App from './App' 7 | 8 | // Export your top level component as JSX (for static rendering) 9 | export default App 10 | 11 | // Render your app 12 | if (typeof document !== 'undefined') { 13 | const target = document.getElementById('root') 14 | 15 | const renderMethod = target.hasChildNodes() 16 | ? ReactDOM.hydrate 17 | : ReactDOM.render 18 | 19 | const render = Comp => { 20 | renderMethod( 21 | 22 | 23 | , 24 | target 25 | ) 26 | } 27 | 28 | // Render! 29 | render(App) 30 | 31 | // Hot Module Replacement 32 | if (module && module.hot) { 33 | module.hot.accept('./App', () => { 34 | render(App) 35 | }) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /code-nav-home/src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default () => ( 4 |
5 |

404 - 抱歉,您要找的页面不存在 :(

6 |
7 | ) 8 | -------------------------------------------------------------------------------- /code-nav-home/src/pages/ghost.css: -------------------------------------------------------------------------------- 1 | /*透明主题*/ 2 | .ghost .card { 3 | background: none !important; 4 | } 5 | 6 | .ghost .resource-name { 7 | color: #fff; 8 | } 9 | 10 | .ghost .search-wrapper { 11 | box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 0 10px 1px rgba(0, 0, 0, 0.09); 12 | } 13 | 14 | .ghost .ant-input-group-addon { 15 | background: none !important; 16 | } 17 | 18 | .ghost .search .ant-input-search-button { 19 | color: white !important; 20 | border-color: #f5f5f5; 21 | } 22 | 23 | .ghost .search .ant-input-search-button:hover { 24 | border-color: #40a9ff; 25 | } 26 | 27 | .ghost .ant-btn-ghost:hover, .ghost .ant-btn-ghost:focus { 28 | color: #40a9ff !important; 29 | } 30 | 31 | .ghost .ant-input-affix-wrapper { 32 | background: none !important; 33 | border-color: #f5f5f5 !important; 34 | } 35 | 36 | .ghost .ant-input-affix-wrapper:hover { 37 | border-color: #40a9ff !important; 38 | } 39 | 40 | .ghost .ant-input { 41 | background: none !important; 42 | color: #fff; 43 | } 44 | 45 | .ghost .ant-card-grid { 46 | box-shadow: none !important; 47 | background: rgba(0, 0, 0, 0.2) !important; 48 | } 49 | 50 | .ghost .ant-card-grid:hover { 51 | box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09) !important; 52 | } 53 | 54 | .ghost .ant-btn-ghost { 55 | color: #fff; 56 | } 57 | -------------------------------------------------------------------------------- /code-nav-home/static.config.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import path from 'path' 3 | 4 | export default { 5 | Document: ({ 6 | Html, 7 | Head, 8 | Body, 9 | children, 10 | state: {siteData, renderMeta}, 11 | }) => ( 12 | 13 | 14 | 15 | 16 | 编程导航 - 程序员必备主页 17 | 18 | 19 | 20 | 21 | 22 | {children} 23 | 24 | ), 25 | silent: true, 26 | getRoutes: async () => { 27 | return [ 28 | { 29 | path: 'search', 30 | template: 'src/pages/search/index', 31 | } 32 | ] 33 | }, 34 | plugins: [ 35 | [ 36 | require.resolve('react-static-plugin-source-filesystem'), 37 | { 38 | location: path.resolve('./src/pages'), 39 | }, 40 | ], 41 | require.resolve('react-static-plugin-reach-router'), 42 | require.resolve('react-static-plugin-sitemap'), 43 | ], 44 | } 45 | -------------------------------------------------------------------------------- /code-nav-main/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /code-nav-main/.env: -------------------------------------------------------------------------------- 1 | ENV_ID=你的云开发环境ID 2 | -------------------------------------------------------------------------------- /code-nav-main/.env.test: -------------------------------------------------------------------------------- 1 | ENV_ID=你的云开发测试环境ID7 2 | -------------------------------------------------------------------------------- /code-nav-main/.eslintignore: -------------------------------------------------------------------------------- 1 | /lambda/ 2 | /scripts 3 | /config 4 | .history 5 | public 6 | dist 7 | .umi 8 | mock -------------------------------------------------------------------------------- /code-nav-main/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [require.resolve('@umijs/fabric/dist/eslint')], 3 | globals: { 4 | page: true, 5 | REACT_APP_ENV: true, 6 | }, 7 | rules: { 8 | 'no-underscore-dangle': 'off', 9 | 'no-param-reassign': 'off', 10 | 'class-methods-use-this': 'off', 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /code-nav-main/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | **/node_modules 5 | # roadhog-api-doc ignore 6 | /src/utils/request-temp.js 7 | _roadhog-api-doc 8 | 9 | # production 10 | dist 11 | /.vscode 12 | 13 | # misc 14 | .DS_Store 15 | npm-debug.log* 16 | package-lock.json 17 | yarn-error.log 18 | yarn.lock 19 | 20 | /coverage 21 | .idea 22 | *bak 23 | .vscode 24 | 25 | # visual studio code 26 | .history 27 | *.log 28 | functions/* 29 | .temp/** 30 | 31 | # umi 32 | .umi 33 | .umi-production 34 | 35 | # screenshot 36 | screenshot 37 | .firebase 38 | .eslintcache 39 | 40 | build 41 | -------------------------------------------------------------------------------- /code-nav-main/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.svg 2 | package.json 3 | .umi 4 | .umi-production 5 | /dist 6 | .dockerignore 7 | .DS_Store 8 | .eslintignore 9 | *.png 10 | *.toml 11 | docker 12 | .editorconfig 13 | Dockerfile* 14 | .gitignore 15 | .prettierignore 16 | LICENSE 17 | .eslintcache 18 | *.lock 19 | yarn-error.log 20 | .history 21 | CNAME 22 | /build 23 | /public -------------------------------------------------------------------------------- /code-nav-main/.prettierrc.js: -------------------------------------------------------------------------------- 1 | const fabric = require('@umijs/fabric'); 2 | 3 | module.exports = { 4 | ...fabric.prettier, 5 | }; 6 | -------------------------------------------------------------------------------- /code-nav-main/.stylelintrc.js: -------------------------------------------------------------------------------- 1 | const fabric = require('@umijs/fabric'); 2 | 3 | module.exports = { 4 | ...fabric.stylelint, 5 | }; 6 | -------------------------------------------------------------------------------- /code-nav-main/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # 参与者公约 2 | 3 | ## 我们的承诺 4 | 5 | 为建设开放友好的环境,我们贡献者和维护者承诺:不论年龄、体型、身体健全与否、民族、性征、性别认同与表征、经验水平、教育程度、社会地位、国籍、相貌、种族、信仰、性取向,我们项目和社区的参与者皆免于骚扰。 6 | 7 | ## 我们的准则 8 | 9 | 有助于创造积极环境的行为包括但不限于: 10 | 11 | * 措辞友好且包容 12 | * 尊重不同的观点和经验 13 | * 耐心接受有益批评 14 | * 关注对社区最有利的事情 15 | * 与社区其他成员友善相处 16 | 17 | 参与者不应采取的行为包括但不限于: 18 | 19 | * 发布与性有关的言论或图像、不受欢迎地献殷勤 20 | * 捣乱/煽动/造谣行为、侮辱/贬损的评论、人身及政治攻击 21 | * 公开或私下骚扰 22 | * 未经明确授权便发布他人的资料,如住址、电子邮箱等 23 | * 其他有理由认定为违反职业操守的不当行为 24 | 25 | ## 我们的义务 26 | 27 | 项目维护者有义务诠释何谓“妥当行为”,并妥善公正地纠正已发生的不当行为。 28 | 29 | 项目维护者有权利和义务去删除、编辑、拒绝违背本行为标准的评论(comments)、提交(commits)、代码、wiki 编辑、问题(issues)等贡献;项目维护者可暂时或永久地封禁任何他们认为行为不当、威胁、冒犯、有害的参与者。 30 | 31 | ## 适用范围 32 | 33 | 本行为标准适用于本项目。当有人代表本项目或本社区时,本标准亦适用于此人所处的公共平台。 34 | 35 | 代表本项目或本社区的情形包括但不限于:使用项目的官方电子邮件、通过官方媒体账号发布消息、作为指定代表参与在线或线下活动等。 36 | 37 | 代表本项目的行为可由项目维护者进一步定义及解释。 38 | 39 | ## 贯彻落实 40 | 41 | 可以致信 [592789970@qq.com](mailto:592789970@qq.com),向项目团队举报滥用、骚扰及不当行为。 42 | 43 | 维护团队将审议并调查全部投诉,妥善地予以必要的回应。项目团队有义务保密举报者信息。具体执行方针或将另行发布。 44 | 45 | 未切实遵守或执行本行为标准的项目维护人员,经项目负责人或其他成员决议,可能被暂时或永久地剥夺参与本项目的资格。 46 | 47 | ## 来源 48 | 49 | 本行为标准改编自[参与者公约][主页],版本 1.4 50 | 可在此查阅:https://www.contributor-covenant.org/zh-cn/version/1/4/code-of-conduct.html 51 | 52 | [主页]: https://www.contributor-covenant.org 53 | 54 | -------------------------------------------------------------------------------- /code-nav-main/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | 3 | WORKDIR /usr/share/nginx/html/ 4 | USER root 5 | 6 | COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf 7 | 8 | COPY ./dist /usr/share/nginx/html/ 9 | 10 | EXPOSE 80 11 | 12 | CMD ["nginx", "-g", "daemon off;"] 13 | -------------------------------------------------------------------------------- /code-nav-main/Dockerfile.build: -------------------------------------------------------------------------------- 1 | FROM circleci/node:latest-browsers as builder 2 | 3 | WORKDIR /usr/src/app/ 4 | USER root 5 | COPY package.json ./ 6 | RUN yarn 7 | 8 | COPY ./ ./ 9 | 10 | RUN npm run build 11 | 12 | FROM nginx 13 | 14 | WORKDIR /usr/share/nginx/html/ 15 | 16 | COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf 17 | 18 | COPY --from=builder /usr/src/app/dist /usr/share/nginx/html/ 19 | 20 | EXPOSE 80 21 | 22 | CMD ["nginx", "-g", "daemon off;"] 23 | -------------------------------------------------------------------------------- /code-nav-main/assets/umiButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/assets/umiButton.png -------------------------------------------------------------------------------- /code-nav-main/assets/umiTmp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/assets/umiTmp.png -------------------------------------------------------------------------------- /code-nav-main/baidu/urls.txt: -------------------------------------------------------------------------------- 1 | www.code-nav.cn 2 | -------------------------------------------------------------------------------- /code-nav-main/cloudbaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "envId": "{{env.ENV_ID}}", 4 | "$schema": "https://framework-1258016615.tcloudbaseapp.com/schema/latest.json", 5 | "functionRoot": "cloudfunctions", 6 | "functions": [ 7 | { 8 | "name": "countUserScoreRank", 9 | "runtime": "Nodejs10.15", 10 | "triggers": [ 11 | { 12 | "name": "countUserScoreRankTrigger", 13 | "type": "timer", 14 | "config": "0 0 2 * * * *" 15 | } 16 | ] 17 | }, 18 | { 19 | "name": "redisService", 20 | "runtime": "Nodejs10.15" 21 | } 22 | ], 23 | "framework": { 24 | "name": "code-nav", 25 | "plugins": { 26 | "client": { 27 | "use": "@cloudbase/framework-plugin-website", 28 | "inputs": { 29 | "buildCommand": "npm run build", 30 | "outputPath": "dist", 31 | "cloudPath": "/", 32 | "envVariables": { 33 | "REACT_APP_ENV_ID": "{{env.ENV_ID}}" 34 | } 35 | } 36 | }, 37 | "auth": { 38 | "use": "@cloudbase/framework-plugin-auth", 39 | "inputs": { 40 | "configs": [ 41 | { 42 | "platform": "NONLOGIN", 43 | "status": "DISABLE" 44 | }, 45 | { 46 | "platform": "ANONYMOUS", 47 | "status": "ENABLE" 48 | } 49 | ] 50 | } 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | yarn.lock 3 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/README.md: -------------------------------------------------------------------------------- 1 | # 编程导航后端 - 云函数 2 | 3 | > 请先阅读 [云函数文档](https://docs.cloudbase.net/cloud-function/introduce.html) 以了解云函数 4 | 5 | ## 已有函数 6 | 7 | - 添加消息 8 | - 添加分享数 9 | - 生成定制主页信息 10 | - 更新定制主页 11 | - 获取简略用户信息 12 | - 获取所有标签信息 13 | - 获取完整用户信息(管理员或当前用户) 14 | - 收藏资源 15 | - 更新资源 16 | - 浏览资源 17 | - 更新用户兴趣 18 | - 获取我的消息列表 19 | - 获取推荐资源列表 20 | - 获取用户排名列表 21 | - 用户登录 22 | - 审核评论 23 | - 审核资源 24 | - 刷新资源指定字段(单次调用) 25 | - 根据 json 批量添加资源(单次调用) 26 | - 根据获取动态码(仅限小程序调用) 27 | 28 | ## 开发 SDK 29 | 30 | > 请阅读:[一站式后端服务文档](https://docs.cloudbase.net/api-reference/server/node-sdk/functions.html) 31 | 32 | ## 用命令行操作云函数 33 | 34 | > 请阅读:[云开发 CLI 工具文档](https://docs.cloudbase.net/cli-v1/intro.html) 35 | 36 | 本地测试 37 | 38 | ```bash 39 | tcb fn run --name --params "{\"userId\": 1}" 40 | ``` 41 | 42 | 更新函数代码 43 | 44 | ```bash 45 | tcb fn code update --dir 46 | ``` 47 | 48 | 部署 49 | 50 | ```bash 51 | tcb fn deploy --dir 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/comment/addComment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addComment", 3 | "version": "1.0.0", 4 | "description": "创建评论", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/comment/reviewComment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reviewComment", 3 | "version": "1.0.0", 4 | "description": "审核评论", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/comment/searchComments/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "searchComments", 3 | "version": "1.0.0", 4 | "description": "搜索评论", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/comment/thumbUpComment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thumbUpComment", 3 | "version": "1.0.0", 4 | "description": "点赞评论", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/common/getTags/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getTags", 3 | "version": "1.0.0", 4 | "description": "获取标签", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/common/parseURL/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parseURL", 3 | "version": "1.0.0", 4 | "description": "解析 URL", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "1.1.1", 11 | "axios": "^0.21.1", 12 | "cheerio": "^1.0.0-rc.6" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/common/redisService/index.js: -------------------------------------------------------------------------------- 1 | const Redis = require('ioredis'); 2 | 3 | const redis = new Redis({ 4 | host: '10.0.192.8', 5 | port: 6379, 6 | password: 'bcdh6666', 7 | }); 8 | 9 | /** 10 | * Redis 服务 11 | * 12 | * @desc 支持多种操作 13 | * @param event 14 | * @param context 15 | * @author yupili 16 | */ 17 | exports.main = async (event, context) => { 18 | const { op, key, value, expireSeconds } = event; 19 | if (!op || !key) { 20 | return null; 21 | } 22 | 23 | switch (op) { 24 | case 'set': 25 | return set(key, value, expireSeconds); 26 | case 'setnx': 27 | return setnx(key, value, expireSeconds); 28 | case 'get': 29 | return get(key); 30 | default: 31 | return null; 32 | } 33 | }; 34 | 35 | function set(key, value, expireSeconds) { 36 | if (expireSeconds) { 37 | return redis.set(key, value, 'EX', expireSeconds); 38 | } 39 | return redis.set(key, value); 40 | } 41 | 42 | function setnx(key, value, expireSeconds) { 43 | if (expireSeconds) { 44 | return redis.set(key, value, 'EX', expireSeconds, 'NX'); 45 | } 46 | return redis.set(key, value, 'NX'); 47 | } 48 | 49 | function get(key) { 50 | return redis.get(key); 51 | } 52 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/common/redisService/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redisService", 3 | "version": "1.0.0", 4 | "description": "Redis 服务", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git@git.code.oa.com:guobinzhang/redis_demo.git" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "ioredis": "^4.27.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/common/sendEmail/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 发送邮件 sendEmail 3 | * 4 | * @Author cjf 5 | * @param to 收件人 6 | * @param subject 主题 7 | * @param content 正文 8 | * @return bool true / error (成功 / 错误) 9 | */ 10 | const nodemailer = require('nodemailer'); 11 | const transporter_config = require('./transporter.json'); 12 | 13 | exports.main = async (event, context) => { 14 | const {to, subject, content} = event; 15 | if (!to || !subject || !content) { 16 | return null; 17 | } 18 | 19 | let mailOptions = { 20 | from: 'xx@qq.com', // sender address 21 | to: to, // list of receivers 22 | subject: subject, // Subject line 23 | // 发送text或者html格式 24 | text: content, // plain text body 25 | // html: 'Hello world?' // html body 26 | }; 27 | 28 | let transporter = nodemailer.createTransport(transporter_config); 29 | 30 | // send mail with defined transport object 31 | transporter.sendMail(mailOptions, (error, info) => { 32 | if (error) { 33 | console.error(error) 34 | return error; 35 | } else { 36 | return true; 37 | } 38 | console.log('Message sent: %s', info.messageId); 39 | }); 40 | return true; 41 | }; 42 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/common/sendEmail/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sendEmail", 3 | "version": "1.0.0", 4 | "description": "发送邮件", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "sendEmail", 11 | "发送邮件", 12 | "nodemailer" 13 | ], 14 | "author": "cjf", 15 | "license": "ISC", 16 | "dependencies": { 17 | "nodemailer": "^6.6.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/common/sendEmail/transporter.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": "qq", 3 | "port": 465, 4 | "secureConnection": true, 5 | "auth": { 6 | "user": "xx@qq.com", 7 | "pass": "xx" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/getCaptcha/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getCaptcha", 3 | "version": "1.0.0", 4 | "description": "获取动态码(用户注册)", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "1.1.1", 11 | "random-string": "^0.2.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/home/updateHome/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require("@cloudbase/node-sdk"); 2 | 3 | /** 4 | * 更新主页模板 5 | * @param event 6 | * @param context 7 | * @return {Promise} 8 | */ 9 | exports.main = async (event, context) => { 10 | const app = cloud.init({ 11 | env: cloud.SYMBOL_CURRENT_ENV, 12 | }); 13 | 14 | const db = app.database(); 15 | 16 | const {homeId, home, userId} = event; 17 | 18 | if (!homeId || !home || !userId) { 19 | return; 20 | } 21 | 22 | const originHome = await db.collection('home') 23 | .where({ 24 | _id: homeId, 25 | userId, 26 | isDelete: false, 27 | }).get().then(({data}) => data[0]); 28 | 29 | if (!originHome) { 30 | return; 31 | } 32 | 33 | return db.collection('home') 34 | .doc(homeId) 35 | .update({ 36 | ...home, 37 | _updateTime: new Date(), 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/home/updateHome/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "updateHome", 3 | "version": "1.0.0", 4 | "description": "更新主页模板", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "1.1.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/login/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "login", 3 | "version": "1.0.0", 4 | "description": "登录", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/message/addMessage/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require('@cloudbase/node-sdk'); 2 | 3 | /** 4 | * 发送系统消息(内部调用) 5 | * @param event 6 | * @param context 7 | */ 8 | exports.main = async (event, context) => { 9 | const { toUserId, title, content } = event; 10 | 11 | // 请求参数校验 12 | if (!toUserId || !title) { 13 | return false; 14 | } 15 | 16 | const app = cloud.init({ 17 | env: cloud.SYMBOL_CURRENT_ENV, 18 | }); 19 | 20 | const db = app.database(); 21 | 22 | // 封装数据 23 | const data = { 24 | toUserId, 25 | title, 26 | content, 27 | fromUserId: 0, 28 | status: 0, 29 | type: 0, 30 | _createTime: new Date(), 31 | _updateTime: new Date(), 32 | isDelete: false, 33 | }; 34 | 35 | // 插入数据 36 | return await db 37 | .collection('message') 38 | .add(data) 39 | .then((res) => { 40 | console.log(`addMessage succeed, id = ${res.id}`); 41 | return true; 42 | }) 43 | .catch((e) => { 44 | console.error('addMessage error', e); 45 | return false; 46 | }); 47 | }; 48 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/message/addMessage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addMessage", 3 | "version": "1.0.0", 4 | "description": "创建消息", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/message/countMyMessages/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require('@cloudbase/node-sdk'); 2 | 3 | const app = cloud.init({ 4 | env: cloud.SYMBOL_CURRENT_ENV, 5 | }); 6 | const db = app.database(); 7 | 8 | /** 9 | * 获取当前用户收到的消息数 10 | * @param event 11 | */ 12 | exports.main = async (event) => { 13 | const { type, status } = event; 14 | 15 | const { userInfo } = app.auth().getEndUserInfo(); 16 | if (!userInfo || !userInfo.customUserId) { 17 | return null; 18 | } 19 | const currentUser = await db 20 | .collection('user') 21 | .where({ 22 | unionId: userInfo.customUserId, 23 | isDelete: false, 24 | }) 25 | .limit(1) 26 | .get() 27 | .then(({ data }) => data[0]); 28 | if (!currentUser || !currentUser._id) { 29 | return null; 30 | } 31 | 32 | const condition = { 33 | toUserId: currentUser._id, 34 | isDelete: false, 35 | }; 36 | if (status > -1) { 37 | condition.status = status; 38 | } 39 | if (type > -1) { 40 | condition.type = type; 41 | } 42 | 43 | // 查询总数 44 | return await db 45 | .collection('message') 46 | .where(condition) 47 | .count() 48 | .then((res) => { 49 | return res.total; 50 | }); 51 | }; 52 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/message/countMyMessages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "countMyMessages", 3 | "version": "1.0.0", 4 | "description": "查询我的消息数", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/message/searchMessages/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require("@cloudbase/node-sdk"); 2 | 3 | /** 4 | * 获取当前用户收到的消息(支持分页) 5 | * @param event 6 | * @param context 7 | */ 8 | exports.main = async (event, context) => { 9 | 10 | const {type, status, pageSize = 10, pageNum = 1} = event; 11 | 12 | const app = cloud.init({ 13 | env: cloud.SYMBOL_CURRENT_ENV, 14 | }); 15 | 16 | const {userInfo} = app.auth().getEndUserInfo(); 17 | 18 | if (!userInfo || !userInfo.customUserId) { 19 | return null; 20 | } 21 | 22 | const db = app.database(); 23 | 24 | const currentUser = await db.collection("user") 25 | .where({ 26 | unionId: userInfo.customUserId, 27 | isDelete: false, 28 | }).limit(1).get().then(({data}) => data[0]); 29 | 30 | if (!currentUser || !currentUser._id) { 31 | return null; 32 | } 33 | 34 | const condition = { 35 | toUserId: currentUser._id, 36 | isDelete: false, 37 | }; 38 | 39 | if (status > -1) { 40 | condition.status = status; 41 | } 42 | 43 | if (type > -1) { 44 | condition.type = type; 45 | } 46 | 47 | // 查询总数 48 | const total = await db.collection("message") 49 | .where(condition) 50 | .count() 51 | .then(res => { 52 | return res.total; 53 | }); 54 | 55 | if (!total) { 56 | return { 57 | total: 0, 58 | data: [], 59 | } 60 | } 61 | 62 | // 查询消息 63 | const list = await db.collection("message") 64 | .where(condition) 65 | .skip((pageNum - 1) * pageSize) 66 | .orderBy('_createTime', 'desc') 67 | .limit(pageSize) 68 | .get() 69 | .then(res => { 70 | return res.data; 71 | }); 72 | 73 | return { 74 | total, 75 | data: list, 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/message/searchMessages/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "searchMessages", 3 | "version": "1.0.0", 4 | "description": "搜索消息", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/message/updateMessage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "updateMessage", 3 | "version": "1.0.0", 4 | "description": "更新消息", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/notice/addNotice/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require('@cloudbase/node-sdk'); 2 | 3 | // 鉴权,仅管理员可调用该接口 4 | const app = cloud.init({ 5 | env: cloud.SYMBOL_CURRENT_ENV, 6 | }); 7 | const db = app.database(); 8 | const collection = db.collection('notice'); 9 | 10 | /** 11 | * 添加通知 12 | * @param event 13 | * @param context 14 | * @author yupili 15 | */ 16 | exports.main = async (event, context) => { 17 | const { title, content } = event; 18 | // 请求参数校验 19 | if (!title) { 20 | return false; 21 | } 22 | // 获取当前登录用户 23 | const { userInfo } = app.auth().getEndUserInfo(); 24 | if (!userInfo || !userInfo.customUserId) { 25 | return false; 26 | } 27 | const currentUser = await db 28 | .collection('user') 29 | .where({ 30 | unionId: userInfo.customUserId, 31 | isDelete: false, 32 | }) 33 | .limit(1) 34 | .get() 35 | .then(({ data }) => data[0]); 36 | // 仅管理员可操作 37 | if (!currentUser || !currentUser._id || !currentUser.authority.includes('admin')) { 38 | return false; 39 | } 40 | 41 | return await collection 42 | .add({ 43 | title, 44 | content, 45 | userId: currentUser._id, 46 | isDelete: false, 47 | _createTime: new Date(), 48 | _updateTime: new Date(), 49 | }) 50 | .then((res) => { 51 | console.log('addNotice succeed', res); 52 | return true; 53 | }) 54 | .catch((e) => { 55 | console.error('addNotice error', e); 56 | return false; 57 | }); 58 | }; 59 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/notice/addNotice/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addNotice", 3 | "version": "1.0.0", 4 | "description": "创建公告", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/notice/updateNotice/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require('@cloudbase/node-sdk'); 2 | 3 | // 鉴权,仅管理员可调用该接口 4 | const app = cloud.init({ 5 | env: cloud.SYMBOL_CURRENT_ENV, 6 | }); 7 | const db = app.database(); 8 | 9 | /** 10 | * 修改通知 11 | * @param event 12 | * @param context 13 | * @author yupili 14 | */ 15 | exports.main = async (event, context) => { 16 | const { noticeId, title, content, isDelete } = event; 17 | // 请求参数校验 18 | if (!noticeId || (title === undefined && content === undefined && isDelete === undefined)) { 19 | return false; 20 | } 21 | 22 | const { userInfo } = app.auth().getEndUserInfo(); 23 | if (!userInfo || !userInfo.customUserId) { 24 | return false; 25 | } 26 | const currentUser = await db 27 | .collection('user') 28 | .where({ 29 | unionId: userInfo.customUserId, 30 | isDelete: false, 31 | }) 32 | .limit(1) 33 | .get() 34 | .then(({ data }) => data[0]); 35 | // 仅管理员可更新 36 | if (!currentUser || !currentUser._id || !currentUser.authority.includes('admin')) { 37 | return false; 38 | } 39 | 40 | const updateData = { 41 | _updateTime: new Date(), 42 | }; 43 | if (title !== undefined) { 44 | updateData.title = title; 45 | } 46 | if (content !== undefined) { 47 | updateData.title = title; 48 | } 49 | if (isDelete !== undefined) { 50 | updateData.isDelete = isDelete; 51 | } 52 | return await db.collection('notice').doc(noticeId).update(updateData); 53 | }; 54 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/notice/updateNotice/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "updateNotice", 3 | "version": "1.0.0", 4 | "description": "更新公告", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/report/addReport/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addReport", 3 | "version": "1.0.0", 4 | "description": "创建举报", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/report/reviewReport/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reviewReport", 3 | "version": "1.0.0", 4 | "description": "审核举报", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/addResource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addResource", 3 | "version": "1.0.0", 4 | "description": "创建资源", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/addShareNum/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addShareNum", 3 | "version": "1.0.0", 4 | "description": "添加资源分享数", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "1.1.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/batchAdd/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "batchAdd", 3 | "version": "1.0.0", 4 | "description": "批量创建资源(仅本地单次调用)", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/likeResource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "likeResource", 3 | "version": "1.0.0", 4 | "description": "喜欢资源", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/listRecommendResources/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "listRecommendResources", 3 | "version": "1.0.0", 4 | "description": "获取推荐资源列表", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/refreshResource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "refreshResource", 3 | "version": "1.0.0", 4 | "description": "刷新资源发布时间(仅本地单次调用)", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/reviewResource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reviewResource", 3 | "version": "1.0.0", 4 | "description": "审核资源", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/updateResource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "updateResource", 3 | "version": "1.0.0", 4 | "description": "更新资源", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/updateTags/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "updateTags", 3 | "version": "1.0.0", 4 | "description": "更新资源标签", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/viewResource/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require("@cloudbase/node-sdk"); 2 | 3 | /** 4 | * 浏览资源 5 | * @param event 6 | * @param context 7 | */ 8 | exports.main = async (event, context) => { 9 | const app = cloud.init({ 10 | env: cloud.SYMBOL_CURRENT_ENV, 11 | }); 12 | 13 | const db = app.database(); 14 | const _ = db.command; 15 | 16 | const {resourceId} = event; 17 | 18 | if (!resourceId) { 19 | return false; 20 | } 21 | 22 | const resource = await db.collection('resource') 23 | .where({ 24 | _id: resourceId, 25 | isDelete: false, 26 | }).get().then(({data}) => data[0]); 27 | 28 | if (!resource) { 29 | return false; 30 | } 31 | 32 | return db.collection('resource') 33 | .doc(resourceId) 34 | .update({ 35 | viewNum: _.inc(1), 36 | _updateTime: new Date(), 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/resource/viewResource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viewResource", 3 | "version": "1.0.0", 4 | "description": "浏览资源", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/doDailyLogin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addUserScore", 3 | "version": "1.0.0", 4 | "description": "每日登录", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/getSimpleUser/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require("@cloudbase/node-sdk"); 2 | 3 | /** 4 | * 获取简略用户信息 5 | * @param event 6 | */ 7 | exports.main = async (event) => { 8 | const {userId} = event; 9 | 10 | if (!userId) { 11 | return null; 12 | } 13 | 14 | const app = cloud.init({ 15 | env: cloud.SYMBOL_CURRENT_ENV, 16 | }); 17 | const db = app.database(); 18 | 19 | return await db.collection("user") 20 | .field({ 21 | _id: true, 22 | nickName: true, 23 | avatarUrl: true, 24 | }).where({ 25 | _id: userId, 26 | isDelete: false, 27 | }).limit(1).get().then(({data}) => data[0]); 28 | }; 29 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/getSimpleUser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getSimpleUser", 3 | "version": "1.0.0", 4 | "description": "获取简略用户信息", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/getUser/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require("@cloudbase/node-sdk"); 2 | 3 | /** 4 | * 获取指定用户信息(传 unionId 为获取当前登录用户信息) 5 | * @param event 6 | * @param context 7 | * @return {Promise} 8 | */ 9 | exports.main = async (event, context) => { 10 | const {userId, unionId} = event; 11 | 12 | if (!userId && !unionId) { 13 | return null; 14 | } 15 | 16 | const app = cloud.init({ 17 | env: cloud.SYMBOL_CURRENT_ENV, 18 | }); 19 | 20 | const {userInfo} = app.auth().getEndUserInfo(); 21 | 22 | if (!userInfo || !userInfo.customUserId) { 23 | return false; 24 | } 25 | 26 | const db = app.database(); 27 | 28 | // 获取当前用户 29 | const currentUser = await db.collection("user") 30 | .where({ 31 | unionId: userInfo.customUserId, 32 | isDelete: false, 33 | }).limit(1).get().then(({data}) => data[0]); 34 | 35 | if (!currentUser || !currentUser._id) { 36 | return false; 37 | } 38 | 39 | // 获取某 user 信息 40 | if (userId) { 41 | if (currentUser._id === userId) { 42 | return currentUser; 43 | } 44 | if (currentUser.authority.includes('admin')) { 45 | return db.collection("user") 46 | .where({ 47 | _id: userId, 48 | isDelete: false, 49 | }).limit(1).get().then(({data}) => data[0]); 50 | } 51 | return null; 52 | } 53 | 54 | // 根据 unionId 获取信息(用于首次登录) 55 | if (unionId !== userInfo.customUserId) { 56 | return null; 57 | } 58 | 59 | return currentUser; 60 | }; 61 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/getUser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getUser", 3 | "version": "1.0.0", 4 | "description": "获取用户信息", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/getUserRank/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require('@cloudbase/node-sdk'); 2 | 3 | const app = cloud.init({ 4 | env: cloud.SYMBOL_CURRENT_ENV, 5 | }); 6 | const db = app.database(); 7 | const _ = db.command; 8 | 9 | const ERROR_CODE = -1; 10 | 11 | /** 12 | * 获取指定用户排名 13 | * @param event 14 | * @param context 15 | */ 16 | exports.main = async (event, context) => { 17 | const { userId } = event; 18 | 19 | if (!userId) { 20 | return ERROR_CODE; 21 | } 22 | 23 | const user = await db 24 | .collection('user') 25 | .doc(userId) 26 | .get() 27 | .then(({ data }) => data[0]); 28 | 29 | if (!user) { 30 | return ERROR_CODE; 31 | } 32 | 33 | // 获取分数大于指定用户分数的人数,+1 即为排名 34 | const count = await db 35 | .collection('user') 36 | .where({ 37 | score: _.gt(user.score), 38 | isDelete: false, 39 | }) 40 | .count() 41 | .then((res) => res.total); 42 | return count + 1; 43 | }; 44 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/getUserRank/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "getUserRank", 3 | "version": "1.0.0", 4 | "description": "获取指定用户排名", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/listUserCycleRank/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require('@cloudbase/node-sdk'); 2 | 3 | const app = cloud.init({ 4 | env: cloud.SYMBOL_CURRENT_ENV, 5 | }); 6 | const db = app.database(); 7 | const _ = db.command; 8 | 9 | /** 10 | * 获取用户积分排行统计榜 11 | * @desc cycle: 0-周榜 1-月榜 12 | * @param event 13 | * @param context 14 | */ 15 | exports.main = async (event, context) => { 16 | const { cycle = 0, countDate, pageSize = 10 } = event; 17 | 18 | let result = []; 19 | 20 | if (![0, 1].includes(cycle) || !countDate || !pageSize) { 21 | return result; 22 | } 23 | 24 | const userScoreRank = await db 25 | .collection('userScoreRank') 26 | .field({ 27 | countDate: true, 28 | rankList: true, 29 | }) 30 | .where({ 31 | cycle, 32 | countDate, 33 | isDelete: false, 34 | }) 35 | .limit(1) 36 | .get() 37 | .then(({ data }) => data[0]); 38 | 39 | if (userScoreRank && userScoreRank.rankList) { 40 | const rankList = JSON.parse(userScoreRank.rankList).slice(0, pageSize); 41 | const userIds = rankList.map((item) => item._id); 42 | const users = await db 43 | .collection('user') 44 | .field({ 45 | _id: true, 46 | nickName: true, 47 | avatarUrl: true, 48 | }) 49 | .where({ 50 | _id: _.in(userIds), 51 | }) 52 | .get() 53 | .then(({ data }) => data); 54 | result = rankList.map((rank) => { 55 | rank.score = rank.totalScore; 56 | const tmpRank = users.find((user) => user._id === rank._id); 57 | return Object.assign({}, rank, tmpRank); 58 | }); 59 | } 60 | return result; 61 | }; 62 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/listUserCycleRank/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "listUserCycleRank", 3 | "version": "1.0.0", 4 | "description": "获取用户积分排行统计榜", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/listUserTotalRank/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require("@cloudbase/node-sdk"); 2 | 3 | const app = cloud.init({ 4 | env: cloud.SYMBOL_CURRENT_ENV, 5 | }); 6 | const db = app.database(); 7 | 8 | /** 9 | * 获取用户积分总排行 10 | * @param event 11 | * @param context 12 | * @return {Promise} 13 | */ 14 | exports.main = async (event, context) => { 15 | const {pageSize = 10, pageNum = 1} = event; 16 | 17 | return await db.collection("user") 18 | .field({ 19 | _id: true, 20 | nickName: true, 21 | avatarUrl: true, 22 | score: true, 23 | }) 24 | .where({ 25 | isDelete: false, 26 | }) 27 | .orderBy('score', 'desc') 28 | .skip((pageNum - 1) * pageSize) 29 | .limit(pageSize) 30 | .get() 31 | .then(({data}) => data); 32 | }; 33 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/listUserTotalRank/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "listUserTotalRank", 3 | "version": "1.0.0", 4 | "description": "获取用户总排行列表", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/updateUserInterests/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require("@cloudbase/node-sdk"); 2 | 3 | /** 4 | * 更新用户兴趣 5 | * @param event 6 | * @param context 7 | */ 8 | exports.main = async (event, context) => { 9 | const app = cloud.init({ 10 | env: cloud.SYMBOL_CURRENT_ENV, 11 | }); 12 | 13 | const {interests} = event; 14 | 15 | if (!interests || interests.length > 10) { 16 | return false; 17 | } 18 | 19 | const {userInfo} = app.auth().getEndUserInfo(); 20 | 21 | if (!userInfo || !userInfo.customUserId) { 22 | return false; 23 | } 24 | 25 | const db = app.database(); 26 | 27 | const currentUser = await db.collection("user") 28 | .where({ 29 | unionId: userInfo.customUserId, 30 | isDelete: false, 31 | }).limit(1).get().then(({data}) => data[0]); 32 | 33 | if (!currentUser || !currentUser._id) { 34 | return false; 35 | } 36 | 37 | return db.collection("user") 38 | .doc(currentUser._id) 39 | .update({ 40 | interests, 41 | _updateTime: new Date(), 42 | }); 43 | }; 44 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/user/updateUserInterests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "updateUserInterests", 3 | "version": "1.0.0", 4 | "description": "更新用户兴趣", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/userIntroduce/addOrUpdateUserIntroduce/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addOrUpdateUserIntroduce", 3 | "version": "1.0.0", 4 | "description": "创建或更新用户介绍", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/userIntroduce/searchUserIntroduces/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "searchUserIntroduces", 3 | "version": "1.0.0", 4 | "description": "搜索用户介绍", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/userIntroduce/thumbUpUserIntroduce/index.js: -------------------------------------------------------------------------------- 1 | const cloud = require('@cloudbase/node-sdk'); 2 | 3 | const app = cloud.init({ 4 | env: cloud.SYMBOL_CURRENT_ENV, 5 | }); 6 | 7 | const db = app.database(); 8 | const _ = db.command; 9 | 10 | /** 11 | * 为用户介绍点赞 12 | * @param event 13 | */ 14 | exports.main = async (event) => { 15 | const { userIntroduceId } = event; 16 | 17 | if (!userIntroduceId) { 18 | return false; 19 | } 20 | 21 | // 登录才能点赞 22 | const {userInfo} = app.auth().getEndUserInfo(); 23 | 24 | if (!userInfo || !userInfo.customUserId) { 25 | return false; 26 | } 27 | 28 | const currentUser = await db.collection("user") 29 | .where({ 30 | unionId: userInfo.customUserId, 31 | isDelete: false, 32 | }).limit(1).get().then(({data}) => data[0]); 33 | 34 | if (!currentUser || !currentUser._id) { 35 | return false; 36 | } 37 | 38 | console.log(`thumbUpUserIntroduce userId = ${currentUser._id}`); 39 | 40 | return await db 41 | .collection('userIntroduce') 42 | .doc(userIntroduceId) 43 | .update({ 44 | thumbNum: _.inc(1), 45 | _updateTime: new Date(), 46 | }); 47 | }; 48 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/userIntroduce/thumbUpUserIntroduce/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thumbUpUserIntroduce", 3 | "version": "1.0.0", 4 | "description": "点赞用户介绍", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/userScore/addUserScore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addUserScore", 3 | "version": "1.0.0", 4 | "description": "创建用户积分记录", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/cloudfunctions/userScore/countUserScoreRank/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "countUserScoreRank", 3 | "version": "1.0.0", 4 | "description": "统计用户积分排行(定时任务)", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "author": "", 8 | "license": "ISC", 9 | "dependencies": { 10 | "@cloudbase/node-sdk": "^2.5.0", 11 | "moment": "^2.29.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /code-nav-main/config/config.ts: -------------------------------------------------------------------------------- 1 | // https://umijs.org/config/ 2 | import {defineConfig} from 'umi'; 3 | import defaultSettings from './defaultSettings'; 4 | import proxy from './proxy'; 5 | import routes from './routes'; 6 | 7 | const {REACT_APP_ENV} = process.env; 8 | 9 | const IS_PROD = process.env.NODE_ENV !== 'development'; 10 | 11 | export default defineConfig({ 12 | hash: true, 13 | antd: {}, 14 | dva: { 15 | hmr: true, 16 | }, 17 | // history: { 18 | // type: 'hash', 19 | // }, 20 | // publicPath: './', 21 | locale: { 22 | // default zh-CN 23 | default: 'zh-CN', 24 | antd: true, 25 | // default true, when it is true, will use `navigator.language` overwrite default 26 | baseNavigator: true, 27 | }, 28 | extraBabelPlugins: [ 29 | IS_PROD ? 'transform-remove-console' : "", 30 | ], 31 | targets: { 32 | ie: 11, 33 | }, 34 | // umi routes: https://umijs.org/docs/routing 35 | routes, 36 | // Theme for antd: https://ant.design/docs/react/customize-theme-cn 37 | theme: { 38 | 'primary-color': defaultSettings.primaryColor, 39 | }, 40 | title: false, 41 | ignoreMomentLocale: true, 42 | proxy: proxy[REACT_APP_ENV || 'dev'], 43 | manifest: { 44 | basePath: '/', 45 | }, 46 | exportStatic: {}, 47 | esbuild: {}, 48 | mock: false, 49 | }); 50 | -------------------------------------------------------------------------------- /code-nav-main/config/defaultSettings.ts: -------------------------------------------------------------------------------- 1 | import { Settings as ProSettings } from '@ant-design/pro-layout'; 2 | 3 | type DefaultSettings = Partial & { 4 | pwa: boolean; 5 | }; 6 | 7 | const proSettings: DefaultSettings = { 8 | navTheme: 'light', 9 | primaryColor: '#1890ff', 10 | layout: 'top', 11 | contentWidth: 'Fluid', 12 | fixedHeader: false, 13 | fixSiderbar: true, 14 | colorWeak: false, 15 | title: '编程导航', 16 | pwa: false, 17 | iconfontUrl: '', 18 | }; 19 | 20 | export type { DefaultSettings }; 21 | 22 | export default proSettings; 23 | -------------------------------------------------------------------------------- /code-nav-main/config/menu.tsx: -------------------------------------------------------------------------------- 1 | import {MenuDataItem} from "@ant-design/pro-layout"; 2 | import * as React from "react"; 3 | import { 4 | FieldBinaryOutlined, 5 | ContainerOutlined, 6 | } from '@ant-design/icons'; 7 | 8 | /** 9 | * 菜单项 10 | */ 11 | export default [ 12 | { 13 | path: "/resources/tutorial", 14 | name: "找教程", 15 | icon: , 16 | }, 17 | { 18 | path: "/resources/basic", 19 | name: "必修基础", 20 | icon: , 21 | children: [ 22 | { 23 | path: "/resources/algorithm", 24 | name: "算法数据结构" 25 | }, 26 | { 27 | path: "/resources/system", 28 | name: "计算机系统" 29 | }, 30 | ] 31 | }, 32 | ] as MenuDataItem[]; 33 | -------------------------------------------------------------------------------- /code-nav-main/config/proxy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 在生产环境 代理是无法生效的,所以这里没有生产环境的配置 3 | * The agent cannot take effect in the production environment 4 | * so there is no configuration of the production environment 5 | * For details, please see 6 | * https://pro.ant.design/docs/deploy 7 | */ 8 | export default { 9 | dev: { 10 | '/api/': { 11 | target: 'https://preview.pro.ant.design', 12 | changeOrigin: true, 13 | pathRewrite: { '^': '' }, 14 | }, 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /code-nav-main/doc/db.md: -------------------------------------------------------------------------------- 1 | # 数据库设计文档 2 | 3 | 4 | 5 | ## 枚举类 6 | 7 | 举报原因 8 | 9 | | 值 | 描述 | 10 | | ---- | -------- | 11 | | 0 | 内容过期 | 12 | | 1 | 内容错误 | 13 | | 2 | 内容不当 | 14 | | 3 | 恶意引流 | 15 | | 100 | 其他 | 16 | 17 | 举报类型 18 | 19 | | 值 | 描述 | 20 | | ---- | ---- | 21 | | 0 | 资源 | 22 | 23 | 审核状态 24 | 25 | | 值 | 描述 | 26 | | ---- | ------ | 27 | | 0 | 审核中 | 28 | | 1 | 已发布 | 29 | | 2 | 拒绝 | 30 | 31 | 积分得失原因 32 | 33 | | 值 | 描述 | 34 | | ---- | ----------- | 35 | | 0 | 每日登录 +1 | 36 | | 1 | 推荐资源 +5 | 37 | | 2 | 发表评论 +1 | 38 | | 3 | 举报资源 +2 | 39 | | 4 | 首次填写自我介绍 +5 | 40 | -------------------------------------------------------------------------------- /code-nav-main/docker/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | # gzip config 4 | gzip on; 5 | gzip_min_length 1k; 6 | gzip_comp_level 9; 7 | gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml; 8 | gzip_vary on; 9 | gzip_disable "MSIE [1-6]\."; 10 | 11 | root /usr/share/nginx/html; 12 | include /etc/nginx/mime.types; 13 | 14 | if ($http_host ~ "^code-nav.cn") { 15 | rewrite ^(.*) https://www.code-nav.cn permanent; 16 | } 17 | 18 | location / { 19 | try_files $uri $uri /index.html; 20 | } 21 | 22 | location = /robots.txt { 23 | allow all; 24 | log_not_found off; 25 | access_log off; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /code-nav-main/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "emitDecoratorMetadata": true, 4 | "experimentalDecorators": true, 5 | "baseUrl": ".", 6 | "paths": { 7 | "@/*": ["./src/*"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /code-nav-main/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/public/logo.png -------------------------------------------------------------------------------- /code-nav-main/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Crawl-delay: 30 3 | User-agent: * 4 | Disallow: -------------------------------------------------------------------------------- /code-nav-main/src/assets/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/src/assets/default.jpg -------------------------------------------------------------------------------- /code-nav-main/src/assets/defaultCover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/src/assets/defaultCover.png -------------------------------------------------------------------------------- /code-nav-main/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/src/assets/logo.png -------------------------------------------------------------------------------- /code-nav-main/src/assets/qrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/src/assets/qrcode.jpg -------------------------------------------------------------------------------- /code-nav-main/src/assets/wechat.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/src/assets/wechat.jpeg -------------------------------------------------------------------------------- /code-nav-main/src/cardList.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | 3 | .cardList { 4 | column-count: 1; 5 | 6 | .card { 7 | :global { 8 | .ant-card-meta-title { 9 | margin-bottom: 12px; 10 | & > a { 11 | display: inline-block; 12 | max-width: 100%; 13 | color: @heading-color; 14 | } 15 | } 16 | 17 | .ant-card-body:hover { 18 | .ant-card-meta-title > a { 19 | color: @primary-color; 20 | } 21 | } 22 | } 23 | } 24 | 25 | :global { 26 | .ant-list .ant-list-item-content-single { 27 | max-width: 100%; 28 | } 29 | 30 | .ant-list-item { 31 | padding-top: 0; 32 | border-bottom: 0; 33 | height: 100%; 34 | overflow: auto; 35 | -webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */ 36 | page-break-inside: avoid; /* Firefox */ 37 | break-inside: avoid; /* IE 10+ */ 38 | } 39 | 40 | .ant-list-pagination { 41 | column-span: all; 42 | } 43 | } 44 | } 45 | 46 | @media screen and (min-width: @screen-sm) { 47 | .cardList { 48 | column-count: 2; 49 | -moz-column-count: 2; /* Firefox */ 50 | -webkit-column-count: 2; /* Safari and Chrome */ 51 | } 52 | } 53 | 54 | @media screen and (min-width: @screen-xl) { 55 | .cardList { 56 | column-count: 3; 57 | -moz-column-count: 3; /* Firefox */ 58 | -webkit-column-count: 3; /* Safari and Chrome */ 59 | } 60 | } 61 | 62 | @media screen and (min-width: @screen-xxl) { 63 | .cardList { 64 | column-count: 4; 65 | -moz-column-count: 4; /* Firefox */ 66 | -webkit-column-count: 4; /* Safari and Chrome */ 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /code-nav-main/src/components/Authorized/Authorized.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Result } from 'antd'; 3 | import check, { IAuthorityType } from './CheckPermissions'; 4 | 5 | import AuthorizedRoute from './AuthorizedRoute'; 6 | import Secured from './Secured'; 7 | 8 | interface AuthorizedProps { 9 | authority: IAuthorityType; 10 | noMatch?: React.ReactNode; 11 | } 12 | 13 | type IAuthorizedType = React.FunctionComponent & { 14 | Secured: typeof Secured; 15 | check: typeof check; 16 | AuthorizedRoute: typeof AuthorizedRoute; 17 | }; 18 | 19 | const Authorized: React.FunctionComponent = ({ 20 | children, 21 | authority, 22 | noMatch = ( 23 | 28 | ), 29 | }) => { 30 | const childrenRender: React.ReactNode = typeof children === 'undefined' ? null : children; 31 | const dom = check(authority, childrenRender, noMatch); 32 | return <>{dom}; 33 | }; 34 | 35 | export default Authorized as IAuthorizedType; 36 | -------------------------------------------------------------------------------- /code-nav-main/src/components/Authorized/AuthorizedRoute.tsx: -------------------------------------------------------------------------------- 1 | import { Redirect, Route } from 'umi'; 2 | 3 | import React from 'react'; 4 | import Authorized from './Authorized'; 5 | import { IAuthorityType } from './CheckPermissions'; 6 | 7 | interface AuthorizedRouteProps { 8 | currentAuthority: string; 9 | component: React.ComponentClass; 10 | render: (props: any) => React.ReactNode; 11 | redirectPath: string; 12 | authority: IAuthorityType; 13 | } 14 | 15 | const AuthorizedRoute: React.SFC = ({ 16 | component: Component, 17 | render, 18 | authority, 19 | redirectPath, 20 | ...rest 21 | }) => ( 22 | } />} 25 | > 26 | (Component ? : render(props))} 29 | /> 30 | 31 | ); 32 | 33 | export default AuthorizedRoute; 34 | -------------------------------------------------------------------------------- /code-nav-main/src/components/Authorized/index.tsx: -------------------------------------------------------------------------------- 1 | import Authorized from './Authorized'; 2 | import Secured from './Secured'; 3 | import check from './CheckPermissions'; 4 | import renderAuthorize from './renderAuthorize'; 5 | 6 | Authorized.Secured = Secured; 7 | Authorized.check = check; 8 | 9 | const RenderAuthorize = renderAuthorize(Authorized); 10 | 11 | export default RenderAuthorize; 12 | -------------------------------------------------------------------------------- /code-nav-main/src/components/Authorized/renderAuthorize.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable eslint-comments/disable-enable-pair */ 2 | /* eslint-disable import/no-mutable-exports */ 3 | let CURRENT: string | string[] = 'NULL'; 4 | 5 | type CurrentAuthorityType = string | string[] | (() => typeof CURRENT); 6 | /** 7 | * use authority or getAuthority 8 | * @param {string|()=>String} currentAuthority 9 | */ 10 | const renderAuthorize = (Authorized: T): ((currentAuthority: CurrentAuthorityType) => T) => ( 11 | currentAuthority: CurrentAuthorityType, 12 | ): T => { 13 | if (currentAuthority) { 14 | if (typeof currentAuthority === 'function') { 15 | CURRENT = currentAuthority(); 16 | } 17 | if ( 18 | Object.prototype.toString.call(currentAuthority) === '[object String]' || 19 | Array.isArray(currentAuthority) 20 | ) { 21 | CURRENT = currentAuthority as string[]; 22 | } 23 | } else { 24 | CURRENT = 'NULL'; 25 | } 26 | return Authorized; 27 | }; 28 | 29 | export { CURRENT }; 30 | export default (Authorized: T) => renderAuthorize(Authorized); 31 | -------------------------------------------------------------------------------- /code-nav-main/src/components/GlobalFooter/index.tsx: -------------------------------------------------------------------------------- 1 | import { DefaultFooter } from '@ant-design/pro-layout'; 2 | import { Tooltip } from 'antd'; 3 | import { GithubOutlined, InfoCircleOutlined, WechatOutlined } from '@ant-design/icons'; 4 | import wechat from '@/assets/wechat.jpeg'; 5 | import React from 'react'; 6 | 7 | const GlobalFooter: React.FC = () => { 8 | return ( 9 | 16 | 支持项目 17 | 18 | ), 19 | href: 'https://github.com/liyupi/code-nav', 20 | blankTarget: true, 21 | }, 22 | { 23 | key: 'contact', 24 | title: ( 25 | }> 26 | 联系作者 27 | 28 | ), 29 | href: 'https://doc.code-nav.cn/author', 30 | blankTarget: true, 31 | }, 32 | { 33 | key: 'info', 34 | title: ( 35 | <> 36 | 免责声明 37 | 38 | ), 39 | href: 'https://doc.code-nav.cn/#%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E', 40 | blankTarget: true, 41 | }, 42 | ]} 43 | /> 44 | ); 45 | }; 46 | 47 | export default GlobalFooter; 48 | -------------------------------------------------------------------------------- /code-nav-main/src/components/GlobalHeader/RightContent.tsx: -------------------------------------------------------------------------------- 1 | import { Settings as ProSettings } from '@ant-design/pro-layout'; 2 | import React from 'react'; 3 | import { Link } from 'umi'; 4 | import { SendOutlined } from '@ant-design/icons'; 5 | import { Button, Tooltip } from 'antd'; 6 | import AvatarDropdown from './AvatarDropdown'; 7 | import styles from './index.less'; 8 | 9 | interface GlobalHeaderRightProps extends Partial { 10 | theme?: ProSettings['navTheme'] | 'realDark'; 11 | } 12 | 13 | const isMobile = () => { 14 | const deviceWidth = document.querySelector('body')?.offsetWidth; 15 | return deviceWidth && deviceWidth < 480; 16 | }; 17 | 18 | const GlobalHeaderRight: React.SFC = (props) => { 19 | const { theme, layout } = props; 20 | let className = styles.right; 21 | 22 | if (theme === 'dark' && layout === 'top') { 23 | className = `${styles.right} ${styles.dark}`; 24 | } 25 | 26 | return ( 27 |
28 | {!isMobile() && ( 29 | 30 | 31 | 38 | 39 | 40 | )} 41 | 42 |
43 | ); 44 | }; 45 | 46 | export default GlobalHeaderRight; 47 | -------------------------------------------------------------------------------- /code-nav-main/src/components/HeaderSearch/index.less: -------------------------------------------------------------------------------- 1 | .headerSearch { 2 | display: flex; 3 | } 4 | -------------------------------------------------------------------------------- /code-nav-main/src/components/NoAuth/index.tsx: -------------------------------------------------------------------------------- 1 | import {Button, Result} from "antd"; 2 | import * as React from "react"; 3 | import {Link} from 'umi'; 4 | import {stringify} from "qs"; 5 | import {FC} from "react"; 6 | 7 | export const NoAuth: FC = () => { 8 | return ( 9 | 14 | 20 | 一键登录 21 | 22 | 23 | } 24 | /> 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /code-nav-main/src/components/PicUploader/index.less: -------------------------------------------------------------------------------- 1 | .avatar-uploader > .ant-upload { 2 | width: 128px; 3 | height: 128px; 4 | } 5 | -------------------------------------------------------------------------------- /code-nav-main/src/components/PicUploader/service.ts: -------------------------------------------------------------------------------- 1 | import {getApp} from "@/tcb"; 2 | import {message} from "antd"; 3 | 4 | const app = getApp(); 5 | 6 | export function uploadFile(file: File) { 7 | return app.uploadFile({ 8 | cloudPath: `img/${new Date().getTime()}-${file.name}`, 9 | // @ts-ignore 10 | filePath: file, 11 | }).catch(e => { 12 | message.error('上传失败,请重试'); 13 | }); 14 | } 15 | 16 | export function getFileUrl(fileId: any) { 17 | return app.getTempFileURL({ 18 | fileList: [fileId] 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /code-nav-main/src/components/ResourceCard/index.less: -------------------------------------------------------------------------------- 1 | .card :global { 2 | user-select: none; 3 | width: 100%; 4 | margin: 0 auto; 5 | 6 | .ant-card-body { 7 | padding-bottom: 12px; 8 | } 9 | 10 | .ant-card-body:hover .ant-card-meta-title { 11 | color: #1890ff !important; 12 | } 13 | } 14 | 15 | .cardMeta :global { 16 | .ant-card-meta-avatar { 17 | width: 35% !important; 18 | max-width: 80px; 19 | padding-right: 0; 20 | margin-right: 16px; 21 | } 22 | 23 | .ant-avatar { 24 | width: 100%; 25 | height: auto; 26 | border-radius: 5px; 27 | min-height: 80px; 28 | display: flex; 29 | align-items: center; 30 | background: #fafafa; 31 | } 32 | 33 | .ant-card-meta-title { 34 | font-size: 17px !important; 35 | } 36 | 37 | .ant-card-meta-description { 38 | min-height: 66px; 39 | } 40 | 41 | } 42 | 43 | .starRate :global { 44 | font-size: 12px; 45 | width: 100%; 46 | text-align: center; 47 | 48 | .ant-rate-star { 49 | margin-right: 1px; 50 | margin-left: 1px; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /code-nav-main/src/components/SelectTags/index.less: -------------------------------------------------------------------------------- 1 | .ant-tabs-content-holder { 2 | padding-bottom: 16px !important; 3 | } 4 | -------------------------------------------------------------------------------- /code-nav-main/src/components/TagList/index.less: -------------------------------------------------------------------------------- 1 | .tagList { 2 | margin-top: 16px; 3 | text-align: right; 4 | 5 | :global { 6 | .ant-tag { 7 | margin-top: 8px; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /code-nav-main/src/constant/categoryMap.ts: -------------------------------------------------------------------------------- 1 | interface CategoryType { 2 | name: string; 3 | mapTag: string; 4 | } 5 | 6 | declare type CategoryMapType = { [key: string]: CategoryType }; 7 | 8 | /** 9 | * 分类专栏映射 10 | */ 11 | export const CATEGORY_MAP: CategoryMapType = { 12 | tutorial: { 13 | name: '贴心教程', 14 | mapTag: '教程', 15 | }, 16 | algorithm: { 17 | name: '算法数据结构', 18 | mapTag: '算法', 19 | }, 20 | system: { 21 | name: '计算机系统', 22 | mapTag: '系统', 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /code-nav-main/src/constant/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 登录 Cookie 键名 3 | */ 4 | export const LOGIN_STATUS = 'loginStatus'; 5 | 6 | /** 7 | * url 动态码键名 8 | */ 9 | export const DYNAMIC_CAPTCHA = 'dc'; 10 | 11 | /** 12 | * 网站域名 13 | * @type {string} 14 | */ 15 | export const WEB_HOST = 'https://www.code-nav.cn'; 16 | 17 | /** 18 | * 云函数请求域名 19 | * @type {string} 20 | */ 21 | export const CLOUD_FUNCTION_HOST = 'https://your-domain'; 22 | 23 | /** 24 | * 分页列表状态键名 25 | */ 26 | export const PRE_PAGE_STATE = 'prePageState'; 27 | 28 | /** 29 | * 用户搜索历史 LocalStorage 键名 30 | */ 31 | export const SEARCH_HISTORY_KEY = 'searchHistory'; 32 | -------------------------------------------------------------------------------- /code-nav-main/src/constant/level.ts: -------------------------------------------------------------------------------- 1 | export interface LevelType { 2 | score: number; 3 | name: string; 4 | color: string; 5 | } 6 | 7 | export const LEVELS = [{ 8 | score: 30, 9 | name: '1 级', 10 | color: 'green', 11 | }, { 12 | score: 100, 13 | name: '2 级', 14 | color: 'cyan', 15 | }] as LevelType[]; 16 | -------------------------------------------------------------------------------- /code-nav-main/src/constant/message.ts: -------------------------------------------------------------------------------- 1 | export const MESSAGE_TYPE_MAP = { 2 | 0: '系统消息', 3 | }; 4 | 5 | export const MESSAGE_STATUS_MAP = { 6 | 0: '未读', 7 | 1: '已读', 8 | }; 9 | 10 | export const MESSAGE_TYPE_ENUM = { 11 | SYSTEM: 0, 12 | }; 13 | 14 | export const MESSAGE_STATUS_ENUM = { 15 | UNREAD: 0, 16 | HAS_READ: 1, 17 | }; 18 | -------------------------------------------------------------------------------- /code-nav-main/src/constant/reportReasonEnum.ts: -------------------------------------------------------------------------------- 1 | const reportReasonEnum = { 2 | CONTENT_EXPIRED: 0, 3 | CONTENT_ERROR: 1, 4 | OTHERS: 100, 5 | }; 6 | 7 | /** 8 | * 举报原因信息映射 9 | */ 10 | export const REPORT_REASON_MAP = { 11 | 0: { 12 | text: '内容过期', 13 | }, 14 | 1: { 15 | text: '内容错误', 16 | }, 17 | 100: { 18 | text: '其他', 19 | } 20 | } 21 | 22 | /** 23 | * 举报类型映射 24 | */ 25 | export const REPORT_REASON_OPTIONS = [ 26 | { label: '内容过期', value: reportReasonEnum.CONTENT_EXPIRED }, 27 | { label: '内容错误', value: reportReasonEnum.CONTENT_ERROR }, 28 | { label: '其他', value: reportReasonEnum.OTHERS }, 29 | ]; 30 | 31 | export default reportReasonEnum; 32 | -------------------------------------------------------------------------------- /code-nav-main/src/constant/reportTypeEnum.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | RESOURCE: 0, 3 | }; 4 | 5 | /** 6 | * 举报类型信息映射 7 | */ 8 | export const REPORT_TYPE_MAP = { 9 | 0: { 10 | text: '资源', 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/src/constant/reviewStatusEnum.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | REVIEWING: 0, 3 | PASS: 1, 4 | REJECT: 2, 5 | } 6 | 7 | /** 8 | * 审核状态信息映射 9 | */ 10 | export const reviewStatusInfoMap = { 11 | 0: { 12 | text: '审核中', 13 | color: 'blue', 14 | }, 15 | 1: { 16 | text: '已发布', 17 | color: 'green', 18 | }, 19 | 2: { 20 | text: '拒绝', 21 | color: 'red', 22 | } 23 | } 24 | 25 | /** 26 | * 审核状态信息映射 27 | */ 28 | export const REVIEW_STATUS_MAP = { 29 | 0: '审核中', 30 | 1: '已发布', 31 | 2: '拒绝', 32 | } 33 | -------------------------------------------------------------------------------- /code-nav-main/src/global.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | 3 | html, 4 | body, 5 | #root { 6 | height: 100%; 7 | } 8 | 9 | .colorWeak { 10 | filter: invert(80%); 11 | } 12 | 13 | .ant-layout { 14 | min-height: 100vh; 15 | } 16 | 17 | .ant-layout-header { 18 | position: sticky; 19 | top: 0; 20 | } 21 | 22 | .ant-page-header { 23 | margin: 0 auto; 24 | } 25 | 26 | .ant-pro-global-footer { 27 | margin-top: 24px; 28 | } 29 | 30 | .ant-radio-wrapper { 31 | margin-bottom: 8px; 32 | } 33 | 34 | canvas { 35 | display: block; 36 | } 37 | 38 | body { 39 | text-rendering: optimizeLegibility; 40 | -webkit-font-smoothing: antialiased; 41 | -moz-osx-font-smoothing: grayscale; 42 | overflow-y: auto !important; 43 | } 44 | 45 | ul, 46 | ol { 47 | list-style: none; 48 | } 49 | 50 | .hidden { 51 | display: none; 52 | } 53 | 54 | @media (max-width: @screen-xs) { 55 | .ant-table { 56 | width: 100%; 57 | overflow-x: auto; 58 | &-thead > tr, 59 | &-tbody > tr { 60 | > th, 61 | > td { 62 | white-space: pre; 63 | > span { 64 | display: block; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | // 兼容IE11 72 | @media screen and(-ms-high-contrast: active), (-ms-high-contrast: none) { 73 | body .ant-design-pro > .ant-layout { 74 | min-height: 100vh; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /code-nav-main/src/layouts/BasicLayout.less: -------------------------------------------------------------------------------- 1 | .ant-pro-top-menu, .ant-layout-header { 2 | height: 64px !important; 3 | line-height: 64px !important; 4 | } 5 | 6 | .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item, .ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu { 7 | margin-top: -2px !important; 8 | } 9 | 10 | .header-search-bar { 11 | flex: 1; 12 | min-width: 120px; 13 | max-width: 500px; 14 | } 15 | 16 | @media (min-width: 480px) { 17 | .header-search-bar { 18 | margin-left: 20px; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /code-nav-main/src/layouts/UserLayout.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | 3 | .container { 4 | display: flex; 5 | flex-direction: column; 6 | height: 100vh; 7 | overflow: auto; 8 | background: @layout-body-background; 9 | } 10 | 11 | .lang { 12 | width: 100%; 13 | height: 40px; 14 | line-height: 44px; 15 | text-align: right; 16 | :global(.ant-dropdown-trigger) { 17 | margin-right: 24px; 18 | } 19 | } 20 | 21 | .content { 22 | flex: 1; 23 | padding: 32px 0; 24 | } 25 | 26 | @media (min-width: @screen-md-min) { 27 | .container { 28 | background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg'); 29 | background-repeat: no-repeat; 30 | background-position: center 110px; 31 | background-size: 100%; 32 | } 33 | 34 | .content { 35 | padding: 32px 0 24px; 36 | } 37 | } 38 | 39 | .top { 40 | text-align: center; 41 | } 42 | 43 | .header { 44 | height: 44px; 45 | line-height: 44px; 46 | a { 47 | text-decoration: none; 48 | } 49 | } 50 | 51 | .logo { 52 | height: 44px; 53 | margin-right: 16px; 54 | vertical-align: top; 55 | } 56 | 57 | .title { 58 | position: relative; 59 | top: 2px; 60 | color: @heading-color; 61 | font-weight: 600; 62 | font-size: 33px; 63 | font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif; 64 | } 65 | 66 | .desc { 67 | margin-top: 12px; 68 | margin-bottom: 24px; 69 | color: @text-color-secondary; 70 | font-size: @font-size-base; 71 | } 72 | -------------------------------------------------------------------------------- /code-nav-main/src/layouts/UserLayout.tsx: -------------------------------------------------------------------------------- 1 | import { getPageTitle } from '@ant-design/pro-layout'; 2 | import { Helmet, HelmetProvider } from 'react-helmet-async'; 3 | import type { ConnectProps} from 'umi'; 4 | import { connect, Link } from 'umi'; 5 | import React from 'react'; 6 | import GlobalFooter from '@/components/GlobalFooter'; 7 | import logo from '../assets/logo.png'; 8 | import defaultSettings from '../../config/defaultSettings'; 9 | import styles from './UserLayout.less'; 10 | 11 | export type UserLayoutProps = Partial 12 | 13 | const UserLayout: React.FC = (props) => { 14 | const { 15 | children, 16 | location = { 17 | pathname: '', 18 | }, 19 | } = props; 20 | const title = getPageTitle({ 21 | pathname: location.pathname, 22 | ...defaultSettings, 23 | }); 24 | return ( 25 | 26 | 27 | {title} 28 | 29 | 30 | 31 |
32 |
33 |
34 |
35 | 36 | logo 37 | 编程导航 38 | 39 |
40 |
发现优质编程学习资源
41 |
42 | {children} 43 |
44 | 45 |
46 |
47 | ); 48 | }; 49 | 50 | export default connect()(UserLayout); 51 | -------------------------------------------------------------------------------- /code-nav-main/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "编程导航", 3 | "short_name": "Code Nav", 4 | "display": "standalone", 5 | "start_url": "./?utm_source=homescreen", 6 | "theme_color": "#002140", 7 | "background_color": "#001529", 8 | "icons": [ 9 | { 10 | "src": "icons/icon-192x192.png", 11 | "sizes": "192x192" 12 | }, 13 | { 14 | "src": "icons/icon-128x128.png", 15 | "sizes": "128x128" 16 | }, 17 | { 18 | "src": "icons/icon-512x512.png", 19 | "sizes": "512x512" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /code-nav-main/src/models/comment.d.ts: -------------------------------------------------------------------------------- 1 | import type { SimpleUser } from '@/models/user'; 2 | 3 | /** 4 | * 评论类型 5 | */ 6 | export interface CommentType { 7 | _id: string; 8 | userId: string; 9 | resourceId: string; 10 | content: string; 11 | rate: number; 12 | thumbNum: number; 13 | reviewStatus: number; 14 | reviewMessage?: string; 15 | reviewerId?: string; 16 | reviewTime?: Date; 17 | isDelete?: boolean; 18 | _createTime?: Date; 19 | } 20 | 21 | /** 22 | * 评论类型(封装用户信息) 23 | */ 24 | export interface CommentUserType extends CommentType { 25 | userInfo: SimpleUser[]; 26 | isThumb?: boolean; 27 | } 28 | -------------------------------------------------------------------------------- /code-nav-main/src/models/connect.d.ts: -------------------------------------------------------------------------------- 1 | import type { MenuDataItem } from '@ant-design/pro-layout'; 2 | import type { UserModelState } from './user'; 3 | import type { LoginType } from './login'; 4 | import type { TagModelState } from './tag'; 5 | import type { ResourceModelState } from './resource'; 6 | 7 | export interface Loading { 8 | global: boolean; 9 | effects: Record; 10 | models: { 11 | menu?: boolean; 12 | user?: boolean; 13 | login?: boolean; 14 | resource?: boolean; 15 | tag?: boolean; 16 | }; 17 | } 18 | 19 | export interface ConnectState { 20 | loading: Loading; 21 | user: UserModelState; 22 | login: LoginType; 23 | resource: ResourceModelState; 24 | tag: TagModelState; 25 | } 26 | 27 | export interface Route extends MenuDataItem { 28 | routes?: Route[]; 29 | } 30 | -------------------------------------------------------------------------------- /code-nav-main/src/models/message.d.ts: -------------------------------------------------------------------------------- 1 | export interface MessageType { 2 | _id: string; 3 | title?: string; 4 | content?: string; 5 | fromUserId?: string; 6 | toUserId?: string; 7 | status?: number; 8 | type?: number; 9 | _createTime?: Date; 10 | _updateTime?: Date; 11 | readTime?: Date; 12 | isDelete?: boolean; 13 | } 14 | -------------------------------------------------------------------------------- /code-nav-main/src/models/notice.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 公告类型 3 | */ 4 | export interface NoticeType { 5 | _id: string; 6 | userId: string; 7 | title: string; 8 | content?: string; 9 | isDelete?: boolean; 10 | _createTime?: Date; 11 | _updateTime?: Date; 12 | } 13 | -------------------------------------------------------------------------------- /code-nav-main/src/models/report.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 举报类型 3 | */ 4 | export interface ReportType { 5 | _id: string; 6 | reporterId: string; 7 | reportedUserId?: string; 8 | reportResourceId?: string; 9 | reportType: number; 10 | reportReason: number; 11 | reportDetail?: string; 12 | reviewStatus: number; 13 | reviewMessage?: string; 14 | reviewerId: string; 15 | reviewTime?: Date; 16 | isDelete?: boolean; 17 | _createTime?: Date; 18 | _updateTime?: Date; 19 | } 20 | -------------------------------------------------------------------------------- /code-nav-main/src/models/tag.ts: -------------------------------------------------------------------------------- 1 | import type { Effect, Reducer } from 'umi'; 2 | import { getTags } from '@/services/tag'; 3 | import { message } from 'antd'; 4 | 5 | export type TagType = string; 6 | 7 | export interface GroupTag { 8 | name: string; 9 | tags: TagType[]; 10 | } 11 | 12 | declare type categoryTagsMapType = Record; 13 | 14 | export interface WholeTagsMap { 15 | hotTags: TagType[]; 16 | allTags: TagType[]; 17 | groupTags: GroupTag[]; 18 | userIntroduceGroupTags: GroupTag[]; 19 | categoryTagsMap: categoryTagsMapType; 20 | } 21 | 22 | export interface TagModelState { 23 | wholeTagsMap: WholeTagsMap; 24 | } 25 | 26 | export interface TagModelType { 27 | namespace: 'tag'; 28 | state: TagModelState; 29 | effects: { 30 | get: Effect; 31 | }; 32 | reducers: { 33 | setWholeTagsMap: Reducer; 34 | }; 35 | } 36 | 37 | const Model: TagModelType = { 38 | namespace: 'tag', 39 | 40 | state: { 41 | wholeTagsMap: { hotTags: [], groupTags: [], userIntroduceGroupTags: [], allTags: [], categoryTagsMap: {} }, 42 | }, 43 | 44 | effects: { 45 | *get({ payload }, { call, put }) { 46 | const response = yield call(getTags, payload); 47 | if (response) { 48 | yield put({ 49 | type: 'setWholeTagsMap', 50 | payload: response, 51 | }); 52 | } else { 53 | message.error('获取标签失败,请刷新页面'); 54 | } 55 | }, 56 | }, 57 | 58 | reducers: { 59 | setWholeTagsMap(state, action) { 60 | return { 61 | ...state, 62 | wholeTagsMap: action.payload, 63 | }; 64 | }, 65 | }, 66 | }; 67 | 68 | export default Model; 69 | -------------------------------------------------------------------------------- /code-nav-main/src/models/userIntroduce.ts: -------------------------------------------------------------------------------- 1 | import type {TagType} from "@/models/tag"; 2 | import type {SimpleUser} from "@/models/user"; 3 | 4 | /** 5 | * 用户介绍 6 | */ 7 | export interface UserIntroduceType { 8 | _id: string; 9 | userId: string; 10 | content: string; 11 | thumbNum: number; 12 | reviewStatus: number; 13 | reviewMessage?: string; 14 | contact: string; 15 | tags: TagType[]; 16 | isDelete?: boolean; 17 | _createTime?: Date; 18 | _updateTime?: Date; 19 | } 20 | 21 | /** 22 | * 用户介绍(封装用户信息) 23 | */ 24 | export interface UserIntroduceUserType extends UserIntroduceType { 25 | userInfo: SimpleUser[]; 26 | isThumb?: boolean; 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/404.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Result } from 'antd'; 2 | import React from 'react'; 3 | import { history } from 'umi'; 4 | 5 | const NoFoundPage: React.FC<{}> = () => ( 6 | history.push('/')}> 11 | 返回首页 12 | 13 | } 14 | /> 15 | ); 16 | 17 | export default NoFoundPage; 18 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/AccountCenter/MyInfo/Center.less: -------------------------------------------------------------------------------- 1 | .avatarHolder { 2 | text-align: center; 3 | margin-bottom: 24px; 4 | 5 | .avatar { 6 | width: 104px; 7 | height: 104px; 8 | margin-bottom: 20px; 9 | border-radius: 50%; 10 | border: 1px solid #eee; 11 | } 12 | 13 | .name { 14 | margin-bottom: 4px; 15 | font-weight: 500; 16 | font-size: 20px; 17 | line-height: 28px; 18 | } 19 | } 20 | 21 | :global { 22 | .ant-descriptions-item-content { 23 | display: block !important; 24 | } 25 | 26 | .ant-descriptions-header { 27 | margin-bottom: 8px; 28 | } 29 | 30 | .ant-tag { 31 | margin-top: 8px; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/AccountCenter/MyMessages/style.less: -------------------------------------------------------------------------------- 1 | .message-list-item:hover { 2 | background-color: rgba(0, 0, 0, .02); 3 | transition: background-color .3s; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/AddResource/style.less: -------------------------------------------------------------------------------- 1 | .myCascader :global { 2 | .ant-cascader-menu { 3 | height: auto; 4 | max-height: 450px; 5 | min-width: 130px; 6 | } 7 | 8 | .ant-cascader-menu-item { 9 | padding: 12px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/AddSucceed/index.less: -------------------------------------------------------------------------------- 1 | .addSucceed { 2 | :global { 3 | .ant-result { 4 | padding: 0; 5 | } 6 | 7 | .ant-result-title { 8 | margin-bottom: 16px; 9 | } 10 | 11 | .ant-card { 12 | margin: 0 auto; 13 | } 14 | } 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/Friend/MyFriendModal/style.less: -------------------------------------------------------------------------------- 1 | .myCascader :global { 2 | .ant-cascader-menu { 3 | height: auto; 4 | max-height: 450px; 5 | min-width: 130px; 6 | } 7 | 8 | .ant-cascader-menu-item { 9 | padding: 12px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/Friend/style.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/src/pages/Friend/style.less -------------------------------------------------------------------------------- /code-nav-main/src/pages/Ranking/style.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liyupi/code-nav/287826658469d8a84bad52df9f974956e172d07a/code-nav-main/src/pages/Ranking/style.less -------------------------------------------------------------------------------- /code-nav-main/src/pages/Recommend/style.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | @import './utils/utils.less'; 3 | 4 | .newButton { 5 | width: 100%; 6 | height: 201px; 7 | color: @text-color-secondary; 8 | background-color: @component-background; 9 | border-color: @border-color-base; 10 | } 11 | 12 | .cardAvatar { 13 | width: 48px; 14 | height: 48px; 15 | border-radius: 48px; 16 | } 17 | 18 | .cardDescription { 19 | .textOverflowMulti(); 20 | } 21 | 22 | .pageHeaderContent { 23 | position: relative; 24 | } 25 | 26 | .contentLink { 27 | margin-top: 16px; 28 | a { 29 | margin-right: 32px; 30 | img { 31 | width: 24px; 32 | } 33 | } 34 | img { 35 | margin-right: 8px; 36 | vertical-align: middle; 37 | } 38 | } 39 | 40 | @media screen and (max-width: @screen-lg) { 41 | .contentLink { 42 | a { 43 | margin-right: 16px; 44 | } 45 | } 46 | } 47 | 48 | @media screen and (max-width: @screen-md) { 49 | .extraImg { 50 | display: none; 51 | } 52 | } 53 | 54 | @media screen and (max-width: @screen-sm) { 55 | .contentLink { 56 | position: absolute; 57 | bottom: -4px; 58 | left: 0; 59 | width: 1000px; 60 | a { 61 | margin-right: 16px; 62 | } 63 | img { 64 | margin-right: 4px; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/Recommend/utils/utils.less: -------------------------------------------------------------------------------- 1 | .textOverflow() { 2 | overflow: hidden; 3 | white-space: nowrap; 4 | text-overflow: ellipsis; 5 | word-break: break-all; 6 | } 7 | 8 | .textOverflowMulti(@line: 3, @bg: #fff) { 9 | position: relative; 10 | max-height: @line * 1.5em; 11 | margin-right: -1em; 12 | padding-right: 1em; 13 | overflow: hidden; 14 | line-height: 1.5em; 15 | text-align: justify; 16 | &::before { 17 | position: absolute; 18 | right: 14px; 19 | bottom: 0; 20 | padding: 0 1px; 21 | background: @bg; 22 | content: '...'; 23 | } 24 | &::after { 25 | position: absolute; 26 | right: 14px; 27 | width: 1em; 28 | height: 1em; 29 | margin-top: 0.2em; 30 | background: white; 31 | content: ''; 32 | } 33 | } 34 | 35 | // mixins for clearfix 36 | // ------------------------ 37 | .clearfix() { 38 | zoom: 1; 39 | &::before, 40 | &::after { 41 | display: table; 42 | content: ' '; 43 | } 44 | &::after { 45 | clear: both; 46 | height: 0; 47 | font-size: 0; 48 | visibility: hidden; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/ResourceDetail/components/CommentList/index.less: -------------------------------------------------------------------------------- 1 | .rank :global { 2 | margin-left: 8px; 3 | font-size: 14px; 4 | 5 | .ant-rate-star:not(:last-child) { 6 | margin-right: 2px; 7 | } 8 | } 9 | 10 | :global { 11 | .ant-comment-inner { 12 | padding: 8px 0 0 !important;; 13 | } 14 | 15 | .ant-pagination { 16 | margin: 12px 0 !important; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/ResourceDetail/components/SimilarResources/index.tsx: -------------------------------------------------------------------------------- 1 | import { List } from 'antd'; 2 | import React, { useEffect, useState } from 'react'; 3 | import type { ResourceType } from '@/models/resource'; 4 | import ResourceCard from '@/components/ResourceCard'; 5 | import { searchResources } from '@/services/resource'; 6 | import reviewStatusEnum from '@/constant/reviewStatusEnum'; 7 | 8 | interface SimilarResourcesProps { 9 | // 参照资源 10 | resource?: ResourceType; 11 | } 12 | 13 | /** 14 | * 相似资源 15 | * @param props 16 | * @constructor 17 | */ 18 | const SimilarResources: React.FC = (props) => { 19 | const { resource } = props; 20 | 21 | const [resources, setResources] = useState([]); 22 | const [loading, setLoading] = useState(true); 23 | 24 | useEffect(() => { 25 | if (resource) { 26 | searchResources({ 27 | tags: [resource.tags[0]], 28 | pageSize: 3, 29 | reviewStatus: reviewStatusEnum.PASS, 30 | notId: resource._id, 31 | }) 32 | .then((res: ResourceType[]) => { 33 | setResources(res); 34 | }) 35 | .finally(() => { 36 | setLoading(false); 37 | }); 38 | } 39 | }, [resource]); 40 | 41 | return ( 42 | 43 | rowKey="id" 44 | dataSource={resources} 45 | split={false} 46 | loading={loading} 47 | renderItem={(item) => { 48 | return ( 49 | 50 | 51 | 52 | ); 53 | }} 54 | /> 55 | ); 56 | }; 57 | 58 | export default SimilarResources; 59 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/ResourceDetail/index.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | 3 | .avatarHolder { 4 | margin-bottom: 24px; 5 | text-align: center; 6 | 7 | :global { 8 | .ant-image { 9 | margin-bottom: 16px; 10 | } 11 | 12 | .ant-image-img { 13 | width: auto; 14 | max-width: 100%; 15 | } 16 | } 17 | 18 | .name { 19 | margin-bottom: 8px; 20 | color: @heading-color; 21 | font-weight: 500; 22 | font-size: 24px; 23 | letter-spacing: 1px; 24 | } 25 | } 26 | 27 | 28 | .subTitle { 29 | margin-bottom: 24px; 30 | color: @heading-color; 31 | font-weight: 500; 32 | font-size: 17px; 33 | } 34 | 35 | .tagBar { 36 | margin-bottom: 24px; 37 | user-select: none; 38 | } 39 | 40 | .starRate :global { 41 | font-size: 14px; 42 | 43 | .ant-rate-star-first .anticon, .ant-rate-star-second .anticon { 44 | vertical-align: text-bottom !important; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/Resources/TagSelect/index.less: -------------------------------------------------------------------------------- 1 | @import '../../../../node_modules/antd/es/style/themes/default.less'; 2 | 3 | .tagSelect { 4 | position: relative; 5 | max-height: 32px; 6 | margin-left: -8px; 7 | overflow: hidden; 8 | line-height: 32px; 9 | transition: all 0.3s; 10 | user-select: none; 11 | :global { 12 | .ant-tag { 13 | margin-right: 24px; 14 | padding: 0 8px; 15 | font-size: @font-size-base; 16 | } 17 | } 18 | &.expanded { 19 | max-height: 200px; 20 | transition: all 0.3s; 21 | } 22 | .trigger { 23 | position: absolute; 24 | top: 0; 25 | right: 0; 26 | 27 | span.anticon { 28 | font-size: 12px; 29 | } 30 | } 31 | &.hasExpandTag { 32 | padding-right: 50px; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/Resources/style.less: -------------------------------------------------------------------------------- 1 | .myCascader :global { 2 | .ant-cascader-menu { 3 | height: auto; 4 | max-height: 450px; 5 | min-width: 130px; 6 | } 7 | 8 | .ant-cascader-menu-item { 9 | padding: 12px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /code-nav-main/src/pages/user/login/index.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | 3 | .main { 4 | width: 260px; 5 | margin: 0 auto; 6 | @media screen and (max-width: @screen-sm) { 7 | width: 95%; 8 | max-width: 260px; 9 | } 10 | 11 | :global { 12 | .@{ant-prefix}-tabs-nav-list { 13 | margin: auto; 14 | font-size: 16rpx; 15 | } 16 | .ant-tabs-tab { 17 | margin: 0; 18 | } 19 | } 20 | 21 | .qrcode { 22 | width: 100%; 23 | margin-bottom: 24px; 24 | } 25 | 26 | .icon { 27 | margin-left: 16px; 28 | color: rgba(0, 0, 0, 0.2); 29 | font-size: 24px; 30 | vertical-align: middle; 31 | cursor: pointer; 32 | transition: color 0.3s; 33 | 34 | &:hover { 35 | color: @primary-color; 36 | } 37 | } 38 | 39 | .other { 40 | margin-top: 24px; 41 | line-height: 22px; 42 | text-align: left; 43 | .register { 44 | float: right; 45 | } 46 | } 47 | 48 | .prefixIcon { 49 | color: @primary-color; 50 | font-size: @font-size-base; 51 | margin-right: 5px; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /code-nav-main/src/services/login.ts: -------------------------------------------------------------------------------- 1 | import { getCurrentUser, getUserById } from '@/services/user'; 2 | import { getApp, tcbCustomLogin, tcbLogout } from '@/tcb'; 3 | import { getMockData, MOCK_OPEN } from '../../mock'; 4 | 5 | const app = getApp(); 6 | 7 | export interface LoginParamsType { 8 | captcha: string; 9 | type: string; 10 | userId?: string; 11 | } 12 | 13 | /** 14 | * 用户登录 15 | * @param params 16 | * @return user 17 | */ 18 | export async function login(params: LoginParamsType) { 19 | if (MOCK_OPEN) { 20 | return getMockData(login.name); 21 | } 22 | // tcb 登录 23 | const loginState = await tcbCustomLogin(params.captcha); 24 | if (!loginState || loginState.loginType !== 'CUSTOM' || !loginState.user.customUserId) { 25 | return null; 26 | } 27 | // 自动登录 28 | if (params.userId) { 29 | return getUserById(params.userId); 30 | } 31 | // 首次登录 32 | return getCurrentUser(loginState.user.customUserId); 33 | } 34 | 35 | /** 36 | * 用户退出登录 37 | */ 38 | export function logout() { 39 | return tcbLogout(); 40 | } 41 | 42 | /** 43 | * 每日登录 44 | */ 45 | export async function doDailyLogin() { 46 | return app 47 | .callFunction({ 48 | name: 'doDailyLogin', 49 | }) 50 | .then((res) => res.result) 51 | .catch((err) => { 52 | console.error('doDailyLogin error', err); 53 | return false; 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /code-nav-main/src/services/searchHistory.ts: -------------------------------------------------------------------------------- 1 | import { SEARCH_HISTORY_KEY } from '@/constant'; 2 | 3 | const SEARCH_HISTORY_MAX_LENGTH = 10; 4 | 5 | /** 6 | * 添加搜索历史 7 | * @param searchText 8 | */ 9 | export function addSearchHistory(searchText: string) { 10 | if (!searchText) { 11 | return; 12 | } 13 | const historyList = listSearchHistory(); 14 | const index = historyList.indexOf(searchText); 15 | // 没有搜索记录,把搜索值 push 进数组首位 16 | if (index < 0) { 17 | historyList.unshift(searchText); 18 | } else { 19 | // 有搜索记录,删除旧记录,重新push到数组首位 20 | historyList.splice(index, 1); 21 | historyList.unshift(searchText); 22 | } 23 | // 长度限制 24 | if (historyList.length > SEARCH_HISTORY_MAX_LENGTH) { 25 | historyList.splice(SEARCH_HISTORY_MAX_LENGTH, historyList.length - SEARCH_HISTORY_MAX_LENGTH); 26 | } 27 | updateSearchHistory(historyList); 28 | } 29 | 30 | /** 31 | * 清空搜索历史 32 | */ 33 | export function deleteAllSearchHistory() { 34 | localStorage.removeItem(SEARCH_HISTORY_KEY); 35 | } 36 | 37 | /** 38 | * 删除指定搜索历史 39 | * @param searchText 40 | */ 41 | export function deleteSearchHistory(searchText: string) { 42 | const historyList = listSearchHistory(); 43 | const index = historyList.indexOf(searchText); 44 | if (index > -1) { 45 | historyList.splice(index, 1); 46 | } 47 | updateSearchHistory(historyList); 48 | } 49 | 50 | /** 51 | * 获取搜索历史 52 | */ 53 | export function listSearchHistory() { 54 | return JSON.parse(localStorage.getItem(SEARCH_HISTORY_KEY) ?? '[]'); 55 | } 56 | 57 | /** 58 | * 更新搜索历史 59 | * @param historyList 60 | */ 61 | export function updateSearchHistory(historyList: string[]) { 62 | localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(historyList)); 63 | } 64 | -------------------------------------------------------------------------------- /code-nav-main/src/services/tag.ts: -------------------------------------------------------------------------------- 1 | import {getApp} from "@/tcb"; 2 | import {getMockData, MOCK_OPEN} from "../../mock"; 3 | 4 | const app = getApp(); 5 | 6 | /** 7 | * 获取标签 8 | */ 9 | export function getTags() { 10 | if (MOCK_OPEN) { 11 | return getMockData(getTags.name); 12 | } 13 | 14 | return app.callFunction({ 15 | name: 'getTags', 16 | data: {} 17 | }).then((res: any) => { 18 | console.log(`getTags succeed`); 19 | return res.result; 20 | }).catch((e: any) => { 21 | console.error(`getTags error`, e); 22 | return false; 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /code-nav-main/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'slash2'; 2 | declare module '*.css'; 3 | declare module '*.less'; 4 | declare module '*.scss'; 5 | declare module '*.sass'; 6 | declare module '*.svg'; 7 | declare module '*.png'; 8 | declare module '*.jpg'; 9 | declare module '*.jpeg'; 10 | declare module '*.gif'; 11 | declare module '*.bmp'; 12 | declare module '*.tiff'; 13 | declare module 'omit.js'; 14 | 15 | // google analytics interface 16 | interface GAFieldsObject { 17 | eventCategory: string; 18 | eventAction: string; 19 | eventLabel?: string; 20 | eventValue?: number; 21 | nonInteraction?: boolean; 22 | } 23 | interface Window { 24 | ga: ( 25 | command: 'send', 26 | hitType: 'event' | 'pageview', 27 | fieldsObject: GAFieldsObject | string, 28 | ) => void; 29 | reloadAuthorized: () => void; 30 | } 31 | 32 | declare let ga: Function; 33 | 34 | declare const REACT_APP_ENV: 'test' | 'dev' | 'pre' | false; 35 | -------------------------------------------------------------------------------- /code-nav-main/src/utils/Authorized.ts: -------------------------------------------------------------------------------- 1 | import RenderAuthorize from '@/components/Authorized'; 2 | import { getAuthority } from './authority'; 3 | /* eslint-disable eslint-comments/disable-enable-pair */ 4 | /* eslint-disable import/no-mutable-exports */ 5 | let Authorized = RenderAuthorize(getAuthority()); 6 | 7 | // Reload the rights component 8 | const reloadAuthorized = (): void => { 9 | Authorized = RenderAuthorize(getAuthority()); 10 | }; 11 | 12 | /** 13 | * hard code 14 | * block need it。 15 | */ 16 | window.reloadAuthorized = reloadAuthorized; 17 | 18 | export { reloadAuthorized }; 19 | export default Authorized; 20 | -------------------------------------------------------------------------------- /code-nav-main/src/utils/authority.ts: -------------------------------------------------------------------------------- 1 | import { reloadAuthorized } from './Authorized'; 2 | 3 | // use localStorage to store the authority info, which might be sent from server in actual project. 4 | export function getAuthority(str?: string): string | string[] { 5 | const authorityString = 6 | typeof str === 'undefined' && localStorage ? localStorage.getItem('antd-pro-authority') : str; 7 | // authorityString could be admin, "admin", ["admin"] 8 | let authority; 9 | try { 10 | if (authorityString) { 11 | authority = JSON.parse(authorityString); 12 | } 13 | } catch (e) { 14 | authority = authorityString; 15 | } 16 | if (typeof authority === 'string') { 17 | return [authority]; 18 | } 19 | return authority; 20 | } 21 | 22 | export function setAuthority(authority: string | string[]): void { 23 | const proAuthority = typeof authority === 'string' ? [authority] : authority; 24 | localStorage.setItem('antd-pro-authority', JSON.stringify(proAuthority)); 25 | // auto reload 26 | reloadAuthorized(); 27 | } 28 | -------------------------------------------------------------------------------- /code-nav-main/src/utils/businessUtils.ts: -------------------------------------------------------------------------------- 1 | import {WEB_HOST} from '@/constant'; 2 | import {addShareNum} from '@/services/resource'; 3 | import {message} from 'antd'; 4 | import type {ResourceType} from '@/models/resource'; 5 | import type { LevelType} from '@/constant/level'; 6 | import {LEVELS} from '@/constant/level'; 7 | import copy from 'copy-to-clipboard'; 8 | 9 | /** 10 | * 分享资源 11 | */ 12 | export const doShare = async (resource?: ResourceType) => { 13 | // 复制到剪切板,分享数 +1 14 | if (resource && resource._id) { 15 | copy(`我在编程导航发现了『 ${resource.name} 』💎 快来看看 ${WEB_HOST}/rd/?rid=${resource._id}`); 16 | addShareNum(resource._id); 17 | message.success('链接已复制,感谢分享!'); 18 | } 19 | }; 20 | 21 | /** 22 | * 根据积分获取等级 23 | * @param score 24 | */ 25 | export const getLevel = (score?: number): LevelType => { 26 | if (!score) { 27 | return LEVELS[0]; 28 | } 29 | for (let i = 0; i < LEVELS.length; i += 1) { 30 | if (score < LEVELS[i].score) { 31 | return LEVELS[i]; 32 | } 33 | } 34 | return LEVELS[LEVELS.length - 1]; 35 | }; 36 | -------------------------------------------------------------------------------- /code-nav-main/src/utils/request.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * request 网络请求工具 3 | * 更详细的 api 文档: https://github.com/umijs/umi-request 4 | */ 5 | import { extend } from 'umi-request'; 6 | import { notification } from 'antd'; 7 | 8 | const codeMessage = { 9 | 200: '服务器成功返回请求的数据。', 10 | 201: '新建或修改数据成功。', 11 | 202: '一个请求已经进入后台排队(异步任务)。', 12 | 204: '删除数据成功。', 13 | 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', 14 | 401: '用户没有权限(令牌、用户名、密码错误)。', 15 | 403: '用户得到授权,但是访问是被禁止的。', 16 | 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', 17 | 406: '请求的格式不可得。', 18 | 410: '请求的资源被永久删除,且不会再得到的。', 19 | 422: '当创建一个对象时,发生一个验证错误。', 20 | 500: '服务器发生错误,请检查服务器。', 21 | 502: '网关错误。', 22 | 503: '服务不可用,服务器暂时过载或维护。', 23 | 504: '网关超时。', 24 | }; 25 | 26 | /** 27 | * 异常处理程序 28 | */ 29 | const errorHandler = (error: { response: Response }): Response => { 30 | const { response } = error; 31 | if (response && response.status) { 32 | const errorText = codeMessage[response.status] || response.statusText; 33 | const { status, url } = response; 34 | 35 | notification.error({ 36 | message: `请求错误 ${status}: ${url}`, 37 | description: errorText, 38 | }); 39 | } else if (!response) { 40 | notification.error({ 41 | description: '您的网络发生异常,无法连接服务器', 42 | message: '网络异常', 43 | }); 44 | } 45 | return response; 46 | }; 47 | 48 | /** 49 | * 配置request请求时的默认参数 50 | */ 51 | const request = extend({ 52 | errorHandler, // 默认错误处理 53 | credentials: 'include', // 默认请求是否带上cookie 54 | }); 55 | 56 | export default request; 57 | -------------------------------------------------------------------------------- /code-nav-main/src/utils/utils.less: -------------------------------------------------------------------------------- 1 | // mixins for clearfix 2 | // ------------------------ 3 | .clearfix() { 4 | zoom: 1; 5 | &::before, 6 | &::after { 7 | display: table; 8 | content: ' '; 9 | } 10 | &::after { 11 | clear: both; 12 | height: 0; 13 | font-size: 0; 14 | visibility: hidden; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /code-nav-main/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "build/dist", 4 | "module": "esnext", 5 | "target": "esnext", 6 | "lib": ["esnext", "dom"], 7 | "sourceMap": true, 8 | "baseUrl": ".", 9 | "jsx": "react-jsx", 10 | "resolveJsonModule": true, 11 | "allowSyntheticDefaultImports": true, 12 | "moduleResolution": "node", 13 | "forceConsistentCasingInFileNames": true, 14 | "noImplicitReturns": true, 15 | "suppressImplicitAnyIndexErrors": true, 16 | "noUnusedLocals": true, 17 | "allowJs": true, 18 | "skipLibCheck": true, 19 | "experimentalDecorators": true, 20 | "strict": true, 21 | "paths": { 22 | "@/*": ["./src/*"], 23 | "@@/*": ["./src/.umi/*"] 24 | } 25 | }, 26 | "include": [ 27 | "mock/**/*", 28 | "src/**/*", 29 | "tests/**/*", 30 | "test/**/*", 31 | "__test__/**/*", 32 | "typings/**/*", 33 | "config/**/*", 34 | ".eslintrc.js", 35 | ".stylelintrc.js", 36 | ".prettierrc.js", 37 | "jest.config.js", 38 | "mock/*" 39 | ], 40 | "exclude": ["node_modules", "build", "dist", "scripts", "src/.umi/*", "webpack", "jest"] 41 | } 42 | -------------------------------------------------------------------------------- /code-nav-mp-server/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | log 7 | logs 8 | .DS_Store 9 | 10 | ### STS ### 11 | .apt_generated 12 | .classpath 13 | .factorypath 14 | .project 15 | .settings 16 | .springBeans 17 | .sts4-cache 18 | 19 | ### IntelliJ IDEA ### 20 | .idea 21 | *.iws 22 | *.iml 23 | *.ipr 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | build/ 32 | !**/src/main/**/build/ 33 | !**/src/test/**/build/ 34 | 35 | ### VS Code ### 36 | .vscode/ 37 | /.mvn/ 38 | -------------------------------------------------------------------------------- /code-nav-mp-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | 3 | VOLUME /tmp 4 | 5 | ADD ./target/code-nav-mp-server-0.0.1.jar code-nav-mp-server.jar 6 | 7 | EXPOSE 8080 8 | 9 | ENTRYPOINT ["java", "-jar", "code-nav-mp-server.jar", "--spring.profiles.active=prod"] 10 | -------------------------------------------------------------------------------- /code-nav-mp-server/README.md: -------------------------------------------------------------------------------- 1 | # 编程导航微信公众号服务端 2 | 3 | 对接编程导航公众号,提供获取动态码、关注回复、动态菜单等功能。 4 | 5 | 6 | 7 | ## 已有功能 8 | 9 | **关注后回复消息** 10 | 11 | **收到消息后回复消息** 12 | 13 | ![公众号回复消息](https://qiniuyun.code-nav.cn/%E5%85%AC%E4%BC%97%E5%8F%B7%E5%9B%9E%E5%A4%8D%E6%B6%88%E6%81%AF.png) 14 | 15 | **自定义菜单项** 16 | 17 | **点击菜单获取动态码** 18 | 19 | ![](https://qiniuyun.code-nav.cn/%E5%85%AC%E4%BC%97%E5%8F%B7%E4%B8%80%E9%94%AE%E7%99%BB%E5%BD%95-20210527012441318.png) 20 | 21 | 22 | 23 | 24 | 25 | ## 快速开始 26 | 27 | 1. 下载项目 28 | 2. 使用 IDEA 打开项目,修改 `resources/application` 文件的公众号配置,进入公众号后台获取: 29 | 30 | ```properties 31 | wx.mp.appId= 32 | wx.mp.secret= 33 | wx.mp.token= 34 | wx.mp.aesKey= 35 | ``` 36 | 37 | 3. 使用 Maven `spring-boot:build-image` 构建,在 target 目录下能看到生成的 jar 包 38 | 4. 可以在服务器启动 jar 包,或直接用 Dockerfile 构建镜像部署在容器中(推荐腾讯云云托管) 39 | 40 | 41 | 42 | ## 技术选型 43 | 44 | 1. Java 编程语言 45 | 2. [WxJava](https://github.com/Wechat-Group/WxJava) 微信公众号后台开发类库 46 | 3. SpringBoot 47 | 4. Maven 包管理 48 | 5. 腾讯云开发云函数 49 | 6. 腾讯云开发云托管部署 50 | 7. Logback 日志 51 | -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/java/com/codenav/mp/server/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.codenav.mp.server; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | /** 9 | * 启动类(编程导航微信公众号服务端) 10 | * 11 | * @author 程序员鱼皮 12 | * @desc 分享编程学习经验 13 | **/ 14 | @RestController 15 | @RequestMapping("/") 16 | @SpringBootApplication 17 | public class MyApplication { 18 | 19 | public static void main(String[] args) { 20 | SpringApplication.run(MyApplication.class, args); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/java/com/codenav/mp/server/constant/CommonConstant.java: -------------------------------------------------------------------------------- 1 | package com.codenav.mp.server.constant; 2 | 3 | /** 4 | * 常量 5 | * 6 | * @author yupili 7 | **/ 8 | public class CommonConstant { 9 | 10 | /** 11 | * 网站域名 12 | */ 13 | public static final String WEB_HOST = "https://xxx"; 14 | 15 | /** 16 | * 来源 17 | */ 18 | public static final String FROM = "mp"; 19 | 20 | /** 21 | * 登录菜单 key 22 | */ 23 | public static final String LOGIN_MENU_KEY = "LOGIN_MENU_KEY"; 24 | } 25 | -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/java/com/codenav/mp/server/handler/MessageHandler.java: -------------------------------------------------------------------------------- 1 | package com.codenav.mp.server.handler; 2 | 3 | import java.util.Map; 4 | import me.chanjar.weixin.common.error.WxErrorException; 5 | import me.chanjar.weixin.common.session.WxSessionManager; 6 | import me.chanjar.weixin.mp.api.WxMpMessageHandler; 7 | import me.chanjar.weixin.mp.api.WxMpService; 8 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; 9 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; 10 | import org.springframework.stereotype.Component; 11 | 12 | /** 13 | * 消息处理器 14 | * 15 | * @author yupili 16 | **/ 17 | @Component 18 | public class MessageHandler implements WxMpMessageHandler { 19 | 20 | @Override 21 | public WxMpXmlOutMessage handle(WxMpXmlMessage wxMpXmlMessage, Map map, 22 | WxMpService wxMpService, WxSessionManager wxSessionManager) throws WxErrorException { 23 | String content = "不太懂您的问题哦,请添加微信 liyupi66 交流反馈"; 24 | // 根据消息内容给出回复 25 | switch (wxMpXmlMessage.getContent()) { 26 | case "领资料": 27 | content = "关注公众号【程序员鱼皮】领编程学习资源!\n" 28 | + "欢迎关注"; 29 | break; 30 | case "测试消息": 31 | content = "哈哈不错"; 32 | break; 33 | default: 34 | break; 35 | } 36 | 37 | return WxMpXmlOutMessage.TEXT().content(content) 38 | .fromUser(wxMpXmlMessage.getToUser()) 39 | .toUser(wxMpXmlMessage.getFromUser()) 40 | .build(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/java/com/codenav/mp/server/model/GetCaptchaResponse.java: -------------------------------------------------------------------------------- 1 | package com.codenav.mp.server.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * GetCaptchaResponse 7 | * 8 | * @author yupili 9 | **/ 10 | public class GetCaptchaResponse implements Serializable { 11 | 12 | private static final long serialVersionUID = 4200328781716962658L; 13 | 14 | private boolean result; 15 | 16 | private String captcha; 17 | 18 | public boolean isResult() { 19 | return result; 20 | } 21 | 22 | public void setResult(boolean result) { 23 | this.result = result; 24 | } 25 | 26 | public String getCaptcha() { 27 | return captcha; 28 | } 29 | 30 | public void setCaptcha(String captcha) { 31 | this.captcha = captcha; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "GetCaptchaResponse{" + 37 | "result=" + result + 38 | ", captcha='" + captcha + '\'' + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/java/com/codenav/mp/server/service/CommonService.java: -------------------------------------------------------------------------------- 1 | package com.codenav.mp.server.service; 2 | 3 | import com.codenav.mp.server.model.GetCaptchaResponse; 4 | import me.chanjar.weixin.common.error.WxErrorException; 5 | import me.chanjar.weixin.mp.api.WxMpService; 6 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; 7 | 8 | /** 9 | * 公共服务 10 | * 11 | * @author yupili 12 | **/ 13 | public interface CommonService { 14 | 15 | /** 16 | * 登录 17 | * 18 | * @param wxMpXmlMessage 19 | * @param wxMpService 20 | * @return 21 | */ 22 | GetCaptchaResponse login(WxMpXmlMessage wxMpXmlMessage, WxMpService wxMpService) 23 | throws WxErrorException; 24 | } 25 | -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/resources/application-dev.properties: -------------------------------------------------------------------------------- 1 | # 本地开发 2 | # base 3 | wx.mp.appId=到公众号后台获取 4 | wx.mp.secret=到公众号后台获取 5 | wx.mp.token=到公众号后台获取 6 | wx.mp.aesKey=到公众号后台获取 7 | -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/resources/application-prod.properties: -------------------------------------------------------------------------------- 1 | # 线上 2 | # base 3 | wx.mp.appId=到公众号后台获取 4 | wx.mp.secret=到公众号后台获取 5 | wx.mp.token=到公众号后台获取 6 | wx.mp.aesKey=到公众号后台获取 -------------------------------------------------------------------------------- /code-nav-mp-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # 线上 2 | # base 3 | wx.mp.appId=到公众号后台获取 4 | wx.mp.secret=到公众号后台获取 5 | wx.mp.token=到公众号后台获取 6 | wx.mp.aesKey=到公众号后台获取 7 | # redis 8 | wx.mp.config-storage.type=Memory 9 | wx.mp.config-storage.key-prefix=wx 10 | wx.mp.config-storage.redis.host=127.0.0.1 11 | wx.mp.config-storage.redis.port=6379 12 | # http 13 | wx.mp.config-storage.http-client-type=HttpClient 14 | wx.mp.config-storage.http-proxy-host= 15 | wx.mp.config-storage.http-proxy-port= 16 | wx.mp.config-storage.http-proxy-username= 17 | wx.mp.config-storage.http-proxy-password= --------------------------------------------------------------------------------