feat: 修改

This commit is contained in:
秋水浮尘
2024-03-03 00:02:50 +08:00
parent 76a300cab0
commit cca31e8de2
16 changed files with 943 additions and 1145 deletions

View File

@@ -38,7 +38,9 @@ const App = () => {
}
useEffect(() => {
if (location.pathname !== '/login' && loginId) {
getUserInfo()
}
}, [])
useEffect(() => {

View File

@@ -23,8 +23,9 @@ const LabelList = props => {
})
.then(res => {
if (res.data && res.data.length > 0) {
const ids = `${res.data[0].id}_${res.data[0].labelDTOList[0].id}`
setCategoryAndLabelList(res.data)
const filterData = [...res.data].filter(item => item?.labelDTOList?.length > 0)
const ids = `${filterData[0].id}_${filterData[0].labelDTOList[0].id}`
setCategoryAndLabelList(filterData)
setCheckedLabelId(ids)
changeLabel(ids)
} else {
@@ -32,10 +33,8 @@ const LabelList = props => {
setCheckedLabelId('')
changeLabel('')
}
// setSpinning(false)
})
.catch(err => {
// setSpinning(false)
console.log(err)
})
}

View File

@@ -1,177 +1,58 @@
import { HeartTwoTone, InfoCircleTwoTone, LikeTwoTone } from '@ant-design/icons'
import { LikeTwoTone } from '@ant-design/icons'
import req from '@utils/request'
import { Input, Modal, Radio, message } from 'antd'
import React, { Component } from 'react'
import './index.less'
const { TextArea } = Input
export default class GoodCollectionError extends Component {
constructor(props) {
super(props)
this.state = {
isGood: false, //是否点赞
isCollection: false, //是否收藏
goodAmount: 0, //点赞数量
collectionAmount: 0, //收藏数量
// index: 1,
question: [], //题目列表
isModal: false, //是否显示纠错弹框
value: 1, //纠错类型对应值
inputValue: '', //纠错详情内容
questionId: '' //题目id
}
}
/**纠错类型 */
errorType = [
{
value: 1,
content: '答案错误'
},
{
value: 2,
content: '题目与答案不符'
}
]
componentDidMount() {
// this.getDetail()
const {
detail: { id, liked, likedCount }
} = this.props
this.setState({
isGood: liked,
goodAmount: likedCount,
questionId: id
})
}
getDetail() {
let params = {
subjectId: this.props.questionId
}
req({
method: 'post',
data: params,
url: 'admin/question/collect/getDetail'
})
.then(res => {
if (res.data) {
this.setState({
isGood: res.data.isThump,
goodAmount: res.data.thumpCount,
isCollection: res.data.isCollect,
collectionAmount: res.data.collectCount
})
}
})
.catch(err => console.log(err))
}
/**
* 点击纠错按钮
*/
handleModal = () => {
return message.info('敬请期待')
this.setState({
isModal: true
})
}
/**
* 点击弹框确认按钮
*/
handleOk = () => {
const { value, inputValue } = this.state
const { questionId } = this.props
let params = {
subjectId: questionId,
errorType: value,
errorMsg: inputValue
}
if (inputValue.length === 0) {
message.warning('请填写纠错详情!')
} else {
this.setState({
isModal: false,
inputValue: ''
})
message.success('感谢纠错,立即更改!')
req({
method: 'post',
data: params,
url: '/admin/question/subjectError/add'
})
}
}
/**
* 点击弹框取消按钮
*/
handleCancel = () => {
this.setState({
isModal: false,
inputValue: ''
})
}
/**
*
* @param {选择纠错类型} e
*/
handleChangeRadio = e => {
this.setState({
value: e.target.value
})
}
/**
*
* @param {纠错详情中填写内容} e
*/
handleChangeInput = e => {
this.setState({
inputValue: e.target.value
})
}
/**
*
* @returns 点击点赞按钮
*/
handleChangeGood = () => {
return message.info('敬请期待')
const { isGood, goodAmount } = this.state
const { questionId } = this.props
const { isGood, goodAmount, questionId } = this.state
let params = {
subjectId: questionId
subjectId: questionId,
status: isGood ? 0 : 1
}
this.setState(
{
isGood: isGood === true ? false : true,
goodAmount: isGood === true ? goodAmount - 1 : goodAmount + 1
isGood: !isGood,
goodAmount: isGood ? goodAmount - 1 : goodAmount + 1
},
() => {
req({
method: 'post',
data: params,
url: 'admin/question/thump/addOrCancel'
}).catch(err => console.log(err))
}
)
}
/**
* 点击收藏按钮
*/
handleChangeCollection = () => {
return message.info('敬请期待')
const { isCollection, collectionAmount } = this.state
const { questionId } = this.props
let params = {
subjectId: questionId
}
this.setState(
req(
{
isCollection: isCollection === true ? false : true,
collectionAmount: isCollection === true ? collectionAmount - 1 : collectionAmount + 1
},
() => {
req({
method: 'post',
data: params,
url: 'admin/question/collect/addOrCancel'
}).catch(err => console.log(err))
url: '/subjectLiked/add'
},
'/subject'
).catch(err => console.log(err))
}
)
}
render() {
const { isCollection, isGood, isModal, value, collectionAmount, goodAmount } = this.state
const { isGood, goodAmount } = this.state
return (
<div className='left'>
<div
@@ -181,87 +62,9 @@ export default class GoodCollectionError extends Component {
this.handleChangeGood()
}}
>
<LikeTwoTone
twoToneColor={isGood == false ? 'grey' : 'blue'}
style={{ marginRight: 4 }}
/>
({goodAmount})
<LikeTwoTone twoToneColor={!isGood ? 'grey' : 'blue'} style={{ marginRight: 4 }} />(
{goodAmount})
</div>
<div
className='collection'
onClick={() => {
this.handleChangeCollection()
}}
>
<HeartTwoTone
twoToneColor={isCollection == false ? 'grey' : 'blue'}
style={{ marginRight: 4 }}
/>
({collectionAmount})
</div>
{/* <div className="comment">
<MessageTwoTone twoToneColor="blue" style={{ marginRight: 4 }} />
评论
</div> */}
<div
className='error-collection'
onClick={() => {
this.handleModal()
}}
>
<InfoCircleTwoTone twoToneColor='red' style={{ marginRight: 4 }} />
纠错
</div>
<Modal
className='error-modal'
title='题目纠错'
open={isModal}
destroyOnClose={true}
onOk={() => {
this.handleOk()
}}
onCancel={() => {
this.handleCancel()
}}
okText='确认'
cancelText='取消'
style={{ fontWeight: 500 }}
>
<div>
<div className='error-collection-title'>纠错类型</div>
<div className='error-collection-type'>
{this.errorType.map((item, index) => {
return (
<div key={index} className='error-collection-type-detail'>
<Radio.Group
onChange={e => {
this.handleChangeRadio(e)
}}
defaultValue={1}
buttonStyle='solid'
value={value}
>
<Radio.Button value={item.value} className='ll'>
{item.content}
</Radio.Button>
</Radio.Group>
</div>
)
})}
</div>
<div className='error-collection-title'>纠错详情</div>
<TextArea
className='error-input'
placeholder='请输入...'
maxLength={256}
rows={4}
showCount={true}
onChange={e => {
this.handleChangeInput(e)
}}
/>
</div>
</Modal>
</div>
)
}

