diff --git a/package.json b/package.json index 6972a3a..a7a6619 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "react": "^18.1.0", "react-dom": "^18.1.0", "react-router-dom": "^6.16.0", + "swiper": "^11.0.4", "wangeditor": "^4.7.15" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 144ce10..86ffcd1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: 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) + swiper: + specifier: ^11.0.4 + version: registry.npmmirror.com/swiper@11.0.4 wangeditor: specifier: ^4.7.15 version: registry.npmmirror.com/wangeditor@4.7.15 @@ -7093,6 +7096,13 @@ packages: has-flag: registry.npmmirror.com/has-flag@4.0.0 dev: true + registry.npmmirror.com/swiper@11.0.4: + resolution: {integrity: sha512-qtUxILrD4aD++rpKzGrkz3IAWL92f9uTrDwjb6HaNLmPvJhZCE/83DL+9w4kIgDDJeF6QKalV47rMBN77UOVYQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/swiper/-/swiper-11.0.4.tgz} + name: swiper + version: 11.0.4 + engines: {node: '>= 4.7.0'} + dev: false + registry.npmmirror.com/tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz} name: tapable diff --git a/src/components/category-list/constant.js b/src/components/category-list/constant.js index 3e1fbb4..b963f80 100644 --- a/src/components/category-list/constant.js +++ b/src/components/category-list/constant.js @@ -1,4 +1,8 @@ export const apiName = { + /** + * 查询分类 + */ + queryPrimaryCategory: '/category/queryPrimaryCategory', /** * 获取二级和三级标签 */ @@ -15,3 +19,66 @@ export const apiName = { // 查询分类及标签 queryCategoryAndLabel: '/category/queryCategoryAndLabel' } + +/** + * 大分类中的背景图颜色 + */ +export const categoryBackColor = { + 0: '#23b2ff', + 1: '#ea7d4d', + 2: '#e93532', + 3: '#343d71', + 4: '#dc4ad6', + 5: '#72b633', + 6: '#9047de', + 7: '#dc4077', + 8: '#dc4077' +} + +export const mockCategoryList = [ + { + title: '后端', + total: 50, + id: 1 + }, + { + title: '前端1', + total: 50, + id: 2 + }, + { + title: '前端2', + total: 50, + id: 3 + }, + { + title: '前端3', + total: 50, + id: 4 + }, + { + title: '前端4', + total: 50, + id: 5 + }, + { + title: '前端5', + total: 50, + id: 6 + }, + { + title: '前端6', + total: 50, + id: 7 + }, + { + title: '前端7', + total: 50, + id: 8 + }, + { + title: '前端8', + total: 50, + id: 9 + } +] diff --git a/src/components/category-list/index-new.jsx b/src/components/category-list/index-new.jsx index e69de29..156a619 100644 --- a/src/components/category-list/index-new.jsx +++ b/src/components/category-list/index-new.jsx @@ -0,0 +1,38 @@ +import { useState } from 'react' +import LabelList from './label-list' +import PrimaryList from './primary-list' + +const CategoryList = props => { + const [selectValue, setSelectValue] = useState({ + primaryId: '', // 大类ID + categoryId: '', // 二级分类ID, + labelId: '' // 标签ID + }) + + const changePrimaryId = primaryId => { + setSelectValue({ + ...selectValue, + primaryId + }) + } + + const changeLabel = ids => { + const [categoryId, labelId] = ids.split('_') + const values = { + ...selectValue, + categoryId, + labelId + } + setSelectValue({ ...values }) + props.onChangeLabel({ ...values }) + } + + return ( +
+ + +
+ ) +} + +export default CategoryList diff --git a/src/components/category-list/index-new.less b/src/components/category-list/index-new.less new file mode 100644 index 0000000..4fb9882 --- /dev/null +++ b/src/components/category-list/index-new.less @@ -0,0 +1,32 @@ +.category-card { + transition: all 0.5s; + color: white; + &-title { + font-size: 16px; + } + &-count { + font-size: 12px; + } + &:hover { + transform: translateY(-8px); + } + &.active { + transform: translateY(-8px); + } +} + +/** label-list style **/ +.label-list-box { + padding-top: 15px; + .label-list-item { + line-height: 40px; + display: flex; + align-items: center; + .label-title { + width: 120px; + font-weight: bold; + color: #333; + font-size: 14px; + } + } +} diff --git a/src/components/category-list/label-list.jsx b/src/components/category-list/label-list.jsx new file mode 100644 index 0000000..09f436f --- /dev/null +++ b/src/components/category-list/label-list.jsx @@ -0,0 +1,112 @@ +import { CaretDownOutlined, CaretUpOutlined } from '@ant-design/icons' +import req from '@utils/request' +import { Divider, Spin, Tag } from 'antd' +import { useEffect, useState } from 'react' +import { apiName } from './constant' + +const { CheckableTag } = Tag +const maxCount = 4 + +const LabelList = props => { + const { primaryId, changeLabel } = props + const [spinning, setSpinning] = useState(false) + const [categoryAndLabelList, setCategoryAndLabelList] = useState([]) + const [isPutAway, setIsPutAway] = useState(true) + const [checkedLabelId, setCheckedLabelId] = useState() + + const getCategoryAndLabel = () => { + // setSpinning(true) + req({ + method: 'post', + url: apiName.queryCategoryAndLabel, + data: { id: primaryId } + }) + .then(res => { + if (res.data && res.data.length > 0) { + const ids = `${res.data[0].id}_${res.data[0].labelDTOList[0].id}` + setCategoryAndLabelList(res.data) + setCheckedLabelId(ids) + changeLabel(ids) + } else { + setCategoryAndLabelList([]) + setCheckedLabelId('') + changeLabel('') + } + // setSpinning(false) + }) + .catch(err => { + // setSpinning(false) + console.log(err) + }) + } + + const onChangePutAway = () => { + setIsPutAway(!isPutAway) + } + + const changeChecked = (categoryId, labelId) => { + const ids = `${categoryId}_${labelId}` + if (ids === checkedLabelId) return + setCheckedLabelId(ids) + changeLabel(ids) + } + + useEffect(() => { + if (primaryId) { + getCategoryAndLabel() + } + }, [primaryId]) + + return ( + +
+ {categoryAndLabelList.map((categoryItem, index) => { + return ( +
= maxCount && isPutAway ? 'none' : 'flex' + }} + > +
{categoryItem.categoryName}:
+ {categoryItem.labelDTOList.map(labelItem => { + return ( + changeChecked(categoryItem.id, labelItem.id)} + > + {labelItem.labelName} + + ) + })} +
+ ) + })} +
+ {categoryAndLabelList.length > maxCount ? ( + + {isPutAway ? '展开' : '收起'} + {isPutAway ? ( + + ) : ( + + )} + + ) : null} +
+ ) +} + +export default LabelList diff --git a/src/components/category-list/primary-list.jsx b/src/components/category-list/primary-list.jsx new file mode 100644 index 0000000..042b934 --- /dev/null +++ b/src/components/category-list/primary-list.jsx @@ -0,0 +1,89 @@ +import req from '@utils/request' +import { Card, Space, Spin } from 'antd' +import { useEffect, useState } from 'react' +import { Navigation } from 'swiper/modules' +import { Swiper, SwiperSlide } from 'swiper/react' +import { apiName, categoryBackColor, mockCategoryList } from './constant' + +import 'swiper/css' +import 'swiper/css/navigation' +import 'swiper/css/pagination' +import 'swiper/css/scrollbar' +import './index-new.less' + +const PrimaryList = props => { + const [loading, setLoading] = useState(false) + const [primaryCategoryId, setPrimaryCategoryId] = useState() + const [categoryList, setCategoryList] = useState([]) + + /** + * 获取大类分类 + */ + const getPrimaryCategoryInfo = () => { + setLoading(true) + req({ + method: 'post', + url: apiName.queryPrimaryCategory, + data: { categoryType: 1 } + }) + .then(res => { + if (res.data && res.data.length > 0) { + setPrimaryCategoryId(res.data[0].id) + setCategoryList([...res.data]) + props.changePrimaryId(res.data[0].id) + } else { + setPrimaryCategoryId(mockCategoryList[0].id) + setCategoryList(mockCategoryList) + } + setLoading(false) + }) + .catch(err => { + console.log(err) + setLoading(false) + }) + } + + useEffect(() => { + getPrimaryCategoryInfo() + }, []) + + return ( + +
+ + {categoryList.map((item, index) => { + return ( + { + setPrimaryCategoryId(item.id) + props.changePrimaryId(item.id) + }} + > + + +
{item.categoryName}
+
{item.count}道题
+
+
+
+ ) + })} +
+
+
+ ) +} + +export default PrimaryList diff --git a/src/views/question-bank/index.tsx b/src/views/question-bank/index.tsx index 9ad37c4..fea0471 100644 --- a/src/views/question-bank/index.tsx +++ b/src/views/question-bank/index.tsx @@ -1,4 +1,5 @@ -import CategoryList from '@components/category-list' +// import CategoryList from '@components/category-list' +import CategoryList from '@components/category-list/index-new.jsx' import QuestionList from '@components/question-list' import req from '@utils/request' import { memo, useEffect, useState } from 'react' @@ -8,59 +9,31 @@ import { apiName } from './constant' import './index.less' const QuestionBank = () => { - const [firstCategoryList, setFirstCategoryList] = useState[]>([]) const [questionList, setQuestionList] = useState([]) const [labelList, setLabelList] = useState() // 选中的标签列表 const [difficulty, setDiffculty] = useState('') //困难度(全部) const [total, setTotal] = useState(0) // 总条数 const [pageIndex, setPageIndex] = useState(0) - const [primaryCategoryId, setPromaryCategoryId] = useState('') //第一个大类id const [secondCategoryId, setSecondCategoryId] = useState('') + const [selectedValue, setSelectedValue] = useState({ + primaryId: '', // 大类ID + categoryId: '', // 二级分类ID, + labelId: '' // 标签ID + }) + const [loading, setLoading] = useState(false) const [finished, setFinished] = useState(false) const [switchFlag, setSwitchFlag] = useState(false) - /** - * 获取大类分类 - */ - const getPrimaryCategoryInfo = () => { - req({ - method: 'post', - url: apiName.queryPrimaryCategory, - data: { categoryType: 1 } - }) - .then((res: Record) => { - if (res.data && res.data.length > 0) { - setPromaryCategoryId(res.data[0].id) - setFirstCategoryList(res.data) - } - }) - .catch((err: string) => { - console.log(err) - }) - } - - /** - * 切换一级分类 - * @param {*} e - */ - const onChangeCategory = (item: Record) => { - setLabelList('') - setPromaryCategoryId(item.id) - setQuestionList([]) - setTotal(0) - setPageIndex(1) - } - /** * 选择标签时,请求列表数据 * @param {*} secondCategoryId 一级分类id * @param {*} assembleIds 三级标签 assembleIds */ - const onChangeLabel = (secondCategoryId: any, assembleIds: string) => { - setSecondCategoryId(secondCategoryId) - setLabelList(assembleIds) + const onChangeLabel = values => { + console.log(values) + setSelectedValue(values) setQuestionList([]) setTotal(0) setPageIndex(1) @@ -71,8 +44,8 @@ const QuestionBank = () => { const params = { pageNo: pageIndex, pageSize: 20, - labelId: labelList, - categoryId: secondCategoryId, + labelId: selectedValue.labelId, + categoryId: selectedValue.categoryId, subjectDifficult: difficulty || '' } req({ @@ -105,29 +78,10 @@ const QuestionBank = () => { } useEffect(() => { - if (!primaryCategoryId) { - getPrimaryCategoryInfo() - } - }, []) - - useEffect(() => { - if (labelList && secondCategoryId) { + if (selectedValue.labelId) { queryQuestionList() } - }, [labelList, pageIndex, secondCategoryId, difficulty]) - - /** - * 更多分类切换 - * @param {*} e - */ - const onChangeCategoryMore = (id: string, categoryList: Record[]) => { - setFirstCategoryList(categoryList) - setPromaryCategoryId(id) - setLabelList('') - setQuestionList([]) - setPageIndex(1) - setTotal(0) - } + }, [pageIndex, selectedValue.labelId, difficulty]) const scrollHandler = e => { let scrollTop = e.target.scrollTop // listBox 滚动条向上卷曲出去的长度,随滚动变化 @@ -158,16 +112,7 @@ const QuestionBank = () => {
- {firstCategoryList?.length > 0 && ( - - )} +
= { 2: '女' } +const normFile = (e: any) => { + if (Array.isArray(e)) { + return e + } + return e?.fileList +} + const UserInfo = () => { const userInfoStorage = localStorage.getItem('userInfo') - const { loginId = '' } = userInfoStorage ? JSON.parse(userInfoStorage) : {} + const { loginId = '', tokenValue = '' } = userInfoStorage ? JSON.parse(userInfoStorage) : {} const [form] = Form.useForm() const [editFlag, setEditFlag] = useState(false) @@ -130,14 +137,18 @@ const UserInfo = () => { {editFlag ? ( - + { '/auth': { target: env.VITE_API_HOST, changeOrigin: true + }, + '/oss': { + target: env.VITE_API_HOST, + changeOrigin: true } } }