feat: 修改
This commit is contained in:
@@ -38,7 +38,9 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUserInfo()
|
if (location.pathname !== '/login' && loginId) {
|
||||||
|
getUserInfo()
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@@ -23,8 +23,9 @@ const LabelList = props => {
|
|||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.data && res.data.length > 0) {
|
if (res.data && res.data.length > 0) {
|
||||||
const ids = `${res.data[0].id}_${res.data[0].labelDTOList[0].id}`
|
const filterData = [...res.data].filter(item => item?.labelDTOList?.length > 0)
|
||||||
setCategoryAndLabelList(res.data)
|
const ids = `${filterData[0].id}_${filterData[0].labelDTOList[0].id}`
|
||||||
|
setCategoryAndLabelList(filterData)
|
||||||
setCheckedLabelId(ids)
|
setCheckedLabelId(ids)
|
||||||
changeLabel(ids)
|
changeLabel(ids)
|
||||||
} else {
|
} else {
|
||||||
@@ -32,10 +33,8 @@ const LabelList = props => {
|
|||||||
setCheckedLabelId('')
|
setCheckedLabelId('')
|
||||||
changeLabel('')
|
changeLabel('')
|
||||||
}
|
}
|
||||||
// setSpinning(false)
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
// setSpinning(false)
|
|
||||||
console.log(err)
|
console.log(err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -1,177 +1,58 @@
|
|||||||
import { HeartTwoTone, InfoCircleTwoTone, LikeTwoTone } from '@ant-design/icons'
|
import { LikeTwoTone } from '@ant-design/icons'
|
||||||
import req from '@utils/request'
|
import req from '@utils/request'
|
||||||
import { Input, Modal, Radio, message } from 'antd'
|
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
const { TextArea } = Input
|
|
||||||
export default class GoodCollectionError extends Component {
|
export default class GoodCollectionError extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
isGood: false, //是否点赞
|
isGood: false, //是否点赞
|
||||||
isCollection: false, //是否收藏
|
|
||||||
goodAmount: 0, //点赞数量
|
goodAmount: 0, //点赞数量
|
||||||
collectionAmount: 0, //收藏数量
|
|
||||||
// index: 1,
|
|
||||||
question: [], //题目列表
|
question: [], //题目列表
|
||||||
isModal: false, //是否显示纠错弹框
|
|
||||||
value: 1, //纠错类型对应值
|
|
||||||
inputValue: '', //纠错详情内容
|
|
||||||
questionId: '' //题目id
|
questionId: '' //题目id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**纠错类型 */
|
|
||||||
errorType = [
|
|
||||||
{
|
|
||||||
value: 1,
|
|
||||||
content: '答案错误'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 2,
|
|
||||||
content: '题目与答案不符'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
componentDidMount() {
|
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 点击点赞按钮
|
* @returns 点击点赞按钮
|
||||||
*/
|
*/
|
||||||
handleChangeGood = () => {
|
handleChangeGood = () => {
|
||||||
return message.info('敬请期待')
|
const { isGood, goodAmount, questionId } = this.state
|
||||||
const { isGood, goodAmount } = this.state
|
|
||||||
const { questionId } = this.props
|
|
||||||
let params = {
|
let params = {
|
||||||
subjectId: questionId
|
subjectId: questionId,
|
||||||
|
status: isGood ? 0 : 1
|
||||||
}
|
}
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
isGood: isGood === true ? false : true,
|
isGood: !isGood,
|
||||||
goodAmount: isGood === true ? goodAmount - 1 : goodAmount + 1
|
goodAmount: isGood ? goodAmount - 1 : goodAmount + 1
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
req({
|
req(
|
||||||
method: 'post',
|
{
|
||||||
data: params,
|
method: 'post',
|
||||||
url: 'admin/question/thump/addOrCancel'
|
data: params,
|
||||||
}).catch(err => console.log(err))
|
url: '/subjectLiked/add'
|
||||||
}
|
},
|
||||||
)
|
'/subject'
|
||||||
}
|
).catch(err => console.log(err))
|
||||||
/**
|
|
||||||
* 点击收藏按钮
|
|
||||||
*/
|
|
||||||
handleChangeCollection = () => {
|
|
||||||
return message.info('敬请期待')
|
|
||||||
const { isCollection, collectionAmount } = this.state
|
|
||||||
const { questionId } = this.props
|
|
||||||
let params = {
|
|
||||||
subjectId: questionId
|
|
||||||
}
|
|
||||||
this.setState(
|
|
||||||
{
|
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const { isCollection, isGood, isModal, value, collectionAmount, goodAmount } = this.state
|
const { isGood, goodAmount } = this.state
|
||||||
return (
|
return (
|
||||||
<div className='left'>
|
<div className='left'>
|
||||||
<div
|
<div
|
||||||
@@ -181,87 +62,9 @@ export default class GoodCollectionError extends Component {
|
|||||||
this.handleChangeGood()
|
this.handleChangeGood()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<LikeTwoTone
|
<LikeTwoTone twoToneColor={!isGood ? 'grey' : 'blue'} style={{ marginRight: 4 }} />(
|
||||||
twoToneColor={isGood == false ? 'grey' : 'blue'}
|
{goodAmount})
|
||||||
style={{ marginRight: 4 }}
|
|
||||||
/>
|
|
||||||
({goodAmount})
|
|
||||||
</div>
|
</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>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,8 @@ export default function request(config, url) {
|
|||||||
withCredentials: true, // send cookies when cross-domain requests
|
withCredentials: true, // send cookies when cross-domain requests
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
[userInfo.tokenName]: 'jichi ' + userInfo.tokenValue
|
[userInfo.tokenName]: 'jichi ' + userInfo.tokenValue,
|
||||||
|
loginId: userInfo.loginId || ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -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 GoodCollectionError from '@components/good-collection-error'
|
||||||
import './index.less'
|
|
||||||
import req from '@utils/request'
|
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> = {
|
const grade: Record<string, string> = {
|
||||||
1: '初级',
|
1: '初级',
|
||||||
2: '中级',
|
2: '中级',
|
||||||
3: '高级',
|
3: '高级',
|
||||||
4: '资深',
|
4: '资深',
|
||||||
5: '专家',
|
5: '专家'
|
||||||
}
|
}
|
||||||
|
|
||||||
const BrushQuestions = () => {
|
const BrushQuestions = () => {
|
||||||
|
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
const [question, setQuestion] = useState<Record<string, any>>(null)
|
const [question, setQuestion] = useState<Record<string, any>>(null)
|
||||||
const [index, setIndex] = useState(1)
|
const [index, setIndex] = useState(1)
|
||||||
@@ -26,51 +25,49 @@ const BrushQuestions = () => {
|
|||||||
data: {
|
data: {
|
||||||
id
|
id
|
||||||
},
|
},
|
||||||
url: '/querySubjectInfo',
|
url: '/querySubjectInfo'
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then(res => {
|
||||||
if (res.success && res.data) {
|
if (res.success && res.data) {
|
||||||
setQuestion(res.data)
|
setQuestion(res.data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => console.log(err))
|
.catch(err => console.log(err))
|
||||||
}, [id])
|
}, [id])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="brush-questions-box">
|
<div className='brush-questions-box'>
|
||||||
<div className="question-box">
|
<div className='question-box'>
|
||||||
<div className="question">
|
<div className='question'>
|
||||||
<div className="question-type">
|
<div className='question-type'>
|
||||||
<div className="number">{index}</div>
|
<div className='number'>{index}</div>
|
||||||
<div className="type">问答题</div>
|
<div className='type'>问答题</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{question ? (
|
||||||
question ? <Fragment>
|
<Fragment>
|
||||||
<div className="question-content">
|
<div className='question-content'>
|
||||||
<div className="difficulty">
|
<div className='difficulty'>
|
||||||
{grade[question.subjectDifficult]}-{question?.labelName.join('、')}
|
{grade[question.subjectDifficult]}-{question?.labelName.join('、')}
|
||||||
</div>
|
</div>
|
||||||
<div>{question.subjectName}</div>
|
<div>{question.subjectName}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="answer-box">
|
<div className='answer-box'>
|
||||||
<div className="reference-answer">参考答案</div>
|
<div className='reference-answer'>参考答案</div>
|
||||||
<div
|
<div
|
||||||
className="answer-content wang-editor-style"
|
className='answer-content wang-editor-style'
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: question.subjectAnswer,
|
__html: question.subjectAnswer
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<div className="change-question-box">
|
<div className='change-question-box'>
|
||||||
<GoodCollectionError
|
<GoodCollectionError detail={question} />
|
||||||
questionId={question.id}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Fragment> : null
|
</Fragment>
|
||||||
}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -84,16 +81,22 @@ class BrushQuestions1 extends Component {
|
|||||||
isGood: 0,
|
isGood: 0,
|
||||||
isCollection: 0,
|
isCollection: 0,
|
||||||
index: 1,
|
index: 1,
|
||||||
question: [{
|
question: [
|
||||||
id: 1, labelNames: ["原理"], subjectName: 'JDK 和 JRE 有什么区别?', difficulty: 1,
|
{
|
||||||
subjectAnswer: `<p>JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。</p>
|
id: 1,
|
||||||
|
labelNames: ['原理'],
|
||||||
|
subjectName: 'JDK 和 JRE 有什么区别?',
|
||||||
|
difficulty: 1,
|
||||||
|
subjectAnswer: `<p>JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。</p>
|
||||||
<p>JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。</p>
|
<p>JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。</p>
|
||||||
<p>具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很多 Java 程序调试和分析的工具。</p>
|
<p>具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很多 Java 程序调试和分析的工具。</p>
|
||||||
<p>简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。</p>` }],
|
<p>简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。</p>`
|
||||||
|
}
|
||||||
|
],
|
||||||
// answer: '',
|
// answer: '',
|
||||||
isModal: false, //是否显示纠错弹框
|
isModal: false, //是否显示纠错弹框
|
||||||
value: 1, //纠错类型对应值
|
value: 1, //纠错类型对应值
|
||||||
inputValue: '', //纠错详情内容
|
inputValue: '' //纠错详情内容
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pageIndex = 1
|
pageIndex = 1
|
||||||
@@ -106,7 +109,7 @@ class BrushQuestions1 extends Component {
|
|||||||
2: '中级',
|
2: '中级',
|
||||||
3: '高级',
|
3: '高级',
|
||||||
4: '资深',
|
4: '资深',
|
||||||
5: '专家',
|
5: '专家'
|
||||||
}
|
}
|
||||||
goodCollectionError = GoodCollectionError | null
|
goodCollectionError = GoodCollectionError | null
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -127,23 +130,23 @@ class BrushQuestions1 extends Component {
|
|||||||
let params = {
|
let params = {
|
||||||
pageInfo: {
|
pageInfo: {
|
||||||
pageIndex: this.pageIndex,
|
pageIndex: this.pageIndex,
|
||||||
pageSize: 1,
|
pageSize: 1
|
||||||
},
|
},
|
||||||
difficulty: this.difficulty,
|
difficulty: this.difficulty,
|
||||||
primaryCategoryId: this.primaryCategoryId,
|
primaryCategoryId: this.primaryCategoryId,
|
||||||
assembleIds: this.assembleIds,
|
assembleIds: this.assembleIds
|
||||||
}
|
}
|
||||||
return await req({
|
return await req({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: params,
|
data: params,
|
||||||
url: '/querySubjectInfo',
|
url: '/querySubjectInfo'
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then(res => {
|
||||||
if (res.data && res.data?.pageList?.length > 0) {
|
if (res.data && res.data?.pageList?.length > 0) {
|
||||||
this.total = res.data.pageInfo.total
|
this.total = res.data.pageInfo.total
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
question: res.data.pageList,
|
question: res.data.pageList
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.goodCollectionError.getDetail()
|
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.pageIndex = pageIndex
|
||||||
this.setState({ index: pageIndex })
|
this.setState({ index: pageIndex })
|
||||||
// await this.getInterviewSubjectList()
|
// await this.getInterviewSubjectList()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNextQuestion = async (value) => {
|
handleNextQuestion = async value => {
|
||||||
let { index } = this.state
|
let { index } = this.state
|
||||||
this.pageIndex += value
|
this.pageIndex += value
|
||||||
index += value
|
index += value
|
||||||
this.setState({
|
this.setState({
|
||||||
index: index,
|
index: index
|
||||||
})
|
})
|
||||||
// await this.getInterviewSubjectList()
|
// await this.getInterviewSubjectList()
|
||||||
}
|
}
|
||||||
@@ -173,12 +176,12 @@ class BrushQuestions1 extends Component {
|
|||||||
render() {
|
render() {
|
||||||
const { index, question } = this.state
|
const { index, question } = this.state
|
||||||
return (
|
return (
|
||||||
<div className="brush-questions-box">
|
<div className='brush-questions-box'>
|
||||||
<div className="question-box">
|
<div className='question-box'>
|
||||||
<div className="question">
|
<div className='question'>
|
||||||
<div className="question-type">
|
<div className='question-type'>
|
||||||
<div className="number">{index}</div>
|
<div className='number'>{index}</div>
|
||||||
<div className="type">问答题</div>
|
<div className='type'>问答题</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="question-number">
|
{/* <div className="question-number">
|
||||||
<div className="now-number">{index}</div>
|
<div className="now-number">{index}</div>
|
||||||
@@ -190,27 +193,27 @@ class BrushQuestions1 extends Component {
|
|||||||
{question.map((item, index) => {
|
{question.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<div className="question-content">
|
<div className='question-content'>
|
||||||
<div className="difficulty">
|
<div className='difficulty'>
|
||||||
{this.grade[item.difficulty]}-{item.labelNames.join('、')}
|
{this.grade[item.difficulty]}-{item.labelNames.join('、')}
|
||||||
</div>
|
</div>
|
||||||
<div>{item.subjectName}</div>
|
<div>{item.subjectName}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="answer-box">
|
<div className='answer-box'>
|
||||||
<div className="reference-answer">参考答案</div>
|
<div className='reference-answer'>参考答案</div>
|
||||||
<div
|
<div
|
||||||
className="answer-content wang-editor-style"
|
className='answer-content wang-editor-style'
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
// __html: item.subjectAnswer,
|
// __html: item.subjectAnswer,
|
||||||
__html: item.subjectAnswer,
|
__html: item.subjectAnswer
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<div className="change-question-box">
|
<div className='change-question-box'>
|
||||||
<GoodCollectionError
|
<GoodCollectionError
|
||||||
questionId={question[0].id}
|
questionId={question[0].id}
|
||||||
ref={(ref) => {
|
ref={ref => {
|
||||||
this.goodCollectionError = ref
|
this.goodCollectionError = ref
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@@ -241,12 +244,12 @@ class BrushQuestions1 extends Component {
|
|||||||
})}
|
})}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
||||||
<div className="jump-question">
|
<div className='jump-question'>
|
||||||
{this.total > 0 && (
|
{this.total > 0 && (
|
||||||
<Pagination
|
<Pagination
|
||||||
style={{
|
style={{
|
||||||
padding: '24px 0',
|
padding: '24px 0',
|
||||||
textAlign: 'center',
|
textAlign: 'center'
|
||||||
}}
|
}}
|
||||||
showQuickJumper
|
showQuickJumper
|
||||||
current={this.pageIndex}
|
current={this.pageIndex}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import Logo from '@/imgs/logo.jpg'
|
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 TopMenu from '@components/top-menu'
|
||||||
import LoginQrcode from '@imgs/personal_qr_code.jpg'
|
import LoginQrcode from '@imgs/personal_qr_code.jpg'
|
||||||
import req from '@utils/request'
|
import req from '@utils/request'
|
||||||
@@ -18,12 +18,12 @@ const menuItems = [
|
|||||||
icon: <UserOutlined style={{ fontSize: '16px' }} />,
|
icon: <UserOutlined style={{ fontSize: '16px' }} />,
|
||||||
path: '/user-info'
|
path: '/user-info'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: '我的收藏',
|
// label: '我的收藏',
|
||||||
key: 2,
|
// key: 2,
|
||||||
icon: <HeartOutlined style={{ fontSize: '16px' }} />,
|
// icon: <HeartOutlined style={{ fontSize: '16px' }} />,
|
||||||
path: '/personal-center/0'
|
// path: '/personal-center/0'
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
label: '我的点赞',
|
label: '我的点赞',
|
||||||
key: 3,
|
key: 3,
|
||||||
|
@@ -66,7 +66,7 @@ const Login = () => {
|
|||||||
<div className='qrcode-box'>
|
<div className='qrcode-box'>
|
||||||
<div className='qrcode-desc'>
|
<div className='qrcode-desc'>
|
||||||
<p>微信扫码关注公众号</p>
|
<p>微信扫码关注公众号</p>
|
||||||
<p>获取验证码登录</p>
|
<p>公众号发送 “验证码”开启加薪之路</p>
|
||||||
</div>
|
</div>
|
||||||
<div className='qrcode-img'>
|
<div className='qrcode-img'>
|
||||||
<img src={LoginQrcode} alt='' />
|
<img src={LoginQrcode} alt='' />
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import req from '@utils/request'
|
||||||
import { Card, Pagination, Spin } from 'antd'
|
import { Card, Pagination, Spin } from 'antd'
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import { goodTabType } from '../../constant'
|
import { goodTabType } from '../../constant'
|
||||||
@@ -53,23 +54,47 @@ export default class GoodBag extends Component {
|
|||||||
* 获取一级分类数据
|
* 获取一级分类数据
|
||||||
*/
|
*/
|
||||||
getGoodList() {
|
getGoodList() {
|
||||||
this.total = 3
|
req(
|
||||||
this.setState({
|
{
|
||||||
goodList: [
|
method: 'post',
|
||||||
{
|
url: '/subjectLiked/getSubjectLikedPage',
|
||||||
id: 100,
|
data: {
|
||||||
subjectName: 'Redis支持哪几种数据类型?'
|
pageNo: 1,
|
||||||
},
|
pageSize: 10
|
||||||
{
|
|
||||||
id: 101,
|
|
||||||
subjectName: 'Redis的高级数据类型有什么?'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 102,
|
|
||||||
subjectName: 'Redis的优点有什么?'
|
|
||||||
}
|
}
|
||||||
]
|
},
|
||||||
|
'/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的优点有什么?'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,12 +24,12 @@ const CollectionQuestion = props => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='collection-bag-component-tab1-body-item'
|
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'>
|
<div className='collection-bag-component-tab1-body-item-question'>
|
||||||
<span
|
<span
|
||||||
className='collection-bag-component-tab1-body-item-question-content'
|
className='collection-bag-component-tab1-body-item-question-content'
|
||||||
onClick={() => handleJump(item.id)}
|
onClick={() => handleJump(item.subjectId)}
|
||||||
>
|
>
|
||||||
{item.subjectName}
|
{item.subjectName}
|
||||||
</span>
|
</span>
|
||||||
|
@@ -1,9 +1,4 @@
|
|||||||
import { LikeTwoTone, StarTwoTone } from '@ant-design/icons'
|
import React from 'react'
|
||||||
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 GoodBag from './components/good-bag'
|
import GoodBag from './components/good-bag'
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
@@ -12,86 +7,89 @@ const personList = {
|
|||||||
1: '点赞'
|
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 PersonalCenter = props => {
|
||||||
const [currentKeyMap, setCurrentKeyMap] = useState(0)
|
return <GoodBag />
|
||||||
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>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PersonalCenter
|
export default PersonalCenter
|
||||||
|
@@ -1,84 +1,83 @@
|
|||||||
import React, { Fragment, Component } from 'react';
|
import req from '@utils/request'
|
||||||
import req from '@utils/request';
|
import React, { Component, Fragment } from 'react'
|
||||||
import RankingBox from '../ranking-box';
|
import { RankingType, apiName } from '../../constant'
|
||||||
import { apiName, RankingType } from '../../constant';
|
import { mockRankingModuleList } from '../../mock'
|
||||||
import { mockRankingModuleList } from '../../mock';
|
import RankingBox from '../ranking-box'
|
||||||
|
|
||||||
class PracticeList extends Component {
|
class PracticeList extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props)
|
||||||
this.state = {
|
this.state = {
|
||||||
contributionList: mockRankingModuleList[0].rankingList,
|
contributionList: mockRankingModuleList[0].rankingList,
|
||||||
contributeType: 0,
|
contributeType: 0,
|
||||||
isLoading: false,
|
isLoading: false
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// this.getPracticeRankList();
|
this.getPracticeRankList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得练习榜
|
* 获得练习榜
|
||||||
*/
|
*/
|
||||||
getPracticeRankList() {
|
getPracticeRankList() {
|
||||||
req({
|
req({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: {},
|
url: apiName.getPracticeRankList
|
||||||
url: apiName.getPracticeRankList,
|
})
|
||||||
})
|
.then(res => {
|
||||||
.then((res) => {
|
if (res.data && res.data.length > 0) {
|
||||||
if (res.data && res.data.length > 0) {
|
this.setState({
|
||||||
this.setState({
|
contributionList: res.data,
|
||||||
contributionList: res.data,
|
isLoading: false
|
||||||
isLoading: false,
|
})
|
||||||
});
|
} else {
|
||||||
} else {
|
this.setState({
|
||||||
this.setState({
|
contributionList: [],
|
||||||
contributionList: [],
|
isLoading: false
|
||||||
isLoading: false,
|
})
|
||||||
});
|
}
|
||||||
}
|
})
|
||||||
})
|
.catch(err => console.log(err))
|
||||||
.catch((err) => console.log(err));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换排行榜
|
* 切换排行榜
|
||||||
* @param {*} index
|
* @param {*} index
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
onChangeRanking = (index) => {
|
onChangeRanking = index => {
|
||||||
console.log(index, 'practice index')
|
console.log(index, 'practice index')
|
||||||
this.setState({
|
this.setState({
|
||||||
contributeType: index,
|
contributeType: index
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 去练题
|
* 去练题
|
||||||
*/
|
*/
|
||||||
onChangeJump = () => {
|
onChangeJump = () => {
|
||||||
this.props.history.push('/practice-questions');
|
this.props.history.push('/practice-questions')
|
||||||
};
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { contributionList, isLoading, contributeType } = this.state;
|
const { contributionList, isLoading, contributeType } = this.state
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{contributionList?.length > 0 && (
|
{contributionList?.length > 0 && (
|
||||||
<RankingBox
|
<RankingBox
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
contributionList={contributionList}
|
contributionList={contributionList}
|
||||||
currentActive={contributeType}
|
currentActive={contributeType}
|
||||||
rankingType={RankingType.practice}
|
rankingType={RankingType.practice}
|
||||||
onHandleRanking={this.onChangeRanking}
|
onHandleRanking={this.onChangeRanking}
|
||||||
onHandleJump={this.onChangeJump}
|
onHandleJump={this.onChangeJump}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PracticeList;
|
export default PracticeList
|
||||||
|
@@ -29,16 +29,24 @@ export default function RankingBox(props) {
|
|||||||
}
|
}
|
||||||
// props.onHandleJump && props.onHandleJump()
|
// props.onHandleJump && props.onHandleJump()
|
||||||
})
|
})
|
||||||
const tabList = [
|
const tabList =
|
||||||
{
|
rankingType === 1
|
||||||
tab: '本月排行',
|
? [
|
||||||
key: 'month'
|
{
|
||||||
},
|
tab: '本月排行',
|
||||||
{
|
key: 'month'
|
||||||
tab: '总榜',
|
},
|
||||||
key: 'total'
|
{
|
||||||
}
|
tab: '总榜',
|
||||||
]
|
key: 'total'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
tab: '总榜',
|
||||||
|
key: 'total'
|
||||||
|
}
|
||||||
|
]
|
||||||
// 获得当前下标的数据
|
// 获得当前下标的数据
|
||||||
let rankingList = contributionList || []
|
let rankingList = contributionList || []
|
||||||
|
|
||||||
@@ -79,24 +87,24 @@ export default function RankingBox(props) {
|
|||||||
{index > 2 && index + 1}
|
{index > 2 && index + 1}
|
||||||
</div>
|
</div>
|
||||||
<div className='ranking-head-img'>
|
<div className='ranking-head-img'>
|
||||||
<img src={item.headImg} className='ranking-head-icon' />
|
<img src={item.createUserAvatar} className='ranking-head-icon' />
|
||||||
</div>
|
</div>
|
||||||
<Popover
|
<Popover
|
||||||
title={<div>{item.name}</div>}
|
title={<div>{item.createUser}</div>}
|
||||||
content={
|
content={
|
||||||
<div className='tooltip-info'>
|
<div className='tooltip-info'>
|
||||||
<div>{item.name}</div>
|
<div>{item.createUser}</div>
|
||||||
{/* <div>{item.organizationFullName}</div> */}
|
{/* <div>{item.organizationFullName}</div> */}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className='ranking-info'>
|
<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 className="ranking-department">{item.organizationName}</div> */}
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<div className='ranking-right'>🔥 {item.count}</div>
|
<div className='ranking-right'>🔥 {item.subjectCount}</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
@@ -1,46 +1,49 @@
|
|||||||
|
|
||||||
export const apiName = {
|
export const apiName = {
|
||||||
/**
|
/**
|
||||||
* 查询分类
|
* 查询分类
|
||||||
*/
|
*/
|
||||||
queryPrimaryCategory: '/category/queryPrimaryCategory',
|
queryPrimaryCategory: '/category/queryPrimaryCategory',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询大类下分类
|
* 查询大类下分类
|
||||||
*/
|
*/
|
||||||
queryCategoryByPrimary: '/category/queryCategoryByPrimary',
|
queryCategoryByPrimary: '/category/queryCategoryByPrimary',
|
||||||
|
|
||||||
// 获取题目列表
|
// 获取题目列表
|
||||||
getSubjectPage: '/getSubjectPage'
|
getSubjectPage: '/getSubjectPage',
|
||||||
|
|
||||||
};
|
/**
|
||||||
|
* 练题排行榜
|
||||||
|
*/
|
||||||
|
getPracticeRankList: '/getContributeList'
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模块类型
|
* 模块类型
|
||||||
*/
|
*/
|
||||||
export const RankingType = {
|
export const RankingType = {
|
||||||
/**
|
/**
|
||||||
* 贡献榜
|
* 贡献榜
|
||||||
*/
|
*/
|
||||||
contribution: 1,
|
contribution: 1,
|
||||||
/**
|
/**
|
||||||
* 排行榜
|
* 排行榜
|
||||||
*/
|
*/
|
||||||
practice: 2,
|
practice: 2
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模块名称
|
* 模块名称
|
||||||
*/
|
*/
|
||||||
export const RankingTypeText = {
|
export const RankingTypeText = {
|
||||||
[RankingType.contribution]: '贡献榜',
|
[RankingType.contribution]: '出题贡献榜',
|
||||||
[RankingType.practice]: '综合练习榜',
|
[RankingType.practice]: '综合练习榜'
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对应按钮名字
|
* 对应按钮名字
|
||||||
*/
|
*/
|
||||||
export const RankingTypeBtnText = {
|
export const RankingTypeBtnText = {
|
||||||
[RankingType.contribution]: '去出题',
|
[RankingType.contribution]: '去出题',
|
||||||
[RankingType.practice]: '去练习',
|
[RankingType.practice]: '去练习'
|
||||||
};
|
}
|
||||||
|
@@ -132,8 +132,8 @@ const QuestionBank = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='ranking-box'>
|
<div className='ranking-box'>
|
||||||
<RankingList />
|
|
||||||
<ContributionList />
|
<ContributionList />
|
||||||
|
<RankingList />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,93 +1,57 @@
|
|||||||
import { ExclamationCircleOutlined } from '@ant-design/icons'
|
import { ExclamationCircleOutlined } from '@ant-design/icons'
|
||||||
import { queryParse } from '@utils'
|
import { queryParse } from '@utils'
|
||||||
|
import req from '@utils/request'
|
||||||
import { Card, Input, Pagination, Skeleton, message } from 'antd'
|
import { Card, Input, Pagination, Skeleton, message } from 'antd'
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
import './index.less'
|
import './index.less'
|
||||||
|
|
||||||
const { Search } = Input
|
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>bitmap:bitmap是一种位数据类型,常常用于统计,大家比较知名的就是布隆过滤器。也可以统计一些大数据量的东西,比如每天有多少优惠券被使用。</p><p><br></p><p>hyperloglog:用于基数统计,基数是数据集去重后元素个数,运用了LogLog的算法。{1,3,5,7,5,7,8} 基数集:{1,3,5,7,8} 基数: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) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)</p><p><br></p><p>(2) 支持丰富数据类型,支持string,list,set,Zset,hash等</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 defaultValue = queryParse(location.search).t
|
|
||||||
|
|
||||||
const SearchDetails = () => {
|
const SearchDetails = () => {
|
||||||
|
const defaultValue = queryParse(location.search).t
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [isShowSkeleton, setIsShowSkeleton] = useState(true)
|
const [isShowSkeleton, setIsShowSkeleton] = useState(true)
|
||||||
const [questionList, setQuestionList] = useState(mockList)
|
const [questionList, setQuestionList] = useState()
|
||||||
const [total, setTotal] = useState(0)
|
const [total, setTotal] = useState(0)
|
||||||
const [pageIndex, setPageIndex] = useState(0)
|
const [pageIndex, setPageIndex] = useState(0)
|
||||||
const [searchValue, setSearchValue] = useState(defaultValue)
|
const [searchValue, setSearchValue] = useState()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSearchValue(defaultValue)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const searchSubject = () => {
|
const searchSubject = () => {
|
||||||
setIsShowSkeleton(false)
|
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 => {
|
const handleJump = id => {
|
||||||
navigate('/brush-question/' + id)
|
navigate('/brush-question/' + id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onChangePagination = () => {}
|
const onChangePagination = curPage => {
|
||||||
|
setPageIndex(curPage)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
searchSubject()
|
searchSubject()
|
||||||
}, [searchValue])
|
}, [searchValue, pageIndex])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='search-details-box'>
|
<div className='search-details-box'>
|
||||||
@@ -97,9 +61,8 @@ const SearchDetails = () => {
|
|||||||
placeholder='请输入感兴趣的内容'
|
placeholder='请输入感兴趣的内容'
|
||||||
onSearch={value => {
|
onSearch={value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
// this.state.searchText = value
|
setSearchValue(value)
|
||||||
// this.pageIndex = 1
|
setPageIndex(1)
|
||||||
// this.searchSubject()
|
|
||||||
} else {
|
} else {
|
||||||
message.info('搜索词不能为空')
|
message.info('搜索词不能为空')
|
||||||
}
|
}
|
||||||
@@ -117,13 +80,7 @@ const SearchDetails = () => {
|
|||||||
>
|
>
|
||||||
<div className='search-details-box-content'>
|
<div className='search-details-box-content'>
|
||||||
<div className='search-details-box-content-card'>
|
<div className='search-details-box-content-card'>
|
||||||
<Card
|
<Card style={{ width: '100%' }}>
|
||||||
style={{ width: '100%' }}
|
|
||||||
// tabList={this.tabList}
|
|
||||||
// onTabChange={key => {
|
|
||||||
// this.onTabChange(key, 'key')
|
|
||||||
// }}
|
|
||||||
>
|
|
||||||
<div className='search-details-box-content-main'>
|
<div className='search-details-box-content-main'>
|
||||||
{questionList?.length > 0 ? (
|
{questionList?.length > 0 ? (
|
||||||
questionList.map((item, index) => {
|
questionList.map((item, index) => {
|
||||||
@@ -133,7 +90,7 @@ const SearchDetails = () => {
|
|||||||
<div
|
<div
|
||||||
className='search-details-box-content-main-item-question'
|
className='search-details-box-content-main-item-question'
|
||||||
key={`search-details-question_${index}`}
|
key={`search-details-question_${index}`}
|
||||||
onClick={() => handleJump(item.id)}
|
onClick={() => handleJump(item.subjectId)}
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: item.subjectName
|
__html: item.subjectName
|
||||||
}}
|
}}
|
||||||
@@ -141,7 +98,7 @@ const SearchDetails = () => {
|
|||||||
<div
|
<div
|
||||||
className='search-details-box-content-main-item-answer'
|
className='search-details-box-content-main-item-answer'
|
||||||
key={`search-details-answer_${index}`}
|
key={`search-details-answer_${index}`}
|
||||||
onClick={() => handleJump(item.id)}
|
onClick={() => handleJump(item.subjectId)}
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: item.subjectAnswer + '...'
|
__html: item.subjectAnswer + '...'
|
||||||
}}
|
}}
|
||||||
@@ -181,7 +138,7 @@ const SearchDetails = () => {
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
<div className='search-details-box-content-paging'>
|
<div className='search-details-box-content-paging'>
|
||||||
{total > 20 && (
|
{total > 10 && (
|
||||||
<Pagination
|
<Pagination
|
||||||
style={{
|
style={{
|
||||||
padding: '24px 0',
|
padding: '24px 0',
|
||||||
@@ -191,7 +148,7 @@ const SearchDetails = () => {
|
|||||||
current={pageIndex}
|
current={pageIndex}
|
||||||
defaultCurrent={1}
|
defaultCurrent={1}
|
||||||
total={total}
|
total={total}
|
||||||
defaultPageSize={20}
|
defaultPageSize={10}
|
||||||
onChange={onChangePagination}
|
onChange={onChangePagination}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
Reference in New Issue
Block a user