feat: 圈子
This commit is contained in:
@@ -1,22 +1,36 @@
|
||||
import headImg from '@/imgs/head.jpg'
|
||||
import javaImg from '@/imgs/java.jpeg'
|
||||
import jobImg from '@/imgs/job.jpg'
|
||||
import {
|
||||
FileImageOutlined,
|
||||
MessageOutlined,
|
||||
PlusOutlined,
|
||||
ShareAltOutlined,
|
||||
SmileOutlined
|
||||
SmileOutlined,
|
||||
MessageTwoTone
|
||||
} from '@ant-design/icons'
|
||||
import { Avatar, Button, Card, Input, Popover, Tabs } from 'antd'
|
||||
import { useState } from 'react'
|
||||
import { Avatar, Button, Card, Input, Popover, Tabs, message, Upload, Image } from 'antd'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { fetchCircleList, saveMoment, getMoments } from './service'
|
||||
import CommentList from './comps/comment-list'
|
||||
import './index.less'
|
||||
|
||||
const { Meta } = Card
|
||||
|
||||
const { TextArea } = Input
|
||||
const Circle = () => {
|
||||
const userInfoStorage = localStorage.getItem('userInfo')
|
||||
const { tokenValue = '' } = userInfoStorage ? JSON.parse(userInfoStorage) : {}
|
||||
|
||||
const [hasFocus, setHasFocus] = useState(false)
|
||||
const [comment, setComment] = useState('')
|
||||
const [circleList, setCircleList] = useState([])
|
||||
const [currentSelectCircle, setCurrentSelectCircle] = useState(null)
|
||||
const [openFlag, setOpenFlag] = useState(false)
|
||||
const [imgList, setImgList] = useState([])
|
||||
const [momentList, setMomentList] = useState([])
|
||||
const [currentReplyCommentId, setCurrentReplyCommentId] = useState(undefined)
|
||||
const [previewList, setPreviewList] = useState({
|
||||
list: [],
|
||||
index: 0
|
||||
})
|
||||
|
||||
const toggleFocus = (flag: boolean) => {
|
||||
setHasFocus(!flag)
|
||||
@@ -26,31 +40,99 @@ const Circle = () => {
|
||||
setComment(e.target.value)
|
||||
}
|
||||
|
||||
const getCircleList = async () => {
|
||||
const res = await fetchCircleList()
|
||||
if (res.success && res.data?.length > 0) {
|
||||
setCircleList(res.data)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getCircleList()
|
||||
getMomentList()
|
||||
}, [])
|
||||
|
||||
const changeCircle = selectItem => {
|
||||
setCurrentSelectCircle(selectItem)
|
||||
setOpenFlag(false)
|
||||
}
|
||||
|
||||
const renderTab = () => {
|
||||
return circleList.map(item => {
|
||||
return {
|
||||
label: item.circleName,
|
||||
key: item.id,
|
||||
children: (
|
||||
<div className='pop-content'>
|
||||
{item.children.map(child => {
|
||||
return (
|
||||
<div
|
||||
className='pop-content-item'
|
||||
key={child.id}
|
||||
onClick={() => changeCircle(child)}
|
||||
>
|
||||
<img src={child.icon} className='item-img' />
|
||||
<span className='item-name'>{child.circleName}</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const renderPopContent = () => {
|
||||
return (
|
||||
<Tabs
|
||||
tabPosition='left'
|
||||
size='small'
|
||||
items={[
|
||||
{
|
||||
label: '推荐圈子',
|
||||
key: '1',
|
||||
children: (
|
||||
<div className='pop-content'>
|
||||
<div className='pop-content-item'>
|
||||
<img src={javaImg} className='item-img' />
|
||||
<span className='item-name'>JAVA圈子</span>
|
||||
</div>
|
||||
<div className='pop-content-item'>
|
||||
<img src={jobImg} className='item-img' />
|
||||
<span className='item-name'>求职圈子</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
)
|
||||
return <Tabs tabPosition='left' size='small' items={renderTab()} />
|
||||
}
|
||||
|
||||
const getMomentList = async () => {
|
||||
const res = await getMoments({
|
||||
pageInfo: {
|
||||
pageNo: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
})
|
||||
setMomentList(res.data.result)
|
||||
}
|
||||
|
||||
const publishMoment = async () => {
|
||||
const params: any = {
|
||||
circleId: currentSelectCircle?.id,
|
||||
content: comment
|
||||
}
|
||||
if (imgList.length) {
|
||||
params.picUrlList = imgList.map(item => item.response.data)
|
||||
}
|
||||
const res = await saveMoment(params)
|
||||
if (res.success) {
|
||||
getMomentList()
|
||||
return message.success('发布成功')
|
||||
}
|
||||
return message.error('有点繁忙呢,要不再试试~~~')
|
||||
}
|
||||
const uploadButton = (
|
||||
<button style={{ border: 0, background: 'none' }} type='button'>
|
||||
<PlusOutlined />
|
||||
</button>
|
||||
)
|
||||
const handleChange = ({ fileList }) => {
|
||||
setImgList(fileList)
|
||||
}
|
||||
|
||||
const showReply = (item: any) => {
|
||||
if (item.id !== currentReplyCommentId) {
|
||||
setCurrentReplyCommentId(item.id)
|
||||
} else {
|
||||
setCurrentReplyCommentId(undefined)
|
||||
}
|
||||
}
|
||||
|
||||
const handlePreview = (picList, index) => {
|
||||
setPreviewList({
|
||||
list: picList,
|
||||
index
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -73,8 +155,33 @@ const Circle = () => {
|
||||
onFocus={() => toggleFocus(false)}
|
||||
onBlur={() => toggleFocus(true)}
|
||||
/>
|
||||
<Popover placement='bottomLeft' trigger='click' content={renderPopContent}>
|
||||
<div className='choose-circle'>选择圈子 {'>'}</div>
|
||||
<Upload
|
||||
name='uploadFile'
|
||||
action='/oss/upload'
|
||||
listType='picture-card'
|
||||
fileList={imgList}
|
||||
withCredentials
|
||||
headers={{
|
||||
satoken: 'jichi ' + tokenValue
|
||||
}}
|
||||
data={{
|
||||
bucket: 'user',
|
||||
objectName: 'icon'
|
||||
}}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{imgList.length >= 8 || imgList.length === 0 ? null : uploadButton}
|
||||
</Upload>
|
||||
<Popover
|
||||
placement='bottomLeft'
|
||||
trigger='click'
|
||||
open={openFlag}
|
||||
onOpenChange={open => setOpenFlag(open)}
|
||||
content={renderPopContent}
|
||||
>
|
||||
<div className='choose-circle'>
|
||||
{currentSelectCircle?.circleName || '选择圈子'} {'>'}
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
<div className='publish-options'>
|
||||
@@ -83,37 +190,73 @@ const Circle = () => {
|
||||
<SmileOutlined />
|
||||
<span style={{ marginLeft: '8px' }}>表情</span>
|
||||
</div>
|
||||
<div>
|
||||
<FileImageOutlined />
|
||||
<span style={{ marginLeft: '8px' }}>图片</span>
|
||||
</div>
|
||||
<Upload
|
||||
name='uploadFile'
|
||||
className='avatar-uploader'
|
||||
accept='image/*'
|
||||
showUploadList={false}
|
||||
withCredentials
|
||||
action='/oss/upload'
|
||||
headers={{
|
||||
satoken: 'jichi ' + tokenValue
|
||||
}}
|
||||
data={{
|
||||
bucket: 'user',
|
||||
objectName: 'icon'
|
||||
}}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<div>
|
||||
<FileImageOutlined />
|
||||
<span style={{ marginLeft: '8px' }}>图片</span>
|
||||
</div>
|
||||
</Upload>
|
||||
</div>
|
||||
<div className='right-box'>
|
||||
<Button type='primary' disabled={!comment.length}>
|
||||
<Button type='primary' disabled={!comment.length} onClick={publishMoment}>
|
||||
发布
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
<Card
|
||||
style={{ marginTop: '10px' }}
|
||||
actions={[
|
||||
<div>
|
||||
<ShareAltOutlined />
|
||||
<span style={{ marginLeft: 8 }}>分享</span>
|
||||
</div>,
|
||||
<div>
|
||||
<MessageOutlined />
|
||||
<span style={{ marginLeft: 8 }}>2</span>
|
||||
</div>
|
||||
]}
|
||||
>
|
||||
<Meta
|
||||
avatar={<Avatar src={headImg} />}
|
||||
title='鸡翅小弟'
|
||||
description='每天练习,两年半定有所成。'
|
||||
/>
|
||||
</Card>
|
||||
{momentList.map((item: any) => {
|
||||
return (
|
||||
<Card style={{ marginTop: '10px' }} bodyStyle={{ paddingBottom: 0 }} key={item.id}>
|
||||
<Meta
|
||||
avatar={<Avatar src={item.userAvatar} />}
|
||||
title={item.userName}
|
||||
description={item.content}
|
||||
/>
|
||||
{item.picUrlList?.length && (
|
||||
<Image.PreviewGroup items={previewList.list}>
|
||||
<div className='img-list'>
|
||||
{item.picUrlList.map((t: string) => (
|
||||
<Image key={t} width={110} src={t} />
|
||||
))}
|
||||
</div>
|
||||
</Image.PreviewGroup>
|
||||
)}
|
||||
<div className='card-footer'>
|
||||
<a key='share' className='footer-item'>
|
||||
<ShareAltOutlined />
|
||||
<span style={{ marginLeft: 8 }}>分享</span>
|
||||
</a>
|
||||
<a key='comment' className='footer-item' onClick={() => showReply(item)}>
|
||||
{currentReplyCommentId === item.id ? <MessageTwoTone /> : <MessageOutlined />}
|
||||
<span
|
||||
style={{
|
||||
marginLeft: 8,
|
||||
color: item.id === currentReplyCommentId ? '#1e80ff' : ''
|
||||
}}
|
||||
>
|
||||
{item.replyCount}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
{currentReplyCommentId === item.id && <CommentList momentId={item.id} />}
|
||||
</Card>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user