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' && (
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
专项练习
+
+ 计算机专业技能-网络基础专项练习
+
+
+
+
+
+
+
完成时间:2021-12-13
+
+
+
+
+
+
+
+ {total > 8 && (
+
+ )}
+
+
+
+ )}
+ {currentKey === 'tab2' && (
+
+ )}
+
+
+ )
+ }
+}
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}
+
+
练题
+
+
+
+
+
+ {collectionAmount}
+
+
收藏
+
+
+
+
+
+
+
+
+ {/* {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
+ }
+ }
}