+
+
+ (window.location.href = '/question-bank')
+ }>
+
-
-
- {'/question-bank' == pathname && (
-
- console.log(value)}
- style={{ width: 300, borderRadius: '10px' }}
- />
-
- )}
-
- {/* */}
-
-
-

+
+
+
+ {'/question-bank' == pathname && (
+
+ console.log(value)}
+ style={{ width: 300, borderRadius: '10px' }}
/>
+ )}
+
+ {/* */}
+
+
+
- );
- }
+
+ )
}
const App = () => {
@@ -87,4 +67,4 @@ const App = () => {
)
}
-export default App
+export default memo(App)
diff --git a/src/components/category-list/constant.js b/src/components/category-list/constant.js
index 6cb36b2..342b4dc 100644
--- a/src/components/category-list/constant.js
+++ b/src/components/category-list/constant.js
@@ -8,23 +8,23 @@ export const filterDifficulty = [
},
{
id: 1,
- title: 'T4',
+ title: '初级',
},
{
id: 2,
- title: 'T5',
+ title: '中级',
},
{
id: 3,
- title: 'T6',
+ title: '高级',
},
{
id: 4,
- title: 'T7',
+ title: '资深',
},
{
id: 5,
- title: 'T8',
+ title: '专家',
},
];
@@ -33,6 +33,14 @@ export const apiName = {
* 获取二级和三级标签
*/
getCategoryLabelInfo: '/admin/question/category/getCategoryLabelInfo',
+
+ /**
+ * 查询大类下分类
+ */
+ queryCategoryByPrimary: '/category/queryCategoryByPrimary',
+
+ // 根据分类查标签
+ queryLabelByCategoryId: '/label/queryLabelByCategoryId'
};
export const imgObject = {
diff --git a/src/components/category-list/index.jsx b/src/components/category-list/index.jsx
index 23930c2..e110a5f 100644
--- a/src/components/category-list/index.jsx
+++ b/src/components/category-list/index.jsx
@@ -1,4 +1,4 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component, Fragment, useState, useEffect } from 'react';
import {
RightOutlined,
@@ -8,7 +8,7 @@ import {
CaretUpOutlined,
} from '@ant-design/icons';
import req from '@utils/request';
-import { Divider } from 'antd';
+import { Divider, Spin } from 'antd';
import _ from 'lodash';
import './index.less';
import { apiName, imgObject } from './constant';
@@ -30,12 +30,263 @@ export const categoryBackImg = {
const categoryShowCount = 4;
-export default class CategoryList extends Component {
+const cacheMap = {}
+
+const CategoryList = ({ primaryCategoryId, categoryList, ...props }) => {
+ const [secondCategoryList, setSecondCategoryList] = useState([])
+ const [currentActive, setCurrentActive] = useState(categoryList[0])
+ const [isPutAway, setIsPutAway] = useState(true)
+ const [loading, setLoading] = useState(false)
+
+ const getLabels = (id) => {
+ return new Promise(resolve => {
+ req({
+ method: 'post',
+ url: apiName.queryLabelByCategoryId,
+ data: { categoryId: id }
+ }).then(res => {
+ if (cacheMap[id]) {
+ resolve(cacheMap[id])
+ } else {
+ cacheMap[id] = res.data
+ resolve(res.data)
+ }
+ })
+ })
+ }
+
+ // 获取大类下分类
+ const getCategoryByPrimary = () => {
+ req({
+ method: 'post',
+ url: apiName.queryCategoryByPrimary,
+ data: { categoryType: 2, parentId: currentActive.id }
+ }).then(async res => {
+ let list = res.data
+ for (let i = 0; i < list.length; i++) {
+ list[i].children = await getLabels(list[i].id)
+ }
+ setSecondCategoryList(_.cloneDeep(list))
+ })
+ }
+
+ useEffect(() => {
+ if (primaryCategoryId) {
+ getCategoryByPrimary()
+ }
+ }, [primaryCategoryId])
+
+
+
+ /**
+ * 切换一级分类
+ * @param {*} item
+ * @returns
+ */
+ const onChangeCategory = (item) => () => {
+ if (currentActive.id === item.id) {
+ return;
+ }
+ setCurrentActive(item)
+ props.onChangeCategory(item);
+ };
+
+ /**
+ * 一级分类模块
+ * @returns
+ */
+ const renderFirstContainer = () => {
+ return (
+
+ {categoryList.slice(0, 7).map((categoryModuleItem, categoryModuleIndex) => {
+ return (
+
+
+ {categoryModuleItem.categoryName}
+
+
+ {categoryModuleItem.count || 50}道题
+
+
+ );
+ })}
+ {categoryList.length > 7 && (
+
+ 更多
+
+
+ )}
+
+ );
+ };
+
+ /**
+ * 选择标签-支持单选(多选)
+ * @param {*} categoryId 一级分类id
+ * @param {*} secondCategoryIndex 二级分类对象index
+ * @param {*} thirdCategoryIndex 三级标签index
+ * @param {*} active 三级标签当前的选中状态
+ * @returns
+ */
+ const onChangeLabel = (secondCategoryIndex, thirdCategoryIndex, active) => () => {
+ const list = _.cloneDeep(secondCategoryList)
+ _.set(list, [secondCategoryIndex, 'children', thirdCategoryIndex, 'active'], !active)
+ setSecondCategoryList(list)
+ };
+
+ /**
+ * 展开/收起
+ * @param {*} secondCategoryIndex
+ * @returns
+ */
+ const onChangeOpenStatus = (secondCategoryIndex, isOpen) => () => {
+ return
+ let { secondCategoryList } = this.state;
+ _.set(secondCategoryList, [secondCategoryIndex, 'isOpen'], !isOpen);
+ this.setState({
+ secondCategoryList,
+ });
+ };
+
+ /**
+ * 展开/收起
+ */
+ const onChangePutAway = () => {
+ return
+ let { isPutAway } = this.state;
+ this.setState({
+ isPutAway: !isPutAway,
+ });
+ };
+
+ /**
+ * 二级分类模块
+ * @returns
+ */
+ const renderSecondContainer = () => {
+ return (
+
+
+ {secondCategoryList.map((secondCategoryItem, secondCategoryIndex) => {
+ return (
+
= categoryShowCount && isPutAway
+ ? 'none'
+ : 'flex',
+ }}
+ className="second-category-item"
+ key={`second_category_${secondCategoryItem.id}`}>
+
+ {secondCategoryItem.categoryName}:
+
+ {secondCategoryItem?.children?.length > 0 && (
+
+
+ {secondCategoryItem.children.map(
+ (thirdCategoryItem, thirdCategoryIndex) => {
+ return (
+
+ {thirdCategoryItem.labelName}·
+ {thirdCategoryItem.subjectCount || 0}
+
+ );
+ }
+ )}
+
+
+
+ {secondCategoryItem.isOpen ? '收起' : '展开'}
+
+
+ {secondCategoryItem.isOpen ? (
+
+ ) : (
+
+ )}
+
+
+
+ )}
+
+ );
+ })}
+ {secondCategoryList?.length >= categoryShowCount && (
+
+ {isPutAway ? '展开' : '收起'}
+ {isPutAway ? (
+
+ ) : (
+
+ )}
+
+ )}
+
+
+
+ );
+ };
+
+ return (
+
+ {categoryList?.length && renderFirstContainer()}
+
+ {secondCategoryList?.length > 0 && renderSecondContainer()}
+
+ {/* {!this.props.isHideSec && (
+
+ {secondCategoryList?.length > 0 && this.renderSecondContainer()}
+
+ )} */}
+
+ )
+}
+
+export default CategoryList
+
+
+class CategoryList1 extends Component {
constructor(props) {
super(props);
this.state = {
secondCategoryList: [],
- currentActive: '',
+ currentActive: null,
isPutAway: true, // 是否收起 默认收起状态
};
}
@@ -49,7 +300,7 @@ export default class CategoryList extends Component {
*/
initCategoryList() {
const { categoryList, primaryCategoryId } = this.props;
- let currentActive = primaryCategoryId ?? categoryList[0].primaryCategoryId;
+ let currentActive = primaryCategoryId ?? categoryList[0];
this.props.onChangeCategory(currentActive);
this.getSecondCategoryList(currentActive);
}
@@ -61,8 +312,8 @@ export default class CategoryList extends Component {
const { categoryListMap } = this.props;
// 调用接口返回二级三级数据
let params = {
- primaryCategoryId: currentActive,
- subjectTypeList: [4],
+ parentId: currentActive.id,
+ categoryType: 2,
};
req({
method: 'post',
@@ -210,28 +461,13 @@ export default class CategoryList extends Component {
});
};
- render() {
- const { categoryList } = this.props;
- const { secondCategoryList } = this.state;
- return (
-
- {categoryList?.length > 0 && this.renderFirstContainer()}
- {!this.props.isHideSec && (
-
- {secondCategoryList?.length > 0 && this.renderSecondContainer()}
-
- )}
-
- );
- }
+
/**
* 一级分类模块
* @returns
*/
renderFirstContainer = () => {
- const { categoryList } = this.props;
- const { currentActive } = this.state;
return (
{categoryList.slice(0, 7).map((categoryModuleItem, categoryModuleIndex) => {
@@ -240,7 +476,7 @@ export default class CategoryList extends Component {
className={`first-category-item ${categoryModuleItem.primaryCategoryId === currentActive &&
'first-category-item-active'
}`}
- key={`first_category_${categoryModuleItem.primaryCategoryId}`}
+ key={`first_category_${categoryModuleItem.id}`}
style={{
backgroundImage: `url(${categoryBackImg[categoryModuleIndex]})`,
}}
@@ -358,5 +594,19 @@ export default class CategoryList extends Component {
);
};
+ render() {
+ const { categoryList } = this.props;
+ const { secondCategoryList } = this.state;
+ return (
+
+ {categoryList?.length > 0 && this.renderFirstContainer()}
+ {!this.props.isHideSec && (
+
+ {secondCategoryList?.length > 0 && this.renderSecondContainer()}
+
+ )}
+
+ );
+ }
}
diff --git a/src/components/category-list/index.less b/src/components/category-list/index.less
index e99a1a8..a393f5e 100644
--- a/src/components/category-list/index.less
+++ b/src/components/category-list/index.less
@@ -91,16 +91,30 @@
font-size: 14px;
border: 1px solid rgba(0, 0, 0, 0.04);
border-radius: 4px;
+ // @mixin box-backgroundColor($alpha: 1) {
+ // background-color: rgba(60, 110, 238, $alpha) !important;
+ // }
+
+ // @mixin box-border($width: 1px, $style: solid, $alpha: 1) {
+ // border: $width $style rgba(60, 110, 238, $alpha) !important;
+ // }
+
+ // @mixin font-color($alpha: 1) {
+ // color: rgba(60, 110, 238, $alpha) !important;
+ // }
&:hover {
- @include box-backgroundColor(0.1);
- @include box-border();
- @include font-color();
+ background-color: rgba(60, 110, 238, 0.1);
+ border: 1px solid rgba(60, 110, 238, 1);
+ color: rgba(60, 110, 238, 1)
}
}
.third-category-item-active {
- @include box-backgroundColor(0.1);
- @include box-border();
- @include font-color();
+ // @include box-backgroundColor(0.1);
+ // @include box-border();
+ // @include font-color();
+ background-color: rgba(60, 110, 238, 0.1);
+ border: 1px solid rgba(60, 110, 238, 1);
+ color: rgba(60, 110, 238, 1)
}
}
.second-category-item-status {
diff --git a/src/components/top-menu/index.jsx b/src/components/top-menu/index.jsx
index 3acb3bc..1149732 100644
--- a/src/components/top-menu/index.jsx
+++ b/src/components/top-menu/index.jsx
@@ -1,6 +1,6 @@
import { message } from 'antd';
-import React, { Component } from 'react'
-import { useLocation } from 'react-router-dom';
+import React, { Component, useState, memo } from 'react'
+import { useLocation, useNavigate } from 'react-router-dom';
import './index.less'
// 顶部tab
const MENULIST = [
@@ -12,7 +12,7 @@ const MENULIST = [
{
key: 'prictiseQuestion',
title: '练题',
- route: '/question-bank',
+ route: '/brush-question',
},
{
key: 'practiceQuestions',
@@ -31,66 +31,43 @@ const MENULIST = [
const mapMenu = {
'/question-bank': 'questionBank',
}
-class TopMenu extends Component {
- constructor(props) {
- super(props)
- this.state = {
- currentKey: 'questionBank',
- }
- }
- componentDidMount() {
- // this.setState({
- // currentKey: mapMenu[this.props.currentRoute] || '',
- // })
- }
+const TopMenu = () => {
+
+ const [currentKey, setCurrentKey] = useState('questionBank')
+ const location = useLocation()
+ const navigate = useNavigate()
/**
* 切换item
* @param {*} item
* @returns
*/
- changeMenu = (item) => () => {
+ const changeMenu = (item) => () => {
if (item.key === "questionBank") {
- return
+ if (location.pathname === '/question-bank') return
+ navigate('/question-bank')
} else {
return message.info("敬请期待")
}
-
- // 打开新窗口
- if (item.isOpenNewWindow) {
- window.open(item.route)
- return
- }
- this.setState(
- {
- currentKey: item.key,
- },
- () => {
- this.props.history.push(item.route)
- }
- )
}
- render() {
- const { currentKey } = this.state
- return (
-
- {MENULIST.map((item, index) => {
- return (
-
- )
- })}
-
- )
- }
+ return (
+
+ {MENULIST.map((item, index) => {
+ return (
+
+ )
+ })}
+
+ )
}
-export default TopMenu
+export default memo(TopMenu)
diff --git a/src/main.tsx b/src/main.tsx
index ce4ab26..b65e600 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,5 +1,4 @@
import './main.less'
-
import React from 'react'
import ReactDOM from 'react-dom/client'
import router from '@/router'
diff --git a/src/views/question-bank/index.tsx b/src/views/question-bank/index.tsx
index e3e7909..dd703de 100644
--- a/src/views/question-bank/index.tsx
+++ b/src/views/question-bank/index.tsx
@@ -1,5 +1,5 @@
// import { Component } from 'react';
-import { useState, useEffect } from 'react'
+import { useState, useEffect, memo } from 'react'
import QuestionList from '@components/question-list';
import CategoryList from '@components/category-list';
import ContributionList from './components/contribution-list';
@@ -12,9 +12,8 @@ import './index.less';
const QuestionBank = () => {
-
const [firstCategoryList, setFirstCategoryList] = useState([])
- const [questionList, setQuestionList] = useState(mockDataList)
+ const [questionList, setQuestionList] = useState([])
const [isShowSpin, setIsShowSpin] = useState(false)
const [labelList, setLabelList] = useState
([]); // 选中的标签列表
const [difficulty, setDiffculty] = useState(0); //困难度(全部)
@@ -46,30 +45,13 @@ const QuestionBank = () => {
})
}
- // 获取大类下分类
- const getCategoryByPrimary = () => {
- req({
- method: 'post',
- url: apiName.queryCategoryByPrimary,
- data: { categoryType: 1, parentId: 1 }
- }).then(res => {
- console.log(res)
- })
- }
-
- useEffect(() => {
- if (primaryCategoryId) {
- getCategoryByPrimary()
- }
- }, [primaryCategoryId])
-
/**
* 切换一级分类
* @param {*} e
*/
- const onChangeCategory = (e: string) => {
+ const onChangeCategory = (item: Record) => {
setLabelList([])
- setPromaryCategoryId(e)
+ setPromaryCategoryId(item.id)
setPageIndex(1)
};
@@ -82,11 +64,12 @@ const QuestionBank = () => {
setLabelList(assembleIds)
setPromaryCategoryId(primaryCategoryId)
setPageIndex(1)
- // this.getInterviewSubjectList();
};
useEffect(() => {
- getPrimaryCategoryInfo()
+ if (!primaryCategoryId) {
+ getPrimaryCategoryInfo()
+ }
}, [])
return (
@@ -99,6 +82,7 @@ const QuestionBank = () => {
onChangeCategory={onChangeCategory}
categoryList={firstCategoryList}
onChangeLabel={onChangeLabel}
+ primaryCategoryId={primaryCategoryId}
/>
)}