react+egg+mysql 写一个评论组件(一)

  • Post author:
  • Post category:mysql

前言

最近想用react 写一款自己的博客 此篇文章主要为设计一个评论框组件~

最终的功能实现效果图

留言本.gif

需求

1、用户对某一文章评论 系统可以获取用户的信息 并展示出来
2、其余用户可以评论别人的回复信息
3、输入QQ 可以后台查询对应的用户头像保存下来

数据库设计

用户表

id 用户名 联系方式 头像地址

评论表

评论id 文章id 评论内容 用户id 状态 点赞数 回复信息

状态分为 是否审核通过 防止恶意评论
回复表

评论id 文章id 回复的内容 用户id 被回复人id 状态 点赞数 回复信息

前端评论框组件设计

前端主要使用antd 里面的form 表单 以及留言板 模块

主要的逻辑

  • 用户在输入qq号那一栏 会利用正则判断是否为qq号 如果为qq号 则动态设置用户联系方式那一栏为qq邮箱地址,并且保存用户的qq号 利用后端去查询用户的头像。
  • 首次进入 会判断 localstorage里面有没有用户信息 如果没有则让用户填写用户信息
  • 前端利用nanoid生成随机数 确保用户id的唯一性
  • 当用户在输入留言以后 会将用户的信息 用localstorage 保存到本地 这样 用户下次登录 或者再次评论别人的信息 就不用再次填写信息,(打算以后改为用户利用qq登录功能)
  • 若为文章评论 还要隐去评论表的取消按钮 若为评论他人信息 要保留评论的取消按钮
  • 还要判断出该条回复信息 是否为评论他人的信息
import React,{useState,useEffect} from 'react'
import { Form, Input, Button,message} from 'antd';
import moment from 'moment';
import {nanoid} from 'nanoid'; //生成随机数 用确保用户的id唯一
import axios from 'axios'
import  servicePath  from '../config/apiUrl'
const { TextArea } = Input;
    
function MessageModal(props){
    const [form] = Form.useForm();
    const [flag,setFlag] = useState(false)
    const [cancelFlag,setCancelFlag] = useState(false)
    const [replyId,setReplyId] = useState(props.replyId)
    const [loadings,setLoadings] = useState(false)
    const [imgUrl,setImgUrl] =useState("")
    useEffect(()=>{
        // 如果有用户id 就设置用户名跟联系方式 且 不能修改
        if(localStorage.getItem("user_id")){
            setFlag(true)
            form.setFieldsValue({
                name:localStorage.getItem("userName")?localStorage.getItem("userName"):"",
                contact:localStorage.getItem("contact")?localStorage.getItem("contact"):""
            })
            if(localStorage.getItem("img_url")){
                setImgUrl(localStorage.getItem("img_url"))
            }
        }
        if(!props.closeComment){
            // 如果不是点击回复进来的 是没有 closeComment函数 即 点击取消的 事件
            setCancelFlag(true)
        } 
    },[])
      const onFinish = (values: any) => {
        setLoadings(true)
        // 用户提交评论信息以后把用户名 用户联系方式 用户的id 保存到本地上
        let commentData={
            user_id:localStorage.getItem("user_id") ? localStorage.getItem("user_id") : nanoid(),
            createtime:moment().format('X'),
            state:0,
            likes:0,
            replys:null,
            article_id:props.id,
            content:values.content,
            contact:values.contact,
            name:values.name,
            img_url:imgUrl,
            // 以下为回复评论的数据
            comment_id:replyId && replyId.comment_id,
            reply_id:replyId && replyId.user_id,
        }
        axios({
            method:'post',
            url:servicePath.addComment,
            data:commentData,
            withCredentials: true
        }).then(
            res=>{
                setLoadings(false)
                if(res.data.isScuccess){
                    form.setFieldsValue({
                        content:""
                    })
                    localStorage.setItem("userName",commentData.name)
                    localStorage.setItem("contact",commentData.contact)
                    localStorage.setItem("user_id",commentData.user_id)
                    localStorage.setItem("img_url",imgUrl)
                    setFlag(true)
                    message.success('评论成功,请等待审核~')
                    !cancelFlag && props.closeComment()
                }else{
                    message.error('评论失败,请刷新重试~');
                }
            }
        )
    };
    const onFinishFailed = (errorInfo: any) => {
        console.log('Failed:', errorInfo);
    };
     // 根据输入的qq号或昵称设置 邮箱 12位邮箱
    const changeContact =()=>{
        let reg = /^[1-9][0-9]{4,9}$/gim
        if(reg.test(form.getFieldValue("name"))){
            form.setFieldsValue({
                contact:form.getFieldValue("name")+'@qq.com'
            })
            //获取QQ头像 没有找到合适的接口获取QQ昵称
            setImgUrl('https://q2.qlogo.cn/headimg_dl?dst_uin='+form.getFieldValue("name")+'&spec=100')
        }else{
   setImgUrl("https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png")
            form.setFieldsValue({
                contact:""
            })
        }	
    }            
     return(   
           <Form
            name="basic"
            labelCol={{ span: 0 }}
            wrapperCol={{ span: 24 }}
            initialValues={{ remember: true }}
            onFinish={onFinish}
            onFinishFailed={onFinishFailed}
            className = "message-modal"
            form={form}
            >
            <Form.Item
                label=""
                name="name"
                rules={[{ required: true, message: '请确认昵称/QQ号' }]}
                className ={flag ? "display-none" : "">
                <Input  placeholder="昵称/QQ号" onChange={changeContact}/>
            </Form.Item>
            <Form.Item
                label=""
                name="contact"
                rules={[
                    { required: true, message: '请确认您的邮箱' },
                    {
                        pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/,
                        message: '邮箱格式不正确',
                        },
                ]}
                className ={flag ? "display-none" : ""}
            >
                <Input placeholder="请输入邮箱"  />
            </Form.Item>
            <Form.Item
                label=""
                name="content"
                rules={[{ required: true, message: '输入您的留言 ' }]}
            >
                <TextArea showCount maxLength={100}  placeholder="1.输入您的留言        2.在昵称框输入QQ号可自动识别头像哦" />
            </Form.Item>
            <Form.Item wrapperCol={{ offset: 0, span: 24 }}>
                <Button  htmlType="button" className ={cancelFlag ? "display-none" : "margin-r10"} onClick={props.closeComment}>
                    取消
                </Button>
                <Button type="primary" htmlType="submit" loading={loadings}>
                提交评论 ✪ω✪
                </Button>
            </Form.Item>
            </Form>)
  }

版权声明:本文为weixin_42609477原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。