diff --git a/package.json b/package.json index a7a6619..cbaace0 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ }, "dependencies": { "@ant-design/icons": "^5.2.6", + "@reduxjs/toolkit": "^1.9.7", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-react": "^1.0.6", "antd": "^5.9.4", @@ -30,6 +31,7 @@ "pubsub-js": "^1.9.4", "react": "^18.1.0", "react-dom": "^18.1.0", + "react-redux": "^8.1.3", "react-router-dom": "^6.16.0", "swiper": "^11.0.4", "wangeditor": "^4.7.15" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86ffcd1..8280495 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ dependencies: '@ant-design/icons': specifier: ^5.2.6 version: registry.npmmirror.com/@ant-design/icons@5.2.6(react-dom@18.1.0)(react@18.1.0) + '@reduxjs/toolkit': + specifier: ^1.9.7 + version: registry.npmmirror.com/@reduxjs/toolkit@1.9.7(react-redux@8.1.3)(react@18.1.0) '@wangeditor/editor': specifier: ^5.1.23 version: registry.npmmirror.com/@wangeditor/editor@5.1.23 @@ -32,6 +35,9 @@ dependencies: react-dom: specifier: ^18.1.0 version: 18.1.0(react@18.1.0) + react-redux: + specifier: ^8.1.3 + version: registry.npmmirror.com/react-redux@8.1.3(@types/react-dom@18.0.5)(@types/react@18.0.9)(react-dom@18.1.0)(react@18.1.0)(redux@4.2.1) react-router-dom: specifier: ^6.16.0 version: registry.npmmirror.com/react-router-dom@6.16.0(react-dom@18.1.0)(react@18.1.0) @@ -701,13 +707,11 @@ packages: /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} - dev: true /@types/react-dom@18.0.5: resolution: {integrity: sha512-OWPWTUrY/NIrjsAPkAk1wW9LZeIjSvkXRhclsFO8CZcZGCOg2G0YZy4ft+rOyYxy8B7ui5iZzi9OkDebZ7/QSA==} dependencies: '@types/react': 18.0.9 - dev: true /@types/react@18.0.9: resolution: {integrity: sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw==} @@ -715,11 +719,9 @@ packages: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 csstype: 3.1.0 - dev: true /@types/scheduler@0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - dev: true /@typescript-eslint/eslint-plugin@5.27.0(@typescript-eslint/parser@5.27.0)(eslint@8.16.0)(typescript@4.7.2): resolution: {integrity: sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==} @@ -1227,7 +1229,6 @@ packages: /csstype@3.1.0: resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==} - dev: true /cz-customizable@6.3.0: resolution: {integrity: sha512-MWGmWa45v4Ds3NJNNwQc3GCFdjtH3k4ypDWoWkwultMVLf7aOHR9VaXGYGZHLOQS4sMfbkBSjNUYoXCSmLuRSA==} @@ -4382,6 +4383,28 @@ packages: react-dom: 18.1.0(react@18.1.0) dev: false + registry.npmmirror.com/@reduxjs/toolkit@1.9.7(react-redux@8.1.3)(react@18.1.0): + resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@reduxjs/toolkit/-/toolkit-1.9.7.tgz} + id: registry.npmmirror.com/@reduxjs/toolkit/1.9.7 + name: '@reduxjs/toolkit' + version: 1.9.7 + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 + react-redux: ^7.2.1 || ^8.0.2 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + dependencies: + immer: registry.npmmirror.com/immer@9.0.21 + react: 18.1.0 + react-redux: registry.npmmirror.com/react-redux@8.1.3(@types/react-dom@18.0.5)(@types/react@18.0.9)(react-dom@18.1.0)(react@18.1.0)(redux@4.2.1) + redux: registry.npmmirror.com/redux@4.2.1 + redux-thunk: registry.npmmirror.com/redux-thunk@2.4.2(redux@4.2.1) + reselect: registry.npmmirror.com/reselect@4.1.8 + dev: false + registry.npmmirror.com/@remix-run/router@1.9.0: resolution: {integrity: sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@remix-run/router/-/router-1.9.0.tgz} name: '@remix-run/router' @@ -4425,6 +4448,15 @@ packages: version: 0.3.4 dev: false + registry.npmmirror.com/@types/hoist-non-react-statics@3.3.5: + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz} + name: '@types/hoist-non-react-statics' + version: 3.3.5 + dependencies: + '@types/react': registry.npmmirror.com/@types/react@18.0.9 + hoist-non-react-statics: registry.npmmirror.com/hoist-non-react-statics@3.3.2 + dev: false + registry.npmmirror.com/@types/json-schema@7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.11.tgz} name: '@types/json-schema' @@ -4437,6 +4469,34 @@ packages: version: 17.0.36 dev: true + registry.npmmirror.com/@types/prop-types@15.7.5: + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.5.tgz} + name: '@types/prop-types' + version: 15.7.5 + dev: false + + registry.npmmirror.com/@types/react@18.0.9: + resolution: {integrity: sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/react/-/react-18.0.9.tgz} + name: '@types/react' + version: 18.0.9 + dependencies: + '@types/prop-types': registry.npmmirror.com/@types/prop-types@15.7.5 + '@types/scheduler': registry.npmmirror.com/@types/scheduler@0.16.2 + csstype: registry.npmmirror.com/csstype@3.1.0 + dev: false + + registry.npmmirror.com/@types/scheduler@0.16.2: + resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/scheduler/-/scheduler-0.16.2.tgz} + name: '@types/scheduler' + version: 0.16.2 + dev: false + + registry.npmmirror.com/@types/use-sync-external-store@0.0.3: + resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz} + name: '@types/use-sync-external-store' + version: 0.0.3 + dev: false + registry.npmmirror.com/@uppy/companion-client@2.2.2: resolution: {integrity: sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@uppy/companion-client/-/companion-client-2.2.2.tgz} name: '@uppy/companion-client' @@ -5438,6 +5498,14 @@ packages: engines: {node: '>=8'} dev: true + registry.npmmirror.com/hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz} + name: hoist-non-react-statics + version: 3.3.2 + dependencies: + react-is: registry.npmmirror.com/react-is@16.13.1 + dev: false + registry.npmmirror.com/html-void-elements@2.0.1: resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-void-elements/-/html-void-elements-2.0.1.tgz} name: html-void-elements @@ -6900,6 +6968,49 @@ packages: version: 16.13.1 dev: false + registry.npmmirror.com/react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz} + name: react-is + version: 18.2.0 + dev: false + + registry.npmmirror.com/react-redux@8.1.3(@types/react-dom@18.0.5)(@types/react@18.0.9)(react-dom@18.1.0)(react@18.1.0)(redux@4.2.1): + resolution: {integrity: sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-redux/-/react-redux-8.1.3.tgz} + id: registry.npmmirror.com/react-redux/8.1.3 + name: react-redux + version: 8.1.3 + peerDependencies: + '@types/react': ^16.8 || ^17.0 || ^18.0 + '@types/react-dom': ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + react-native: '>=0.59' + redux: ^4 || ^5.0.0-beta.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + react-dom: + optional: true + react-native: + optional: true + redux: + optional: true + dependencies: + '@babel/runtime': registry.npmmirror.com/@babel/runtime@7.23.1 + '@types/hoist-non-react-statics': registry.npmmirror.com/@types/hoist-non-react-statics@3.3.5 + '@types/react': 18.0.9 + '@types/react-dom': 18.0.5 + '@types/use-sync-external-store': registry.npmmirror.com/@types/use-sync-external-store@0.0.3 + hoist-non-react-statics: registry.npmmirror.com/hoist-non-react-statics@3.3.2 + react: 18.1.0 + react-dom: 18.1.0(react@18.1.0) + react-is: registry.npmmirror.com/react-is@18.2.0 + redux: registry.npmmirror.com/redux@4.2.1 + use-sync-external-store: registry.npmmirror.com/use-sync-external-store@1.2.0(react@18.1.0) + dev: false + registry.npmmirror.com/react-router-dom@6.16.0(react-dom@18.1.0)(react@18.1.0): resolution: {integrity: sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/react-router-dom/-/react-router-dom-6.16.0.tgz} id: registry.npmmirror.com/react-router-dom/6.16.0 @@ -6929,12 +7040,37 @@ packages: react: 18.1.0 dev: false + registry.npmmirror.com/redux-thunk@2.4.2(redux@4.2.1): + resolution: {integrity: sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/redux-thunk/-/redux-thunk-2.4.2.tgz} + id: registry.npmmirror.com/redux-thunk/2.4.2 + name: redux-thunk + version: 2.4.2 + peerDependencies: + redux: ^4 + dependencies: + redux: registry.npmmirror.com/redux@4.2.1 + dev: false + + registry.npmmirror.com/redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/redux/-/redux-4.2.1.tgz} + name: redux + version: 4.2.1 + dependencies: + '@babel/runtime': registry.npmmirror.com/@babel/runtime@7.23.1 + dev: false + registry.npmmirror.com/regenerator-runtime@0.14.0: resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz} name: regenerator-runtime version: 0.14.0 dev: false + registry.npmmirror.com/reselect@4.1.8: + resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/reselect/-/reselect-4.1.8.tgz} + name: reselect + version: 4.1.8 + dev: false + registry.npmmirror.com/resize-observer-polyfill@1.5.1: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz} name: resize-observer-polyfill @@ -7208,6 +7344,17 @@ packages: punycode: registry.npmmirror.com/punycode@2.1.1 dev: true + registry.npmmirror.com/use-sync-external-store@1.2.0(react@18.1.0): + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz} + id: registry.npmmirror.com/use-sync-external-store/1.2.0 + name: use-sync-external-store + version: 1.2.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.1.0 + dev: false + registry.npmmirror.com/util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz} name: util-deprecate diff --git a/src/App.less b/src/App.less index 8b051e6..b09a428 100644 --- a/src/App.less +++ b/src/App.less @@ -20,141 +20,10 @@ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently not supported by any browser */ + scrollbar-width: none; .content-box { width: 1439px; margin: 0 auto; overflow: auto; } } - -.header-navigator { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 50px; - min-width: 1439px; - background-color: #fff; - border-radius: 4px; -} - -.nav-title { - display: flex; - justify-content: space-between; - cursor: pointer; - width: 1407px; - margin: 0 auto; - line-height: 50px; - color: #1890ff; - font-size: 24px; - // font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", 微软雅黑, - // Arial, sans-serif; -} - -.header-navigator .user { - width: 36px; - height: 36px; - float: right; - /* background: #1890ff; */ - border-radius: 50%; - color: #fff; - margin-top: 7px; - line-height: 36px; - text-align: center; - font-size: 16px; - overflow: hidden; - box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.08); -} - -.jump-box { - font-size: 14px; - margin-right: 20px; -} - -.info-time-box { - display: flex; -} -.time-box { - margin-top: 8px; - margin-right: 120px; -} -.head-navigator-box { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 50px; - background-color: #fff; - border-radius: 4px; -} -.head-navigator { - display: flex; - align-items: center; - justify-content: space-between; - margin: 0 auto; - width: 1435px; -} -.head-navigator-left { - display: flex; - align-items: center; -} -.head-navigator-logo { - margin-right: 20px; - // line-height: 50px; - cursor: pointer; - color: #1890ff; - font-size: 24px; - // font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, 微软雅黑, - // Arial, sans-serif; -} -.head-navigator-select-box { - display: flex; - justify-content: space-between; - align-items: center; - width: 500px; -} - -.head-navigator-menu-box { - display: flex; -} -.head-navigator-menu-box .ant-menu-horizontal { - border-bottom: 0; -} -.ant-menu-horizontal > .ant-menu-item, -.ant-menu-horizontal > .ant-menu-submenu { - padding: 0px; - margin: 0 12px; -} -.head-navigator-input-box { - margin-right: 24px; -} -.head-navigator-input-box .ant-input { - border-radius: 16px; -} - -.head-navigator-user-box { - display: flex; - justify-content: center; - align-items: center; -} -.head-navigator-bell { - display: flex; - justify-content: center; - align-items: center; - margin-right: 24px; - width: 28px; - height: 28px; - border-radius: 50%; - cursor: pointer; -} -.head-navigator-bell:hover { - background-color: rgba(0, 10, 32, 0.03); -} -.head-navigator-user-img { - width: 36px; - height: 36px; - color: #fff; - cursor: pointer; - border-radius: 50%; - box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.08); -} diff --git a/src/components/question-list/index.jsx b/src/components/question-list/index.jsx index c9f0fb4..3265e22 100644 --- a/src/components/question-list/index.jsx +++ b/src/components/question-list/index.jsx @@ -133,7 +133,8 @@ const QuestionList = props => { * @returns */ const onChangeAction = item => () => { - navigate('/brush-question/' + item.id) + // navigate('/brush-question/' + item.id) + window.open('/brush-question/' + item.id, '_blank') // let { isNotToDetail } = props; // !isNotToDetail && // if (!isNotToDetail) return; diff --git a/src/main.tsx b/src/main.tsx index aed007f..7aa141a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,18 +1,17 @@ -import './main.less' -import React from 'react' -import ReactDOM from 'react-dom/client' import router from '@/router' -import { - RouterProvider, -} from "react-router-dom"; -import { ConfigProvider } from 'antd'; -import zhCN from 'antd/locale/zh_CN'; +import { ConfigProvider } from 'antd' +import zhCN from 'antd/locale/zh_CN' +import ReactDOM from 'react-dom/client' +import { Provider } from 'react-redux' +import { RouterProvider } from 'react-router-dom' +import store from './store/index.ts' +import './main.less' ReactDOM.createRoot(document.getElementById('root')!).render( - - + + - - + + ) diff --git a/src/router/index.tsx b/src/router/index.tsx index df5553d..03bba88 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -36,8 +36,8 @@ const router = createBrowserRouter([ Component: lazy(() => import('@views/search-details')) }, { - path: 'search-question', - Component: lazy(() => import('@views/search-question')) + path: 'personal-center', + Component: lazy(() => import('@views/personal-center')) } ] } diff --git a/src/store/features/userInfoSlice.ts b/src/store/features/userInfoSlice.ts new file mode 100644 index 0000000..7d0b0cc --- /dev/null +++ b/src/store/features/userInfoSlice.ts @@ -0,0 +1,28 @@ +import { createSlice } from '@reduxjs/toolkit' + +export interface CounterState { + value: number + title: string +} +const initialState: CounterState = { + value: 0, + title: 'redux toolkit pre' +} + +// 创建一个 Slice +export const userInfoSlice = createSlice({ + name: 'userInfo', + initialState, + // 定义 reducers 并生成关联的操作 + reducers: { + // 定义一个加的方法 + saveUserInfo: (state, { payload }) => { + state.value = payload + } + } +}) +// 导出加减的方法 +export const { saveUserInfo } = userInfoSlice.actions + +// 默认导出 +export default userInfoSlice.reducer diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..e0210f8 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,12 @@ +import { configureStore } from '@reduxjs/toolkit' +import userInfoSlice from './features/userInfoSlice.ts' + +// configureStore创建一个redux数据 +const store = configureStore({ + // 合并多个Slice + reducer: { + userInfo: userInfoSlice + } +}) + +export default store diff --git a/src/views/header/index.less b/src/views/header/index.less new file mode 100644 index 0000000..a95136a --- /dev/null +++ b/src/views/header/index.less @@ -0,0 +1,155 @@ +.header-navigator { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50px; + min-width: 1439px; + background-color: #fff; + border-radius: 4px; +} + +.nav-title { + display: flex; + justify-content: space-between; + cursor: pointer; + width: 1407px; + margin: 0 auto; + line-height: 50px; + color: #1890ff; + font-size: 24px; + // font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", 微软雅黑, + // Arial, sans-serif; +} + +.header-navigator .user { + width: 36px; + height: 36px; + float: right; + /* background: #1890ff; */ + border-radius: 50%; + color: #fff; + margin-top: 7px; + line-height: 36px; + text-align: center; + font-size: 16px; + overflow: hidden; + box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.08); +} + +.jump-box { + font-size: 14px; + margin-right: 20px; +} + +.drop-down-box { + display: flex; + background-color: #fff; + padding: 24px; + border-radius: 8px; + box-shadow: + 0 6px 16px 0 rgba(0, 0, 0, 0.08), + 0 3px 6px -4px rgba(0, 0, 0, 0.12), + 0 9px 28px 8px rgba(0, 0, 0, 0.05); + .drop-down-item { + background-color: #eee; + padding: 20px 30px; + text-align: center; + width: 200px; + border-radius: 8px; + cursor: pointer; + &:hover { + background-color: rgba(60, 110, 238, 0.9); + color: white; + } + &-title { + font-size: 18px; + font-weight: bold; + margin-bottom: 10px; + } + &-content { + font-size: 12px; + } + } +} + +.head-navigator-box { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50px; + background-color: #fff; + border-radius: 4px; +} +.head-navigator { + display: flex; + align-items: center; + justify-content: space-between; + margin: 0 auto; + width: 1435px; +} +.head-navigator-left { + display: flex; + align-items: center; +} +.head-navigator-logo { + margin-right: 20px; + // line-height: 50px; + cursor: pointer; + color: #1890ff; + font-size: 24px; + // font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, 微软雅黑, + // Arial, sans-serif; +} +.head-navigator-select-box { + display: flex; + justify-content: space-between; + align-items: center; + width: 500px; +} + +.head-navigator-menu-box { + display: flex; +} +.head-navigator-menu-box .ant-menu-horizontal { + border-bottom: 0; +} +.ant-menu-horizontal > .ant-menu-item, +.ant-menu-horizontal > .ant-menu-submenu { + padding: 0px; + margin: 0 12px; +} +.head-navigator-input-box { + margin-right: 24px; +} +.head-navigator-input-box .ant-input { + border-radius: 16px; +} + +.head-navigator-user-box { + display: flex; + justify-content: center; + align-items: center; +} +.head-navigator-bell { + display: flex; + justify-content: center; + align-items: center; + margin-right: 24px; + width: 28px; + height: 28px; + border-radius: 50%; + cursor: pointer; +} +.head-navigator-bell:hover { + background-color: rgba(0, 10, 32, 0.03); +} +.head-navigator-user-img { + width: 36px; + height: 36px; + color: #fff; + cursor: pointer; + border-radius: 50%; + box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.08); +} diff --git a/src/views/header/index.tsx b/src/views/header/index.tsx index 2fd8371..b8750d3 100644 --- a/src/views/header/index.tsx +++ b/src/views/header/index.tsx @@ -2,10 +2,13 @@ import Head from '@/imgs/head.jpg' import Logo from '@/imgs/logo.jpg' import { HeartOutlined, LikeOutlined, LoginOutlined, UserOutlined } from '@ant-design/icons' import TopMenu from '@components/top-menu' +import LoginQrcode from '@imgs/login_qrcode.jpg' import req from '@utils/request' -import { Dropdown, Input, Modal, message } from 'antd' +import { Button, Dropdown, Input, Modal, Popover, Space, message } from 'antd' import { useNavigate } from 'react-router-dom' +import './index.less' + const { Search } = Input const menuItems = [ @@ -34,6 +37,32 @@ const menuItems = [ } ] +const discoverItems = [ + { + title: '联系我', + subTitle: '一键添加鸡哥微信', + key: 'wechat' + }, + { + title: '跟我做', + subTitle: '从0到1做鸡翅Club项目', + key: 'club', + path: '' + }, + { + title: '更深入', + subTitle: '从0到1做企业级框架项目', + key: 'deep', + path: '' + }, + { + title: '加星球', + subTitle: '一键进入鸡哥的知识星球', + key: 'star', + path: '' + } +] + const Header = () => { const { pathname } = window.location const navigate = useNavigate() @@ -87,6 +116,12 @@ const Header = () => { navigate('/search-detail?t=' + value) } + const goPath = item => { + if (item.path) { + window.open(item.path, '_blank') + } + } + return (
@@ -97,7 +132,50 @@ const Header = () => {
-
+ { + return ( +
+ + {discoverItems.map(item => { + return ( +
goPath(item)}> + {item.key === 'wechat' ? ( + <> + { + return ( +
+ +
+ ) + }} + > +
{item.title}
+
{item.subTitle}
+
+ + ) : ( + <> +
{item.title}
+
{item.subTitle}
+ + )} +
+ ) + })} +
+
+ ) + }} + > + +
{'/question-bank' == pathname && (
{ />
)} - {/*
*/} - {/* */} - {/*
*/}
{text} + }, + { + title: '知识点', + dataIndex: 'knowledge', + key: 'knowledge' + }, + { + title: '来自', + dataIndex: 'from', + key: 'from' + }, + { + title: () => 只看已完成的, + key: 'tags', + dataIndex: 'tags', + render: () => + } + ] + + data = [ + { + key: '1', + question: '在哈希法存储中,冲突指的是 ( )', + knowledge: '哈希', + from: '考卷1' + // tags: ['nice', 'developer'], + }, + { + key: '2', + question: '在深度为5的满二叉树中,结点的个数为多少个?', + knowledge: '树', + from: '考卷2' + // tags: ['loser'], + } + ] + + onTabChange = key => { + console.log('----', key) + this.setState({ + currentKey: key + }) + } + onLookChange = () => { + this.setState({ + lookFinish: true + }) + } + onLookErrorChange = key => { + console.log('----', key) + } + handleNext() { + console.log('再做一次') + } + handleLook() { + console.log('查看详情') + } + onChangePagination = pageIndex => { + this.pageIndex = pageIndex + } + render() { + const { currentKey, total } = this.state + return ( +
+ { + this.onTabChange(key, 'key') + }} + > + {currentKey === 'tab1' && ( +
+
+
+
+ +
+
练习的试卷(21)
+
+
+ 只看已完成的 +
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习 +
+
+
+
+ +
+
完成时间:2021-12-13
+
+
+
+ +
+
得分:0
+
+
+
+ 再做一次 +
+
+ 查看详情 +
+
+
+
+ +
+ {total > 8 && ( + + )} +
+
+
+ )} + {currentKey === 'tab2' && ( +
+
+
+
+ +
+
历史错题总数(21)
+
+
+ +
+
+
+ + + + )} + + + ) + } +} diff --git a/src/views/personal-center/components/brush-question/index.less b/src/views/personal-center/components/brush-question/index.less new file mode 100644 index 0000000..054c27e --- /dev/null +++ b/src/views/personal-center/components/brush-question/index.less @@ -0,0 +1,97 @@ +.brush-question-component { + .brush-question-component-tab1-head { + display: flex; + justify-content: space-between; + padding: 0 0 20px 0; + .brush-question-component-tab1-head-title { + display: flex; + color: #333; + font-size: 16px; + font-weight: 400; + .brush-question-component-tab1-head-title-icon { + margin-right: 8px; + } + } + .brush-question-component-tab1-head-filter { + font-weight: 400; + } + } + .brush-question-component-tab1-body { + padding: 0 50px; + // display: flex; + // flex-wrap: wrap; + + .brush-question-component-tab1-body-item { + border-radius: 2px; + box-shadow: 0 6px 20px 0 #bababa; + cursor: pointer; + display: block; + height: 230px; + margin-bottom: 17px; + margin-right: 17px; + width: 216px; + transition: all 0.5s; + &:hover { + transform: scale(1.04); + } + &:hover .brush-question-component-tab1-body-item-footer { + display: flex; + } + .brush-question-component-tab1-body-label { + width: 76px; + height: 20px; + background-image: linear-gradient(136deg, #ffe324, #e7920f 100%, #ffb533 0); + box-shadow: 2px 0 2px 0 rgb(175, 130, 6); + position: relative; + top: -3%; + left: -8px; + text-align: center; + } + .brush-question-component-tab1-body-item-title { + background-color: rgb(234, 235, 236); + color: #333; + font-size: 14px; + font-weight: 700; + height: 80px; + // line-height: 50px; + overflow: auto; + padding: 20px 10px 0; + text-align: center; + } + .brush-question-component-tab1-body-item-content { + display: flex; + margin: 10px; + color: #000000a6; + .brush-question-component-tab1-body-item-content-icon { + margin-right: 5px; + } + } + .brush-question-component-tab1-body-item-footer { + display: none; + margin-top: 40px; + + .brush-question-component-tab1-body-item-footer-button { + flex: 1; + text-align: center; + &:hover { + color: #3c6eee; + } + } + } + } + } + .brush-question-component-tab2-head { + display: flex; + justify-content: space-between; + padding: 0 0 20px 0; + .brush-question-component-tab2-head-title { + display: flex; + color: #333; + font-size: 16px; + font-weight: 400; + .brush-question-component-tab2-head-title-icon { + margin-right: 8px; + } + } + } +} diff --git a/src/views/personal-center/components/collection-bag/index.jsx b/src/views/personal-center/components/collection-bag/index.jsx new file mode 100644 index 0000000..0788853 --- /dev/null +++ b/src/views/personal-center/components/collection-bag/index.jsx @@ -0,0 +1,145 @@ +import { Card, Pagination, Spin } from 'antd' +import React, { Component } from 'react' +import { collectTabType } from '../../constant' +import CollectionQuestion from '../collection-question' +import EmptyBox from '../empty-box' +import './index.less' +const tabList = [ + { + key: 'testQuestions', + tab: '收藏的试题' + } + // { + // key: 'posts', + // tab: '收藏的帖子', + // }, +] + +export default class CollectionBag extends Component { + constructor(props) { + super(props) + this.state = { + currentKey: collectTabType.testQuestions, // 选中的tab 默认选中第一个 + collectionList: [], + isShowSpin: true, + isShowSkeleton: true + } + } + + total = 0 // 总题数 + pageIndex = 1 + pageSize = 10 + + componentDidMount() { + this.getCollectionList() + } + + /** + * 切换tab + * @param {*} key + */ + onTabChange = key => { + this.setState( + { + currentKey: key + }, + () => { + this.pageIndex = 1 + this.getCollectionList() + } + ) + } + + /** + * 获取一级分类数据 + */ + getCollectionList() { + // JDreq({ + // method: 'post', + // data: { + // pageInfo: { + // pageIndex: this.pageIndex, + // pageSize: this.pageSize, + // }, + // }, + // url: apiName.getCollectionList, + // }) + // .then((res) => { + // if (res.data && res.data.pageList?.length > 0) { + // this.total = res.data.pageInfo.total + // this.setState({ + // collectionList: res.data.pageList, + // isShowSpin: false, + // isShowSkeleton: false, + // }) + // } else { + // this.total = 0 + // this.setState({ + // collectionList: [], + // isShowSpin: false, + // }) + // } + // }) + // .catch((err) => console.log(err)) + } + + /** + * 分页 + * @param {*} pageIndex + */ + onChangePagination = pageIndex => { + this.pageIndex = pageIndex + this.getCollectionList() + } + + render() { + const { currentKey, collectionList, isShowSpin } = this.state + return ( +
+ { + this.onTabChange(key) + }} + > + + {collectionList?.length > 0 ? this.renderContent(currentKey) : } + {this.total > 10 && ( + + )} + + +
+ ) + } + + /** + * 渲染内容 + * @param {*} type + * @returns + */ + renderContent = type => { + const { collectionList } = this.state + switch (type) { + // 收藏的试题 + case collectTabType.testQuestions: + return ( +
+ +
+ ) + } + } +} diff --git a/src/views/personal-center/components/collection-bag/index.less b/src/views/personal-center/components/collection-bag/index.less new file mode 100644 index 0000000..bd2f029 --- /dev/null +++ b/src/views/personal-center/components/collection-bag/index.less @@ -0,0 +1,16 @@ +.collection-bag-component { + .collection-bag-component-tab1-head { + display: flex; + justify-content: space-between; + padding: 0 0 20px 0; + .collection-bag-component-tab1-head-title { + display: flex; + color: #333; + font-size: 16px; + font-weight: 400; + .collection-bag-component-tab1-head-title-icon { + margin-right: 8px; + } + } + } +} diff --git a/src/views/personal-center/components/collection-question/index.jsx b/src/views/personal-center/components/collection-question/index.jsx new file mode 100644 index 0000000..6c206e9 --- /dev/null +++ b/src/views/personal-center/components/collection-question/index.jsx @@ -0,0 +1,103 @@ +import { SnippetsTwoTone } from '@ant-design/icons' +import { debounce, splicingQuery } from '@utils' +import React, { Component } from 'react' + +import './index.less' + +class CollectionQuestion extends Component { + constructor(props) { + super(props) + this.state = { + isModalVisible: false //对话框默认不可见 + } + } + + handleCancelCollection = () => { + console.log('取消收藏') + this.setState({ + isModalVisible: true + }) + } + + handleCancel = () => { + // console.log('点了取消'); + this.setState({ + isModalVisible: false + }) + } + + handleOk = () => { + console.log('点了确认') + this.setState({ + isModalVisible: false + }) + } + handleJump = id => + debounce(() => { + this.props.history.push( + splicingQuery('good-collection-question', { + subjectType: 4, + subjectId: id + }) + ) + }) + + render() { + const { collectionList, collectionTotal } = this.props + const { isModalVisible } = this.state + return ( +
+
+
+ +
+
收藏的题目({collectionTotal})
+
+ {collectionList.map(item => { + return ( +
+
+ + {item.subjectName} + +
+ {/*
+ + 取消收藏 + + +

+ 确认取消收藏吗? +

+
+
*/} +
+ ) + })} +
+ ) + } +} + +export default CollectionQuestion diff --git a/src/views/personal-center/components/collection-question/index.less b/src/views/personal-center/components/collection-question/index.less new file mode 100644 index 0000000..012dfe5 --- /dev/null +++ b/src/views/personal-center/components/collection-question/index.less @@ -0,0 +1,44 @@ +.collection-bag-component-tab1-body { + padding: 0 20px 20px 20px; + .collection-bag-component-tab1-head-title { + display: flex; + color: #333; + font-size: 16px; + font-weight: 400; + .collection-bag-component-tab1-head-title-icon { + margin-right: 8px; + } + } + .collection-bag-component-tab1-body-item { + margin: 10px 0; + overflow: auto; + position: relative; + clear: both; + // height: 60px; + border-bottom: 1px solid #e5e5e5; + + .collection-bag-component-tab1-body-item-question { + font-size: 14px; + line-height: 1.8; + .collection-bag-component-tab1-body-item-question-content { + width: 600px; + cursor: pointer; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + overflow: hidden; + &:hover { + color: #3c6eee; + } + } + } + .collection-bag-component-tab1-body-item-foot { + margin-top: 10px; + float: right; + .collection-bag-component-tab1-body-item-foot-button { + cursor: pointer; + color: #3c6eee; + } + } + } +} diff --git a/src/views/personal-center/components/empty-box/index.jsx b/src/views/personal-center/components/empty-box/index.jsx new file mode 100644 index 0000000..0980c6c --- /dev/null +++ b/src/views/personal-center/components/empty-box/index.jsx @@ -0,0 +1,13 @@ +import React from 'react' +import './index.less' +export default function EmptyBox() { + return ( +
+ + 这里什么也没有哦~ +
+ ) +} diff --git a/src/views/personal-center/components/empty-box/index.less b/src/views/personal-center/components/empty-box/index.less new file mode 100644 index 0000000..06e6958 --- /dev/null +++ b/src/views/personal-center/components/empty-box/index.less @@ -0,0 +1,17 @@ +.empty-box { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 100px 0; + .empty-inco { + width: 100px; + height: 100px; + } + .empty-text { + margin-top: 20px; + color: #b2bac2; + font-weight: 500; + font-size: 14px; + } +} diff --git a/src/views/personal-center/components/good-bag/index.jsx b/src/views/personal-center/components/good-bag/index.jsx new file mode 100644 index 0000000..666c996 --- /dev/null +++ b/src/views/personal-center/components/good-bag/index.jsx @@ -0,0 +1,139 @@ +import { Card, Pagination, Spin } from 'antd' +import React, { Component } from 'react' +import { goodTabType } from '../../constant' +import EmptyBox from '../empty-box' +import GoodQuestion from '../good-question' +import './index.less' +const tabList = [ + { + key: 'testQuestions', + tab: '点赞的试题' + } + // { + // key: 'posts', + // tab: '点赞的帖子', + // }, +] + +export default class GoodBag extends Component { + constructor(props) { + super(props) + this.state = { + currentKey: goodTabType.testQuestions, // 选中的tab 默认选中第一个 + goodList: [], + isShowSpin: true + } + } + + total = 0 // 总题数 + pageIndex = 1 + pageSize = 10 + + componentDidMount() { + this.getGoodList() + } + + /** + * 切换tab + * @param {*} key + */ + onTabChange = key => { + this.setState( + { + currentKey: key + }, + () => { + this.pageIndex = 1 + this.getGoodList() + } + ) + } + + /** + * 获取一级分类数据 + */ + getGoodList() { + // JDreq({ + // method: 'post', + // data: { + // pageInfo: { + // pageIndex: this.pageIndex, + // pageSize: this.pageSize, + // }, + // }, + // url: apiName.getGoodList, + // }) + // .then((res) => { + // if (res.data && res.data.pageList?.length > 0) { + // this.total = res.data.pageInfo.total + // this.setState({ + // goodList: res.data.pageList, + // isShowSpin: false, + // }) + // } else { + // this.total = 0 + // this.setState({ + // goodList: [], + // isShowSpin: false, + // }) + // } + // }) + // .catch((err) => console.log(err)) + } + + /** + * 分页 + * @param {*} pageIndex + */ + onChangePagination = pageIndex => { + this.pageIndex = pageIndex + this.getGoodList() + } + + render() { + const { currentKey, goodList, isShowSpin } = this.state + return ( +
+ { + this.onTabChange(key) + }} + > + + {goodList?.length > 0 ? this.renderContent(currentKey) : } + {this.total > 10 && ( + + )} + + +
+ ) + } + + /** + * 渲染内容 + * @param {*} type + * @returns + */ + renderContent = type => { + const { goodList } = this.state + switch (type) { + // 收藏的试题 + case goodTabType.testQuestions: + return + } + } +} diff --git a/src/views/personal-center/components/good-bag/index.less b/src/views/personal-center/components/good-bag/index.less new file mode 100644 index 0000000..70b8b70 --- /dev/null +++ b/src/views/personal-center/components/good-bag/index.less @@ -0,0 +1,16 @@ +.good-bag-component { + .good-bag-component-tab1-head { + display: flex; + justify-content: space-between; + padding: 0 0 20px 0; + .good-bag-component-tab1-head-title { + display: flex; + color: #333; + font-size: 16px; + font-weight: 400; + .good-bag-component-tab1-head-title-icon { + margin-right: 8px; + } + } + } +} diff --git a/src/views/personal-center/components/good-question/index.jsx b/src/views/personal-center/components/good-question/index.jsx new file mode 100644 index 0000000..058d5ba --- /dev/null +++ b/src/views/personal-center/components/good-question/index.jsx @@ -0,0 +1,97 @@ +import { SnippetsTwoTone } from '@ant-design/icons' +import { debounce, splicingQuery } from '@utils' +import React, { Component } from 'react' + +import './index.less' + +class GoodQuestion extends Component { + constructor(props) { + super(props) + this.state = { + isModalVisible: false //对话框默认不可见 + } + } + + handleCancelGood = () => { + console.log('取消点赞') + this.setState({ + isModalVisible: true + }) + } + + handleCancel = () => { + // console.log('点了取消'); + this.setState({ + isModalVisible: false + }) + } + + handleOk = () => { + console.log('点了确认') + this.setState({ + isModalVisible: false + }) + } + handleJump = id => + debounce(() => { + this.props.history.push( + splicingQuery('good-collection-question', { + subjectType: 4, + subjectId: id + }) + ) + }) + + render() { + const { goodList, goodTotal } = this.props + const { isModalVisible } = this.state + return ( +
+
+
+ +
+
点赞的题目({goodTotal})
+
+ {goodList.map(item => { + return ( +
+
+ + {item.subjectName} + +
+ {/*
+ + 取消点赞 + + +

+ 确认取消点赞吗? +

+
+
*/} +
+ ) + })} +
+ ) + } +} + +export default GoodQuestion diff --git a/src/views/personal-center/components/good-question/index.less b/src/views/personal-center/components/good-question/index.less new file mode 100644 index 0000000..06dc739 --- /dev/null +++ b/src/views/personal-center/components/good-question/index.less @@ -0,0 +1,44 @@ +.good-bag-component-tab1-body { + padding: 0 20px 20px 20px; + .good-bag-component-tab1-head-title { + display: flex; + color: #333; + font-size: 16px; + font-weight: 400; + .good-bag-component-tab1-head-title-icon { + margin-right: 8px; + } + } + .good-bag-component-tab1-body-item { + margin: 10px 0; + overflow: auto; + position: relative; + clear: both; + // height: 60px; + border-bottom: 1px solid #e5e5e5; + + .good-bag-component-tab1-body-item-question { + font-size: 14px; + line-height: 1.8; + .good-bag-component-tab1-body-item-question-content { + width: 600px; + cursor: pointer; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + overflow: hidden; + &:hover { + color: #3c6eee; + } + } + } + .good-bag-component-tab1-body-item-foot { + margin-top: 10px; + float: right; + .good-bag-component-tab1-body-item-foot-button { + cursor: pointer; + color: #3c6eee; + } + } + } +} diff --git a/src/views/personal-center/constant.js b/src/views/personal-center/constant.js new file mode 100644 index 0000000..ec45fd9 --- /dev/null +++ b/src/views/personal-center/constant.js @@ -0,0 +1,19 @@ +export const apiName = { + /** + * 获取收藏数据 + */ + getCollectionList: '/admin/question/collect/list', + getGoodList: 'admin/question/thump/list', +} + +// 收藏-tab类型 +export const collectTabType = { + testQuestions: 'testQuestions', //试题 + posts: 'posts', //帖子 +} + +// 点赞-tab类型 +export const goodTabType = { + testQuestions: 'testQuestions', //试题 + posts: 'posts', //帖子 +} diff --git a/src/views/personal-center/headLog.png b/src/views/personal-center/headLog.png new file mode 100644 index 0000000..dcd7ead Binary files /dev/null and b/src/views/personal-center/headLog.png differ diff --git a/src/views/personal-center/index.jsx b/src/views/personal-center/index.jsx new file mode 100644 index 0000000..954675a --- /dev/null +++ b/src/views/personal-center/index.jsx @@ -0,0 +1,160 @@ +import { IdcardOutlined, LikeTwoTone, MailOutlined, StarTwoTone } from '@ant-design/icons' +import { Menu } from 'antd' +import React, { Component } from 'react' +// import JDreq from '@common/JDreq' +import PubSub from 'pubsub-js' +// import headLog from './headLog.png' +import CollectionBag from './components/collection-bag' +import GoodBag from './components/good-bag' +import './index.less' + +export default class PersonalCenter extends Component { + constructor(props) { + super(props) + this.state = { + currentKeyMap: 0, //选中的menu + userName: '', //姓名 + intervieweEamil: '', //邮箱 + headImg: '', //头像 + department: '', //部门 + practiceAmount: 0, //练题数 + inputAmount: 0, //录题数 + goodAmount: 0, //点赞数 + collectionAmount: 0, //收藏数 + subMenuList: [] + } + } + personList = { + // 0: '刷题', + 0: '收藏', + 1: '点赞' + } + componentDidMount() { + // JDreq({ + // method: 'post', + // url: 'admin/person/home/getPersonInfo' + // }).then(res => { + // this.setState( + // { + // userName: res.data?.name ?? '', + // intervieweEamil: res.data?.email ?? '', + // headImg: res.data?.headImg ?? '', + // department: res.data?.departmentName ?? '', + // goodAmount: res.data?.thumpCount ?? 0, + // collectionAmount: res.data?.collectCount ?? 0, + // practiceAmount: res.data?.practiceCount ?? 0, + // inputAmount: res.data?.subjectCount ?? 0 + // }, + // () => { + // window.localStorage.setItem('interviewName', res.data?.name ?? 'XXX') + // window.localStorage.setItem('interviewEamil', res.data?.email ?? 'XXX') + // } + // ) + // }) + PubSub.subscribe('handleToRender', () => { + this.setState({}) + }) + } + /** + * 切换菜单 + * @param {*} e + */ + handleClick = e => { + console.log('--------', e) + //截取_后的字符 + let index = e.keyPath[0].lastIndexOf('_') + let index2 = e.keyPath[0].substring(index + 1, e.keyPath[0].length) + // + console.log('index2>>>>', index2) + this.setState({ + currentKeyMap: Number(index2) + }) + } + render() { + let { + headImg, + userName, + intervieweEamil, + department, + goodAmount, + collectionAmount, + practiceAmount, + inputAmount + } = this.state + const { currentKeyMap } = this.state + return ( +
+
+
+
+ +
+
+
{userName}
+
+ + + {/* 部门:{department} */} + + + + {/* 邮箱:{intervieweEamil} */} + +
+
+
+
+
+
+ {practiceAmount} +
+
练题
+
+
+
{inputAmount}
+
录题
+
+
+
{goodAmount}
+
点赞
+
+
+
+ {collectionAmount} +
+
收藏
+
+
+
+
+
+ + {/* + + {this.personList[0]} + */} + + + {this.personList[0]} + + + + {this.personList[1]} + + +
+
+ {/* {currentKeyMap === 0 && } */} + {currentKeyMap === 0 && } + {currentKeyMap === 1 && } +
+
+
+ ) + } +} diff --git a/src/views/personal-center/index.less b/src/views/personal-center/index.less new file mode 100644 index 0000000..9c0577e --- /dev/null +++ b/src/views/personal-center/index.less @@ -0,0 +1,68 @@ +.personal-center-box { + margin: 0 auto; + width: 1439px; + // padding: 20px 50px; + border-radius: 5px; + overflow: auto; + .personal-center-introduction { + background-color: #fff; + border-radius: 3px; + height: 100px; + margin-bottom: 10px; + display: flex; + justify-content: space-between; + .personal-center-introduction-detail { + margin-left: 50px; + padding-top: 20px; + display: flex; + .personal-center-introduction-detail-headImg { + margin-right: 20px; + align-items: center; + } + .personal-center-introduction-detail-text { + .personal-center-introduction-detail-name { + color: #3c6eee; + font-weight: 570; + } + .personal-center-introduction-detail-information { + margin: 15px 0; + .personal-center-introduction-detail-information-content { + margin-right: 15px; + } + } + } + } + .personal-center-introduction-result { + margin-right: 50px; + padding-top: 30px; + display: flex; + .personal-center-introduction-result-item { + text-align: center; + padding-right: 10px; + .personal-center-introduction-result-item-number { + font-weight: 570; + color: #3c6eee; + } + } + } + } + .personal-center-content { + display: flex; + align-items: flex-start; + .personal-center-content-left { + background-color: #fff; + overflow-y: auto; + border-radius: 3px; + width: 300px; + height: 720px; + } + .personal-center-content-right { + background-color: #fff; + flex-direction: column; + overflow: auto; + border-radius: 4px; + margin: 0 0 0 10px; + width: 100%; + } + } +} diff --git a/src/views/personal-center/mock.js b/src/views/personal-center/mock.js new file mode 100644 index 0000000..fffe02a --- /dev/null +++ b/src/views/personal-center/mock.js @@ -0,0 +1,58 @@ +export const getCollectionList = { + pageInfo: { + pageSize: 10, + totalPage: 2, + pageIndex: 1, + total: 12, + firstPage: true, + lastPage: false, + startRecord: 0, + endRecord: 10, + }, + pageList: [ + { + id: 1717, + subjectName: '说说 React组件开发中关于作用域的常见问题。', + }, + { + id: 1710, + subjectName: '概述一下 React中的事件处理逻辑。', + }, + { + id: 1706, + subjectName: 'React中Diff算法的原理是什么?', + }, + { + id: 1698, + subjectName: 'shouldComponentUpdate有什么用?为什么它很重要?', + }, + { + id: 1695, + subjectName: '在哪个生命周期中你会发出Ajax请求?为什么?', + }, + { + id: 1692, + subjectName: '类组件和函数组件之间的区别是什么?', + }, + { + id: 1691, + subjectName: '详细解释 React 组件的生命周期方法?', + }, + { + id: 1689, + subjectName: '什么是 Props?', + }, + { + id: 1579, + subjectName: '横竖屏切换的Activity 生命周期变化?', + }, + { + id: 1578, + subjectName: '谈下MVC ,MVP,MVVM', + }, + { + id: 1532, + subjectName: 'get 和post 请求在缓存方面的区别是什么?', + }, + ], +} diff --git a/src/views/question-bank/components/contribution-list/index.jsx b/src/views/question-bank/components/contribution-list/index.jsx index 1e513ce..3355ace 100644 --- a/src/views/question-bank/components/contribution-list/index.jsx +++ b/src/views/question-bank/components/contribution-list/index.jsx @@ -67,12 +67,12 @@ const ContributionList = props => { ).then(res => { if (res.success && res.data) { if (res.data.includes('subject:add')) { - navigate('/upload-questions') + window.open('/upload-question') } else { - message.info('敬请期待') + message.info('暂无权限') } } else { - message.info('敬请期待') + message.info('暂无权限') } }) } diff --git a/src/views/upload-questions/components/brief-questions/index.less b/src/views/upload-questions/components/brief-questions/index.less index 56be9d8..8ded137 100644 --- a/src/views/upload-questions/components/brief-questions/index.less +++ b/src/views/upload-questions/components/brief-questions/index.less @@ -1,58 +1,58 @@ .brief-questions-container { - width: 1000px; + // width: 1000px; + display: flex; + align-items: center; + padding: 0 24px; + padding-top: 36px; + .brief-questions-title { display: flex; align-items: center; - padding: 0 24px; - padding-top: 36px; - .brief-questions-title { - display: flex; - align-items: center; - justify-content: flex-end; - width: 140px; - line-height: 40px; - font-size: 16px; - color: rgba(51, 51, 51, 1); - &:before { - display: inline-block; - margin-right: 4px; - margin-top: 1px; - color: #f5222d; - font-size: 16px; - content: '*'; - } + justify-content: flex-end; + width: 140px; + line-height: 40px; + font-size: 16px; + color: rgba(51, 51, 51, 1); + &:before { + display: inline-block; + margin-right: 4px; + margin-top: 1px; + color: #f5222d; + font-size: 16px; + content: '*'; } - .brief-questions-main { - width: 100%; - // 题目输入框 - .brief-questions-input { - height: 48px; - } + } + .brief-questions-main { + width: 100%; + // 题目输入框 + .brief-questions-input { + height: 48px; } + } } .brief-questions-btns-container { + display: flex; + justify-content: flex-end; + align-items: center; + margin: 20px auto; + width: 952px; + .brief-questions-btn { display: flex; - justify-content: flex-end; align-items: center; - margin: 20px auto; - width: 952px; - .brief-questions-btn { - display: flex; - align-items: center; - justify-content: center; - width: 150px; - height: 40px; - font-size: 16px; - cursor: pointer; - border: 1px solid #d9d9d9; - border-radius: 10px; - } - .brief-questions-submit { - margin-left: 40px; - background-color: #4390f7; - color: #fff; - border: 1px solid #4390f7; - } - .brief-questions-disabled-submit { - opacity: 0.5; - } + justify-content: center; + width: 150px; + height: 40px; + font-size: 16px; + cursor: pointer; + border: 1px solid #d9d9d9; + border-radius: 10px; + } + .brief-questions-submit { + margin-left: 40px; + background-color: #4390f7; + color: #fff; + border: 1px solid #4390f7; + } + .brief-questions-disabled-submit { + opacity: 0.5; + } } diff --git a/src/views/upload-questions/components/upload-left-layout/index.less b/src/views/upload-questions/components/upload-left-layout/index.less index 082e544..206c7cc 100644 --- a/src/views/upload-questions/components/upload-left-layout/index.less +++ b/src/views/upload-questions/components/upload-left-layout/index.less @@ -18,8 +18,6 @@ background: rgba(255, 255, 255, 1); border: 1px solid rgba(208, 212, 222, 1); border-radius: 12px; - &:hover { - } } .upload-left-layout-item-active { color: rgba(60, 110, 238, 1); diff --git a/src/views/upload-questions/index.less b/src/views/upload-questions/index.less index 9a944e5..e3af76d 100644 --- a/src/views/upload-questions/index.less +++ b/src/views/upload-questions/index.less @@ -1,20 +1,20 @@ .upload-questions-box { - position: relative; - margin: 0 auto; - width: 1439px; - overflow-y: auto; - border-radius: 5px; - height: calc(100vh - 90px); - .ant-card-head { - position: sticky; - top: 0; - left: 0; - right: 0; - padding: 0 48px; - z-index: 10; - background-color: #fff; - } - .ant-card-body { - display: flex; - } + position: relative; + margin: 0 auto; + width: 1439px; + overflow-y: auto; + border-radius: 5px; + height: calc(100vh - 100px); + .ant-card-head { + position: sticky; + top: 0; + left: 0; + right: 0; + padding: 0 48px; + z-index: 10; + background-color: #fff; + } + .ant-card-body { + display: flex; + } } diff --git a/src/views/upload-questions/index.tsx b/src/views/upload-questions/index.tsx index 52f87ca..5090e98 100644 --- a/src/views/upload-questions/index.tsx +++ b/src/views/upload-questions/index.tsx @@ -1,49 +1,66 @@ -import React, { Component } from 'react'; -import { Card } from 'antd'; -import SingleBox from './pages/single-box'; -import BatchleBox from './pages/batch-box'; -import './index.less'; +import req from '@utils/request' +import { Card, message } from 'antd' +import { useEffect, useState } from 'react' +import { useNavigate } from 'react-router-dom' +import BatchleBox from './pages/batch-box' +import SingleBox from './pages/single-box' + +import './index.less' const tabList = [ - { - key: 'singleBox', - tab: '单题录入', - }, - // { - // key: 'batchBox', - // tab: '批量导入', - // }, -]; -export default class UploadQuestions extends Component { - constructor(props) { - super(props); - this.state = { currentKey: 'singleBox' }; - } + { + key: 'singleBox', + tab: '单题录入' + } +] +const UploadQuestions = () => { + const [currentKey, setCurrentKey] = useState('singleBox') + const navigate = useNavigate() - contentList = { - singleBox: , - batchBox: , - }; - - onTabChange = (e) => { - this.setState({ - currentKey: e, - }); - }; - render() { - const { currentKey } = this.state; - return ( -
- { - this.onTabChange(key, 'key'); - }}> - {this.contentList[currentKey]} - -
- ); + useEffect(() => { + const userInfoStorage = localStorage.getItem('userInfo') + if (!userInfoStorage) { + return message.info('请登录') } + const { loginId } = JSON.parse(userInfoStorage) + req( + { + method: 'get', + url: '/permission/getPermission', + params: { + userName: loginId + } + }, + '/auth' + ).then(res => { + if (res.success && res.data) { + if (!res.data.includes('subject:add')) { + message.info('暂无权限') + navigate('/question-bank') + } + } + }) + }, []) + + const contentList = { + singleBox: , + batchBox: + } + + return ( +
+ { + setCurrentKey(key) + }} + > + {contentList[currentKey]} + +
+ ) } + +export default UploadQuestions diff --git a/src/views/upload-questions/pages/single-box/index.jsx b/src/views/upload-questions/pages/single-box/index.jsx index 6d1e360..c755dd3 100644 --- a/src/views/upload-questions/pages/single-box/index.jsx +++ b/src/views/upload-questions/pages/single-box/index.jsx @@ -1,64 +1,65 @@ -import React, { Component } from 'react'; -import UploadLeftLayout from '../../components/upload-left-layout'; -import BriefQuestions from '../../components/brief-questions'; -import SingleQuestions from '../../components/single-questions'; -import MultipleQuestions from '../../components/multiple-questions'; -import JudgeQuestions from '../../components/judge-questions'; -import { uploadLayout } from '../../constant'; -import './index.less'; +import React, { Component } from 'react' +import BriefQuestions from '../../components/brief-questions' +import JudgeQuestions from '../../components/judge-questions' +import MultipleQuestions from '../../components/multiple-questions' +import SingleQuestions from '../../components/single-questions' +import UploadLeftLayout from '../../components/upload-left-layout' +import { uploadLayout } from '../../constant' + +import './index.less' export default class SingleBox extends Component { - constructor(props) { - super(props); - this.state = { - layoutList: uploadLayout, - currentIndex: 0, - }; + constructor(props) { + super(props) + this.state = { + layoutList: uploadLayout, + currentIndex: 0 } - /** - * 切换题型 - * @param {*} id - */ - onChangeQuestionsType = (layoutIndex) => { - let { layoutList, currentIndex } = this.state; - if (currentIndex === layoutIndex) { - return; - } - let list = layoutList.map((item, index) => { - let flag = false; - if (layoutIndex === index) { - flag = true; - } - return { - ...item, - active: flag, - }; - }); - this.setState({ - layoutList: list, - currentIndex: layoutIndex, - }); - }; - - render() { - const { currentIndex, layoutList } = this.state; - return ( -
- -
{this.changeReander(currentIndex)}
-
- ); + } + /** + * 切换题型 + * @param {*} id + */ + onChangeQuestionsType = layoutIndex => { + let { layoutList, currentIndex } = this.state + if (currentIndex === layoutIndex) { + return } + let list = layoutList.map((item, index) => { + let flag = false + if (layoutIndex === index) { + flag = true + } + return { + ...item, + active: flag + } + }) + this.setState({ + layoutList: list, + currentIndex: layoutIndex + }) + } - changeReander = (i) => { - switch (i) { - case 0: - return ; - case 1: - return ; - case 2: - return ; - case 3: - return ; - } - }; + render() { + const { currentIndex, layoutList } = this.state + return ( +
+ +
{this.changeReander(currentIndex)}
+
+ ) + } + + changeReander = i => { + switch (i) { + case 0: + return + case 1: + return + case 2: + return + case 3: + return + } + } }