View File

@@ -14,7 +14,8 @@ export default function request(config, url) {
withCredentials: true, // send cookies when cross-domain requests
headers: {
'Content-Type': 'application/json; charset=utf-8',
[userInfo.tokenName]: 'jichi ' + userInfo.tokenValue
[userInfo.tokenName]: 'jichi ' + userInfo.tokenValue,
loginId: userInfo.loginId || ''
}
})

View File

@@ -1,20 +1,19 @@
import { Pagination, Button, Modal, Input, Radio, message } from 'antd'
import React, { Component, Fragment, useState, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import GoodCollectionError from '@components/good-collection-error'
import './index.less'
import req from '@utils/request'
import { Pagination } from 'antd'
import { Component, Fragment, useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import './index.less'
const grade: Record<string, string> = {
1: '初级',
2: '中级',
3: '高级',
4: '资深',
5: '专家',
5: '专家'
}
const BrushQuestions = () => {
const { id } = useParams()
const [question, setQuestion] = useState<Record<string, any>>(null)
const [index, setIndex] = useState(1)
@@ -26,51 +25,49 @@ const BrushQuestions = () => {
data: {
id
},
url: '/querySubjectInfo',
url: '/querySubjectInfo'
})
.then((res) => {
.then(res => {
if (res.success && res.data) {
setQuestion(res.data)
}
})
.catch((err) => console.log(err))
.catch(err => console.log(err))
}, [id])
return (
<div className="brush-questions-box">
<div className="question-box">
<div className="question">
<div className="question-type">
<div className="number">{index}</div>
<div className="type"></div>
<div className='brush-questions-box'>
<div className='question-box'>
<div className='question'>
<div className='question-type'>
<div className='number'>{index}</div>
<div className='type'></div>
</div>
</div>
</div>
{
question ? <Fragment>
<div className="question-content">
<div className="difficulty">
{question ? (
<Fragment>
<div className='question-content'>
<div className='difficulty'>
{grade[question.subjectDifficult]}-{question?.labelName.join('、')}
</div>
<div>{question.subjectName}</div>
</div>
<div className="answer-box">
<div className="reference-answer"></div>
<div className='answer-box'>
<div className='reference-answer'></div>
<div
className="answer-content wang-editor-style"
className='answer-content wang-editor-style'
dangerouslySetInnerHTML={{
__html: question.subjectAnswer,
__html: question.subjectAnswer
}}
></div>
<br />
</div>
<div className="change-question-box">
<GoodCollectionError
questionId={question.id}
/>
<div className='change-question-box'>
<GoodCollectionError detail={question} />
</div>
</Fragment> : null
}
</Fragment>
) : null}
</div>
)
}
@@ -84,16 +81,22 @@ class BrushQuestions1 extends Component {
isGood: 0,
isCollection: 0,
index: 1,
question: [{
id: 1, labelNames: ["原理"], subjectName: 'JDK 和 JRE 有什么区别?', difficulty: 1,
question: [
{
id: 1,
labelNames: ['原理'],
subjectName: 'JDK 和 JRE 有什么区别?',
difficulty: 1,
subjectAnswer: `<p>JDKJava Development Kit 的简称Java 开发工具包,提供了 Java 的开发环境和运行环境。</p>
<p>JREJava Runtime Environment 的简称Java 运行环境,为 Java 的运行提供了所需环境。</p>
<p>具体来说 JDK 其实包含了 JRE同时还包含了编译 Java 源码的编译器 Javac还包含了很多 Java 程序调试和分析的工具。</p>
<p>简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。</p>` }],
<p>简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。</p>`
}
],
// answer: '',
isModal: false, //是否显示纠错弹框
value: 1, //纠错类型对应值
inputValue: '', //纠错详情内容
inputValue: '' //纠错详情内容
}
}
pageIndex = 1
@@ -106,7 +109,7 @@ class BrushQuestions1 extends Component {
2: '中级',
3: '高级',
4: '资深',
5: '专家',
5: '专家'
}
goodCollectionError = GoodCollectionError | null
componentDidMount() {
@@ -127,23 +130,23 @@ class BrushQuestions1 extends Component {
let params = {
pageInfo: {
pageIndex: this.pageIndex,
pageSize: 1,
pageSize: 1
},
difficulty: this.difficulty,
primaryCategoryId: this.primaryCategoryId,
assembleIds: this.assembleIds,
assembleIds: this.assembleIds
}
return await req({
method: 'post',
data: params,
url: '/querySubjectInfo',
url: '/querySubjectInfo'
})
.then((res) => {
.then(res => {
if (res.data && res.data?.pageList?.length > 0) {
this.total = res.data.pageInfo.total
this.setState(
{
question: res.data.pageList,
question: res.data.pageList
},
() => {
this.goodCollectionError.getDetail()
@@ -151,21 +154,21 @@ class BrushQuestions1 extends Component {
)
}
})
.catch((err) => console.log(err))
.catch(err => console.log(err))
}
onChangePagination = async (pageIndex) => {
onChangePagination = async pageIndex => {
this.pageIndex = pageIndex
this.setState({ index: pageIndex })
// await this.getInterviewSubjectList()
}
handleNextQuestion = async (value) => {
handleNextQuestion = async value => {
let { index } = this.state
this.pageIndex += value
index += value
this.setState({
index: index,
index: index
})
// await this.getInterviewSubjectList()
}
@@ -173,12 +176,12 @@ class BrushQuestions1 extends Component {
render() {
const { index, question } = this.state
return (
<div className="brush-questions-box">
<div className="question-box">
<div className="question">
<div className="question-type">
<div className="number">{index}</div>
<div className="type"></div>
<div className='brush-questions-box'>
<div className='question-box'>
<div className='question'>
<div className='question-type'>
<div className='number'>{index}</div>
<div className='type'></div>
</div>
{/* <div className="question-number">
<div className="now-number">{index}</div>
@@ -190,27 +193,27 @@ class BrushQuestions1 extends Component {
{question.map((item, index) => {
return (
<div key={index}>
<div className="question-content">
<div className="difficulty">
<div className='question-content'>
<div className='difficulty'>
{this.grade[item.difficulty]}-{item.labelNames.join('、')}
</div>
<div>{item.subjectName}</div>
</div>
<div className="answer-box">
<div className="reference-answer"></div>
<div className='answer-box'>
<div className='reference-answer'></div>
<div
className="answer-content wang-editor-style"
className='answer-content wang-editor-style'
dangerouslySetInnerHTML={{
// __html: item.subjectAnswer,
__html: item.subjectAnswer,
__html: item.subjectAnswer
}}
></div>
<br />
</div>
<div className="change-question-box">
<div className='change-question-box'>
<GoodCollectionError
questionId={question[0].id}
ref={(ref) => {
ref={ref => {
this.goodCollectionError = ref
}}
/>
@@ -241,12 +244,12 @@ class BrushQuestions1 extends Component {
})}
</Fragment>
<div className="jump-question">
<div className='jump-question'>
{this.total > 0 && (
<Pagination
style={{
padding: '24px 0',
textAlign: 'center',
textAlign: 'center'
}}
showQuickJumper
current={this.pageIndex}

View File

@@ -1,5 +1,5 @@
import Logo from '@/imgs/logo.jpg'
import { HeartOutlined, LikeOutlined, LoginOutlined, UserOutlined } from '@ant-design/icons'
import { LikeOutlined, LoginOutlined, UserOutlined } from '@ant-design/icons'
import TopMenu from '@components/top-menu'
import LoginQrcode from '@imgs/personal_qr_code.jpg'
import req from '@utils/request'
@@ -18,12 +18,12 @@ const menuItems = [
icon: <UserOutlined style={{ fontSize: '16px' }} />,
path: '/user-info'
},
{
label: '我的收藏',
key: 2,
icon: <HeartOutlined style={{ fontSize: '16px' }} />,
path: '/personal-center/0'
},
// {
// label: '我的收藏',
// key: 2,
// icon: <HeartOutlined style={{ fontSize: '16px' }} />,
// path: '/personal-center/0'
// },
{
label: '我的点赞',
key: 3,

View File

@@ -66,7 +66,7 @@ const Login = () => {
<div className='qrcode-box'>
<div className='qrcode-desc'>
<p></p>
<p></p>
<p> </p>
</div>
<div className='qrcode-img'>
<img src={LoginQrcode} alt='' />

View File

@@ -1,3 +1,4 @@
import req from '@utils/request'
import { Card, Pagination, Spin } from 'antd'
import React, { Component } from 'react'
import { goodTabType } from '../../constant'
@@ -53,23 +54,47 @@ export default class GoodBag extends Component {
* 获取一级分类数据
*/
getGoodList() {
this.total = 3
this.setState({
goodList: [
req(
{
id: 100,
subjectName: 'Redis支持哪几种数据类型'
},
{
id: 101,
subjectName: 'Redis的高级数据类型有什么'
},
{
id: 102,
subjectName: 'Redis的优点有什么'
method: 'post',
url: '/subjectLiked/getSubjectLikedPage',
data: {
pageNo: 1,
pageSize: 10
}
]
},
'/subject'
).then(res => {
if (res.success && res.code === 200) {
this.total = res.data?.total || 0
this.setState({
goodList: res.data.result
})
} else {
this.total = 0
this.setState({
goodList: []
})
}
})
// this.total = 3
// this.setState({
// goodList: [
// {
// id: 100,
// subjectName: 'Redis支持哪几种数据类型'
// },
// {
// id: 101,
// subjectName: 'Redis的高级数据类型有什么'
// },
// {
// id: 102,
// subjectName: 'Redis的优点有什么'
// }
// ]
// })
}
/**

View File

@@ -24,12 +24,12 @@ const CollectionQuestion = props => {
return (
<div
className='collection-bag-component-tab1-body-item'
key={`collection_question_${item.id}`}
key={`collection_question_${item.subjectId}`}
>
<div className='collection-bag-component-tab1-body-item-question'>
<span
className='collection-bag-component-tab1-body-item-question-content'
onClick={() => handleJump(item.id)}
onClick={() => handleJump(item.subjectId)}
>
{item.subjectName}
</span>

View File

@@ -1,9 +1,4 @@
import { LikeTwoTone, StarTwoTone } from '@ant-design/icons'
import { Menu } from 'antd'
import React, { useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'
import CollectionBag from './components/collection-bag'
import React from 'react'
import GoodBag from './components/good-bag'
import './index.less'
@@ -12,86 +7,89 @@ const personList = {
1: '点赞'
}
// const PersonalCenter = props => {
// const [currentKeyMap, setCurrentKeyMap] = useState(0)
// const { userInfo } = useSelector(store => store.userInfo)
// const [selectedKeys, setSelectedKeys] = useState('0')
// const { tab } = useParams()
// useEffect(() => {
// setCurrentKeyMap(+tab)
// setSelectedKeys(tab)
// }, [tab])
// const handleClick = ({ key }) => {
// setCurrentKeyMap(Number(key))
// setSelectedKeys(key)
// }
// return (
// <div className='personal-center-box'>
// <div className='personal-center-introduction'>
// <div className='personal-center-introduction-detail'>
// <div className='personal-center-introduction-detail-headImg'>
// <img src={userInfo.avatar} style={{ width: 60, height: 60, borderRadius: '50%' }} />
// </div>
// <div className='personal-center-introduction-detail-text'>
// <div className='personal-center-introduction-detail-name'>{userInfo.nickName}</div>
// {/* <div className='personal-center-introduction-detail-information'>
// <span className='personal-center-introduction-detail-information-content'>
// <IdcardOutlined style={{ color: 'blue', marginRight: '3px' }} />
// </span>
// <span className='personal-center-introduction-detail-information-content'>
// <MailOutlined style={{ color: 'blue', marginRight: '3px' }} />
// </span>
// </div> */}
// </div>
// </div>
// <div className='personal-center-introduction-result'>
// {/* <div className='personal-center-introduction-result-item'>
// <div className='personal-center-introduction-result-item-number'>{10}</div>
// <div>练题</div>
// </div> */}
// {/* <div className='personal-center-introduction-result-item'>
// <div className='personal-center-introduction-result-item-number'>{inputAmount}</div>
// <div>录题</div>
// </div> */}
// <div className='personal-center-introduction-result-item'>
// <div className='personal-center-introduction-result-item-number'>{20}</div>
// <div>点赞</div>
// </div>
// <div className='personal-center-introduction-result-item'>
// <div className='personal-center-introduction-result-item-number'>{30}</div>
// <div>收藏</div>
// </div>
// </div>
// </div>
// <div className='personal-center-content'>
// <div className='personal-center-content-left'>
// <Menu
// mode='inline'
// onClick={handleClick}
// style={{ width: 256 }}
// selectedKeys={[selectedKeys]}
// >
// <Menu.Item key={0}>
// <StarTwoTone twoToneColor='rgb(252,132,67)' />
// <span>{personList[0]}</span>
// </Menu.Item>
// <Menu.Item key={1}>
// <LikeTwoTone twoToneColor='#99bbff' />
// <span>{personList[1]}</span>
// </Menu.Item>
// </Menu>
// </div>
// <div className='personal-center-content-right'>
// {currentKeyMap === 0 && <CollectionBag />}
// {currentKeyMap === 1 && <GoodBag />}
// </div>
// </div>
// </div>
// )
// }
const PersonalCenter = props => {
const [currentKeyMap, setCurrentKeyMap] = useState(0)
const { userInfo } = useSelector(store => store.userInfo)
const [selectedKeys, setSelectedKeys] = useState('0')
const { tab } = useParams()
useEffect(() => {
setCurrentKeyMap(+tab)
setSelectedKeys(tab)
}, [tab])
const handleClick = ({ key }) => {
setCurrentKeyMap(Number(key))
setSelectedKeys(key)
}
return (
<div className='personal-center-box'>
<div className='personal-center-introduction'>
<div className='personal-center-introduction-detail'>
<div className='personal-center-introduction-detail-headImg'>
<img src={userInfo.avatar} style={{ width: 60, height: 60, borderRadius: '50%' }} />
</div>
<div className='personal-center-introduction-detail-text'>
<div className='personal-center-introduction-detail-name'>{userInfo.nickName}</div>
{/* <div className='personal-center-introduction-detail-information'>
<span className='personal-center-introduction-detail-information-content'>
<IdcardOutlined style={{ color: 'blue', marginRight: '3px' }} />
</span>
<span className='personal-center-introduction-detail-information-content'>
<MailOutlined style={{ color: 'blue', marginRight: '3px' }} />
</span>
</div> */}
</div>
</div>
<div className='personal-center-introduction-result'>
{/* <div className='personal-center-introduction-result-item'>
<div className='personal-center-introduction-result-item-number'>{10}</div>
<div>练题</div>
</div> */}
{/* <div className='personal-center-introduction-result-item'>
<div className='personal-center-introduction-result-item-number'>{inputAmount}</div>
<div>录题</div>
</div> */}
<div className='personal-center-introduction-result-item'>
<div className='personal-center-introduction-result-item-number'>{20}</div>
<div>点赞</div>
</div>
<div className='personal-center-introduction-result-item'>
<div className='personal-center-introduction-result-item-number'>{30}</div>
<div>收藏</div>
</div>
</div>
</div>
<div className='personal-center-content'>
<div className='personal-center-content-left'>
<Menu
mode='inline'
onClick={handleClick}
style={{ width: 256 }}
selectedKeys={[selectedKeys]}
>
<Menu.Item key={0}>
<StarTwoTone twoToneColor='rgb(252,132,67)' />
<span>{personList[0]}</span>
</Menu.Item>
<Menu.Item key={1}>
<LikeTwoTone twoToneColor='#99bbff' />
<span>{personList[1]}</span>
</Menu.Item>
</Menu>
</div>
<div className='personal-center-content-right'>
{currentKeyMap === 0 && <CollectionBag />}
{currentKeyMap === 1 && <GoodBag />}
</div>
</div>
</div>
)
return <GoodBag />
}
export default PersonalCenter

View File

@@ -1,21 +1,21 @@
import React, { Fragment, Component } from 'react';
import req from '@utils/request';
import RankingBox from '../ranking-box';
import { apiName, RankingType } from '../../constant';
import { mockRankingModuleList } from '../../mock';
import req from '@utils/request'
import React, { Component, Fragment } from 'react'
import { RankingType, apiName } from '../../constant'
import { mockRankingModuleList } from '../../mock'
import RankingBox from '../ranking-box'
class PracticeList extends Component {
constructor(props) {
super(props);
super(props)
this.state = {
contributionList: mockRankingModuleList[0].rankingList,
contributeType: 0,
isLoading: false,
};
isLoading: false
}
}
componentDidMount() {
// this.getPracticeRankList();
this.getPracticeRankList()
}
/**
@@ -24,23 +24,22 @@ class PracticeList extends Component {
getPracticeRankList() {
req({
method: 'post',
data: {},
url: apiName.getPracticeRankList,
url: apiName.getPracticeRankList
})
.then((res) => {
.then(res => {
if (res.data && res.data.length > 0) {
this.setState({
contributionList: res.data,
isLoading: false,
});
isLoading: false
})
} else {
this.setState({
contributionList: [],
isLoading: false,
});
isLoading: false
})
}
})
.catch((err) => console.log(err));
.catch(err => console.log(err))
}
/**
@@ -48,22 +47,22 @@ class PracticeList extends Component {
* @param {*} index
* @returns
*/
onChangeRanking = (index) => {
onChangeRanking = index => {
console.log(index, 'practice index')
this.setState({
contributeType: index,
});
};
contributeType: index
})
}
/**
* 去练题
*/
onChangeJump = () => {
this.props.history.push('/practice-questions');
};
this.props.history.push('/practice-questions')
}
render() {
const { contributionList, isLoading, contributeType } = this.state;
const { contributionList, isLoading, contributeType } = this.state
return (
<Fragment>
{contributionList?.length > 0 && (
@@ -77,8 +76,8 @@ class PracticeList extends Component {
/>
)}
</Fragment>
);
)
}
}
export default PracticeList;
export default PracticeList

View File

@@ -29,7 +29,9 @@ export default function RankingBox(props) {
}
// props.onHandleJump && props.onHandleJump()
})
const tabList = [
const tabList =
rankingType === 1
? [
{
tab: '本月排行',
key: 'month'
@@ -39,6 +41,12 @@ export default function RankingBox(props) {
key: 'total'
}
]
: [
{
tab: '总榜',
key: 'total'
}
]
// 获得当前下标的数据
let rankingList = contributionList || []
@@ -79,24 +87,24 @@ export default function RankingBox(props) {
{index > 2 && index + 1}
</div>
<div className='ranking-head-img'>
<img src={item.headImg} className='ranking-head-icon' />
<img src={item.createUserAvatar} className='ranking-head-icon' />
</div>
<Popover
title={<div>{item.name}</div>}
title={<div>{item.createUser}</div>}
content={
<div className='tooltip-info'>
<div>{item.name}</div>
<div>{item.createUser}</div>
{/* <div>{item.organizationFullName}</div> */}
</div>
}
>
<div className='ranking-info'>
<div className='ranking-name'>{item.name}</div>
<div className='ranking-name'>{item.createUser}</div>
{/* <div className="ranking-department">{item.organizationName}</div> */}
</div>
</Popover>
</div>
<div className='ranking-right'>🔥 {item.count}</div>
<div className='ranking-right'>🔥 {item.subjectCount}</div>
</div>
)
})}

View File

@@ -1,4 +1,3 @@
export const apiName = {
/**
* 查询分类
@@ -11,9 +10,13 @@ export const apiName = {
queryCategoryByPrimary: '/category/queryCategoryByPrimary',
// 获取题目列表
getSubjectPage: '/getSubjectPage'
getSubjectPage: '/getSubjectPage',
};
/**
* 练题排行榜
*/
getPracticeRankList: '/getContributeList'
}
/**
* 模块类型
@@ -26,21 +29,21 @@ export const RankingType = {
/**
* 排行榜
*/
practice: 2,
};
practice: 2
}
/**
* 模块名称
*/
export const RankingTypeText = {
[RankingType.contribution]: '贡献榜',
[RankingType.practice]: '综合练习榜',
};
[RankingType.contribution]: '出题贡献榜',
[RankingType.practice]: '综合练习榜'
}
/**
* 对应按钮名字
*/
export const RankingTypeBtnText = {
[RankingType.contribution]: '去出题',
[RankingType.practice]: '去练习',
};
[RankingType.practice]: '去练习'
}

View File

@@ -132,8 +132,8 @@ const QuestionBank = () => {
</div>
</div>
<div className='ranking-box'>
<RankingList />
<ContributionList />
<RankingList />
</div>
</div>
)

View File

@@ -9,7 +9,7 @@ export const mockRankingModuleList = [
headImg:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王1',
count: 160,
count: 160
},
{
id: 2,
@@ -17,7 +17,7 @@ export const mockRankingModuleList = [
headImg:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王2',
count: 140,
count: 140
},
{
id: 3,
@@ -25,7 +25,7 @@ export const mockRankingModuleList = [
headImg:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王',
count: 101,
count: 101
},
{
id: 4,
@@ -33,7 +33,7 @@ export const mockRankingModuleList = [
headImg:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅小王',
count: 100,
count: 100
},
{
id: 5,
@@ -41,9 +41,9 @@ export const mockRankingModuleList = [
headImg:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王5',
count: 99,
},
],
count: 99
}
]
},
{
id: 2,
@@ -52,46 +52,46 @@ export const mockRankingModuleList = [
{
id: 1,
wechatName: 'jcdw5',
headImg:
createUserAvatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅小王',
count: 160,
createUser: '鸡翅小王',
subjectCount: 160
},
{
id: 2,
wechatName: 'jcdw6',
headImg:
createUserAvatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王2',
count: 150,
createUser: '鸡翅大王2',
subjectCount: 150
},
{
id: 3,
wechatName: 'jcdw7',
headImg:
createUserAvatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王',
count: 101,
createUser: '鸡翅大王',
subjectCount: 101
},
{
id: 4,
wechatName: 'jcdw8',
headImg:
createUserAvatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王4',
count: 100,
createUser: '鸡翅大王4',
subjectCount: 100
},
{
id: 5,
wechatName: 'jcdw9',
headImg:
createUserAvatar:
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg1.doubanio.com%2Fview%2Fnote%2Flarge%2Fpublic%2Fp37015927.jpg&refer=http%3A%2F%2Fimg1.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1699286185&t=00db8ff5a1e11783f6c8eba954a5891f',
name: '鸡翅大王5',
count: 99,
},
],
},
];
createUser: '鸡翅大王5',
subjectCount: 99
}
]
}
]
export const mockDataList = [
{
@@ -101,7 +101,7 @@ export const mockDataList = [
{ name: '数学', id: 5050 },
{ name: '穷举', id: 596 },
{ name: '贪心', id: 592 },
{ name: '二分', id: 5058 },
{ name: '二分', id: 5058 }
],
id: 0,
grade: 1,
@@ -112,7 +112,7 @@ export const mockDataList = [
questionTitle: '非空数组某元素只出现1次其余出现2次找到出现1次的元素',
tags: [
{ name: '数学', id: 5050 },
{ name: '穷举', id: 596 },
{ name: '穷举', id: 596 }
],
id: 1,
grade: 2,
@@ -123,88 +123,88 @@ export const mockDataList = [
questionTitle: 'Proxy、Observable的区别',
tags: [
{ name: '贪心', id: 592 },
{ name: '二分', id: 5058 },
{ name: '二分', id: 5058 }
],
id: 2,
grade: 3,
questionType: 3,
questionType: 3
},
{
questionTitle: '谈谈浏览器的回流与重绘如何优化dom渲染呢',
tags: [
{ name: '字符串', id: 579 },
{ name: '模拟', id: 595 },
{ name: '模拟', id: 595 }
],
id: 3,
grade: 1,
questionType: 1,
questionType: 1
},
{
questionTitle: 'API指标有哪些为什么有白屏现象考虑哪些方向优化',
tags: [
{ name: '字符串', id: 579 },
{ name: '模拟', id: 595 },
{ name: '模拟', id: 595 }
],
id: 4,
grade: 2,
questionType: 4,
questionType: 4
},
{
questionTitle: '将两个升序链表合并为一个新的升序链表并返回',
tags: [{ name: '数学', id: 5050 }],
id: 5,
grade: 1,
questionType: 2,
questionType: 2
},
{
questionTitle: '对MVP架构的理解',
tags: [
{ name: '递归', id: 591 },
{ name: '动态规划', id: 593 },
{ name: '动态规划', id: 593 }
],
id: 6,
grade: 3,
questionType: 5,
questionType: 5
},
{
questionTitle: 'SPA页面的前端路由实现方案',
tags: [
{ name: '排序', id: 590 },
{ name: '数组', id: 578 },
{ name: '数组', id: 578 }
],
id: 7,
grade: 2,
questionType: 1,
questionType: 1
},
{
questionTitle: '怎么看 nodejs 可支持高并发',
tags: [
{ name: '数学', id: 5050 },
{ name: '模拟', id: 595 },
{ name: '模拟', id: 595 }
],
id: 8,
grade: 2,
questionType: 2,
questionType: 2
},
{
questionTitle: '二叉树遍历',
tags: [
{ name: '树', id: 583 },
{ name: '搜索', id: 3381 },
{ name: '搜索', id: 3381 }
],
id: 9,
grade: 3,
questionType: 4,
questionType: 4
},
{
questionTitle: '玛雅人的密码',
tags: [
{ name: '图', id: 584 },
{ name: '搜索', id: 3381 },
{ name: '搜索', id: 3381 }
],
id: 10,
grade: 1,
questionType: 3,
questionType: 3
},
{ questionTitle: '求最大最小数', tags: [], id: 11, grade: 1, questionType: 1 },
{
@@ -212,7 +212,7 @@ export const mockDataList = [
tags: [{ name: '动态规划', id: 593 }],
id: 12,
grade: 1,
questionType: 1,
questionType: 1
},
{ questionTitle: 'abc', tags: [{ name: '穷举', id: 596 }], id: 13, grade: 1, questionType: 5 },
{
@@ -220,68 +220,68 @@ export const mockDataList = [
tags: [
{ name: '递归', id: 591 },
{ name: '数学', id: 5050 },
{ name: '二分', id: 5058 },
{ name: '二分', id: 5058 }
],
id: 14,
grade: 1,
questionType: 3,
questionType: 3
},
{
questionTitle: 'n的阶乘',
tags: [{ name: '数学', id: 5050 }],
id: 15,
grade: 1,
questionType: 3,
questionType: 3
},
{
questionTitle: '特殊乘法',
tags: [
{ name: '模拟', id: 595 },
{ name: '数组', id: 578 },
{ name: '数学', id: 5050 },
{ name: '数学', id: 5050 }
],
id: 16,
grade: 1,
questionType: 3,
questionType: 3
},
{
questionTitle: '今年的第几天?',
tags: [
{ name: '递归', id: 591 },
{ name: '数学', id: 5050 },
{ name: '穷举', id: 596 },
{ name: '穷举', id: 596 }
],
id: 17,
grade: 1,
questionType: 2,
questionType: 2
},
{
questionTitle: '完数VS盈数',
tags: [{ name: '数学', id: 5050 }],
id: 18,
grade: 1,
questionType: 3,
questionType: 3
},
{
questionTitle: '递推数列',
tags: [
{ name: '动态规划', id: 593 },
{ name: '数学', id: 5050 },
{ name: '数学', id: 5050 }
],
id: 19,
grade: 1,
questionType: 1,
questionType: 1
},
{ questionTitle: '最大序列和', tags: [{ name: '动态规划', id: 593 }], id: 20, grade: 1 },
{
questionTitle: '最小花费',
tags: [
{ name: '动态规划', id: 593 },
{ name: '图', id: 584 },
{ name: '图', id: 584 }
],
id: 21,
grade: 1,
questionType: 2,
questionType: 2
},
{ questionTitle: 'N的阶乘', tags: [{ name: '数学', id: 5050 }], id: 22, grade: 1 },
{
@@ -290,33 +290,33 @@ export const mockDataList = [
{ name: '数组', id: 578 },
{ name: '数学', id: 5050 },
{ name: '哈希', id: 585 },
{ name: '栈', id: 581 },
{ name: '栈', id: 581 }
],
id: 23,
grade: 1,
questionType: 5,
questionType: 5
},
{
questionTitle: '10进制 VS 2进制',
tags: [
{ name: '数学', id: 5050 },
{ name: '位运算', id: 5074 },
{ name: '位运算', id: 5074 }
],
id: 24,
grade: 1,
questionType: 3,
questionType: 3
},
{
questionTitle: '查找学生信息',
tags: [
{ name: '数组', id: 578 },
{ name: '模拟', id: 595 },
{ name: '模拟', id: 595 }
],
id: 25,
grade: 1,
questionType: 2,
},
];
questionType: 2
}
]
/**
* 一级分类
*/
@@ -331,8 +331,8 @@ export const mockTabList = [
{ id: 8, levelName: '产品', count: 1 },
{ id: 9, levelName: '视觉', count: 100 },
{ id: 10, levelName: '产品', count: 1 },
{ id: 11, levelName: '视觉', count: 100 },
];
{ id: 11, levelName: '视觉', count: 100 }
]
// 二级数据
export const mockCategoryList = {
@@ -370,8 +370,8 @@ export const mockCategoryList = {
{ id: 26, levelName: '枚举法', count: 109 },
{ id: 27, levelName: '最短路', count: 6 },
{ id: 28, levelName: '贪心法', count: 85 },
{ id: 29, levelName: '最小生成树', count: 3 },
],
{ id: 29, levelName: '最小生成树', count: 3 }
]
},
{
id: 2,
@@ -399,8 +399,8 @@ export const mockCategoryList = {
{ id: 20, levelName: '并查集', count: 36 },
{ id: 21, levelName: '树状数组', count: 7 },
{ id: 22, levelName: '线段树', count: 21 },
{ id: 23, levelName: '平衡树', count: 7 },
],
{ id: 23, levelName: '平衡树', count: 7 }
]
},
{
id: 3,
@@ -425,9 +425,9 @@ export const mockCategoryList = {
{ id: 17, levelName: '约束', count: 3 },
{ id: 18, levelName: 'IFNULL/COLLAPSE', count: 2 },
{ id: 19, levelName: 'ANY', count: 2 },
{ id: 20, levelName: 'ALL', count: 2 },
],
},
{ id: 20, levelName: 'ALL', count: 2 }
]
}
],
// 前端
2: [
@@ -438,19 +438,19 @@ export const mockCategoryList = {
{
id: 1,
levelName: 'IOSIOSIOSIOS',
count: 13,
count: 13
},
{
id: 2,
levelName: '安卓',
count: 130,
count: 130
},
{
id: 3,
levelName: '鸿蒙',
count: 134,
},
],
count: 134
}
]
},
{
id: 2,
@@ -459,19 +459,19 @@ export const mockCategoryList = {
{
id: 1,
levelName: 'Vue.js',
count: 13,
count: 13
},
{
id: 2,
levelName: 'React.js',
count: 13,
count: 13
},
{
id: 3,
levelName: 'Bootstrap',
count: 13,
},
],
count: 13
}
]
},
{
id: 3,
@@ -481,9 +481,9 @@ export const mockCategoryList = {
{ id: 2, levelName: '京东小程序', count: 13 },
{ id: 3, levelName: '支付宝小程序', count: 13 },
{ id: 4, levelName: '百度小程序', count: 13 },
{ id: 5, levelName: 'QQ小程序', count: 13 },
],
},
{ id: 5, levelName: 'QQ小程序', count: 13 }
]
}
],
// 后端
3: [
@@ -494,19 +494,19 @@ export const mockCategoryList = {
{
id: 1,
levelName: 'Spring框架',
count: 17,
count: 17
},
{
id: 2,
levelName: 'Struts框架',
count: 127,
count: 127
},
{
id: 3,
levelName: 'Hibernate框架',
count: 170,
},
],
count: 170
}
]
},
{
id: 2,
@@ -515,15 +515,15 @@ export const mockCategoryList = {
{
id: 1,
levelName: 'SpringMVC框架',
count: 170,
count: 170
},
{
id: 2,
levelName: 'Mybatis框架',
count: 1,
},
],
},
count: 1
}
]
}
],
// 测试
4: [
@@ -534,20 +534,20 @@ export const mockCategoryList = {
{
id: 1,
levelName: '管理工具',
count: 16,
count: 16
},
{
id: 2,
levelName: 'UI自动化',
count: 16,
count: 16
},
{
id: 3,
levelName: '接口自动化',
count: 16,
},
],
},
count: 16
}
]
}
],
// 人工智能
5: [
@@ -559,8 +559,8 @@ export const mockCategoryList = {
{ id: 2, levelName: '数据预处理', count: 127 },
{ id: 3, levelName: 'Numpy', count: 170 },
{ id: 4, levelName: 'Matplotlib', count: 170 },
{ id: 5, levelName: 'Pandas', count: 170 },
],
{ id: 5, levelName: 'Pandas', count: 170 }
]
},
{
id: 2,
@@ -569,12 +569,12 @@ export const mockCategoryList = {
{ id: 1, levelName: '工具库', count: 170 },
{ id: 2, levelName: '分类', count: 1 },
{ id: 3, levelName: '模型', count: 170 },
{ id: 4, levelName: '决策树', count: 170 },
],
},
{ id: 4, levelName: '决策树', count: 170 }
]
}
],
// 产品
6: [],
// 视觉
7: [],
};
7: []
}

View File

@@ -1,93 +1,57 @@
import { ExclamationCircleOutlined } from '@ant-design/icons'
import { queryParse } from '@utils'
import req from '@utils/request'
import { Card, Input, Pagination, Skeleton, message } from 'antd'
import React, { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import './index.less'
const { Search } = Input
const mockList = [
{
id: 100,
subjectName: 'Redis支持哪几种数据类型',
subjectDifficult: 1,
subjectType: 4,
subjectScore: 1,
subjectParse: '解析什么',
subjectAnswer:
'<p><br></p><ol><li>String字符串</li><li>List列表</li><li>Hash字典</li><li>Set集合</li><li>Sorted Set有序集合</li></ol><p><br></p><p><strong>String</strong></p><p><br></p><p>String是简单的 key-value 键值对value 不仅可以是 String也可以是数字。String在redis内部存储默认就是一个字符串被redisObject所引用当遇到incr,decr等操作时会转成数值型进行计算此时redisObject的encoding字段为int。</p><p><br></p><p><strong>List</strong></p><p><br></p><p>Redis列表是简单的字符串列表可以类比到C++中的std::list简单的说就是一个链表或者说是一个队列。可以从头部或尾部向Redis列表添加元素。列表的最大长度为2^32 - 1也即每个列表支持超过40亿个元素。</p><p><br></p><p>Redis list的实现为一个双向链表即可以支持反向查找和遍历更方便操作不过带来了部分额外的内存开销Redis内部的很多实现包括发送缓冲队列等也都是用的这个数据结构。</p><p><br></p><p><strong>Hash</strong></p><p><br></p><p>Redis Hash对应Value内部实际就是一个HashMap实际这里会有2种不同实现这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储而不会采用真正的HashMap结构对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap。</p><p><br></p><p><strong>Set</strong></p><p><br></p><p>set 的内部实现是一个 value永远为null的HashMap实际就是通过计算hash的方式来快速排重的这也是set能提供判断一个成员是否在集合内的原因。</p><p><br></p><p><strong>Sorted Set</strong></p><p><br></p><p>Redis有序集合类似Redis集合不同的是增加了一个功能即集合是有序的。一个有序集合的每个成员带有分数用于进行排序。</p><p><br></p><p>Redis有序集合添加、删除和测试的时间复杂度均为O(1)(固定时间,无论里面包含的元素集合的数量)。列表的最大长度为2^32- 1元素(4294967295超过40亿每个元素的集合)。</p><p><br></p><p>Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序HashMap里放的是成员到score的映射而跳跃表里存放的是所有的成员排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。</p>',
labelName: ['Redis']
},
{
id: 101,
subjectName: 'Redis的高级数据类型有什么',
subjectDifficult: 2,
subjectType: 4,
subjectScore: 1,
subjectParse: '解析什么',
subjectAnswer:
'<p><br></p><p>bitmapbitmap是一种位数据类型常常用于统计大家比较知名的就是布隆过滤器。也可以统计一些大数据量的东西比如每天有多少优惠券被使用。</p><p><br></p><p>hyperloglog用于基数统计基数是数据集去重后元素个数运用了LogLog的算法。{1,3,5,7,5,7,8} &nbsp; 基数集:{1,3,5,7,8} &nbsp;基数:5</p><p><br></p><p>geo应用于地理位置计算主要是经纬度的计算常见的就是附近的人可以以当前人的坐标获取周围附近的成员可以计算经纬度计算地理位置</p>',
labelName: ['Redis']
},
{
id: 102,
subjectName: 'Redis的优点有什么',
subjectDifficult: 1,
subjectType: 4,
subjectScore: 1,
subjectParse: '解析什么',
subjectAnswer:
'<p><br></p><p>(1) 速度快因为数据存在内存中类似于HashMapHashMap的优势就是查找和操作的时间复杂度都是O(1)</p><p><br></p><p>(2) 支持丰富数据类型支持stringlistsetZsethash等</p><p><br></p><p>(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行</p><p><br></p><p>(4) 丰富的特性可用于缓存消息按key设置过期时间过期后将会自动删除</p>',
labelName: ['Redis']
},
{
id: 103,
subjectName: 'Redis相比Memcached有哪些优势',
subjectDifficult: 1,
subjectType: 4,
subjectScore: 1,
subjectParse: '解析什么',
subjectAnswer:
'<p><br></p><p>(1) Memcached所有的值均是简单的字符串redis作为其替代者支持更为丰富的数据类型</p><p><br></p><p>(2) Redis的速度比Memcached快很多</p><p><br></p><p>(3) Redis可以持久化其数据</p>',
labelName: ['Redis']
},
{
id: 106,
subjectName: 'redis过期策略都有哪些',
subjectDifficult: 1,
subjectType: 4,
subjectScore: 1,
subjectParse: '解析什么',
subjectAnswer:
'<p><br></p><p>noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错。</p><p><br></p><p>allkeys-lru当内存不足以容纳新写入数据时在键空间中移除最近最少使用的 key。</p><p><br></p><p>allkeys-random当内存不足以容纳新写入数据时在键空间中随机移除某个 key这个一般没人用吧为啥要随机肯定是把最近最少使用的 key 给干掉啊。</p><p><br></p><p>volatile-lru当内存不足以容纳新写入数据时在设置了过期时间的键空间中移除最近最少使用的 key。</p><p><br></p><p>volatile-random当内存不足以容纳新写入数据时在设置了过期时间的键空间中随机移除某个 key。</p><p><br></p><p>volatile-ttl当内存不足以容纳新写入数据时在设置了过期时间的键空间中有更早过期时间的 key 优先移除。</p>',
labelName: ['Redis']
}
]
const SearchDetails = () => {
const defaultValue = queryParse(location.search).t
const SearchDetails = () => {
const navigate = useNavigate()
const [isShowSkeleton, setIsShowSkeleton] = useState(true)
const [questionList, setQuestionList] = useState(mockList)
const [questionList, setQuestionList] = useState()
const [total, setTotal] = useState(0)
const [pageIndex, setPageIndex] = useState(0)
const [searchValue, setSearchValue] = useState(defaultValue)
const [searchValue, setSearchValue] = useState()
useEffect(() => {
setSearchValue(defaultValue)
}, [])
const searchSubject = () => {
setIsShowSkeleton(false)
req({
method: 'post',
url: '/getSubjectPageBySearch',
data: {
pageSize: 10,
pageNo: pageIndex,
keyWord: searchValue
}
}).then(res => {
if (res.success && res.data) {
setTotal(res.data.total)
setQuestionList(res.data.result)
}
})
}
const handleJump = id => {
navigate('/brush-question/' + id)
}
const onChangePagination = () => {}
const onChangePagination = curPage => {
setPageIndex(curPage)
}
useEffect(() => {
searchSubject()
}, [searchValue])
}, [searchValue, pageIndex])
return (
<div className='search-details-box'>
@@ -97,9 +61,8 @@ const SearchDetails = () => {
placeholder='请输入感兴趣的内容'
onSearch={value => {
if (value) {
// this.state.searchText = value
// this.pageIndex = 1
// this.searchSubject()
setSearchValue(value)
setPageIndex(1)
} else {
message.info('搜索词不能为空')
}
@@ -117,13 +80,7 @@ const SearchDetails = () => {
>
<div className='search-details-box-content'>
<div className='search-details-box-content-card'>
<Card
style={{ width: '100%' }}
// tabList={this.tabList}
// onTabChange={key => {
// this.onTabChange(key, 'key')
// }}
>
<Card style={{ width: '100%' }}>
<div className='search-details-box-content-main'>
{questionList?.length > 0 ? (
questionList.map((item, index) => {
@@ -133,7 +90,7 @@ const SearchDetails = () => {
<div
className='search-details-box-content-main-item-question'
key={`search-details-question_${index}`}
onClick={() => handleJump(item.id)}
onClick={() => handleJump(item.subjectId)}
dangerouslySetInnerHTML={{
__html: item.subjectName
}}
@@ -141,7 +98,7 @@ const SearchDetails = () => {
<div
className='search-details-box-content-main-item-answer'
key={`search-details-answer_${index}`}
onClick={() => handleJump(item.id)}
onClick={() => handleJump(item.subjectId)}
dangerouslySetInnerHTML={{
__html: item.subjectAnswer + '...'
}}
@@ -181,7 +138,7 @@ const SearchDetails = () => {
</Card>
</div>
<div className='search-details-box-content-paging'>
{total > 20 && (
{total > 10 && (
<Pagination
style={{
padding: '24px 0',
@@ -191,7 +148,7 @@ const SearchDetails = () => {
current={pageIndex}
defaultCurrent={1}
total={total}
defaultPageSize={20}
defaultPageSize={10}
onChange={onChangePagination}
/>
)}