Spring boot +React集成ChatGPT 智能AI

news2024/11/24 13:34:04
在这里插入代码片import {Button, Input, Radio,Alert,Modal  } from 'antd';
import Marquee from 'react-fast-marquee';
import {ChromeOutlined,WifiOutlined,AimOutlined } from '@ant-design/icons';
import React, {useEffect, useState, useRef} from 'react';
import chatgptPng from '../../static/icon/chatgpt.png'
import meJpg from '../../static/icon/me.jpg'
import './openai.css'
import {sendMsgApi} from "../../services/openai/openaiService";

export default function OpenAi() {

    const [isButtonDisabled, setIsButtonDisabled] = useState(false);
    const [countdown, setCountdown] = useState(20);
    const containerRef = useRef(null);
    const [inputValue, setInputValue] = useState('');
    const [value, setValue] = useState(1);
    const [imgUrl, setImgUrl] = useState("");
    // 聊天数据
    const [chatList, setChatList] = useState([
        {
            headImg: require('../../static/icon/chatgpt.png'),
            name: 'ChatGPT',
            time: new Date().toLocaleTimeString(),
            msg: ' 您好,诗绣智能AI助手为您服务。',
            chatType: 0,
            uid: '1002',
            type: 1
        }
    ])

    const [isModalOpen, setIsModalOpen] = useState(false);
    const showModal = (url) => {
        setImgUrl("")
        setImgUrl(url)
        setIsModalOpen(true);
    };
    const handleOk = () => {
        setIsModalOpen(false);
    };
    const handleCancel = () => {
        setIsModalOpen(false);
    };

    const onChange = (e) => {
        setValue(e.target.value);
    };
    useEffect(() => {
        if (isButtonDisabled) {
            const timer = setInterval(() => {
                setCountdown(prevCountdown => prevCountdown - 1);
            }, 1000);

            setTimeout(() => {
                setIsButtonDisabled(false);
                setCountdown(20);
                clearInterval(timer);
            }, 20000);

            return () => {
                clearInterval(timer);
            };
        }
    }, [isButtonDisabled]);

    const handleInputChange = (event) => {
        setInputValue(event.target.value);
    };

    const send = () => {
        if (inputValue.trim() === '') {
            alert('输入框不能为空');
            return;
        }
        setIsButtonDisabled(true);
        const obj = {
            headImg: require('../../static/icon/chatgpt.png'),
            name: '初出茅庐',
            time: new Date().toLocaleTimeString(),
            msg: inputValue,
            chatType: 0,
            uid: '1001'
        }
        let news = chatList.concat(obj)
        setChatList(news)
        setInputValue('')
        sendMsgApi({type: value, question: inputValue}).then((res) => {
            if (res.status_code === 200) {
                const item = {
                    headImg: require('../../static/icon/chatgpt.png'),
                    name: 'ChatGPT',
                    time: new Date().toLocaleTimeString(),
                    msg: res.data,
                    chatType: 0,
                    uid: '1002',
                    type: value === 1 ? 1 : 2
                }
                let concat = news.concat(item);
                setChatList(concat)
                setTimeout(() => {
                    containerRef.current.scrollTop = containerRef.current.scrollHeight;
                }, 0);
            }
        })
        setTimeout(() => {
            containerRef.current.scrollTop = containerRef.current.scrollHeight;
        }, 0);
    }
    return (
        <div className="chatHome">
            <div className="chatLeft">
                <p className="chat-title"><ChromeOutlined   spin /> 诗绣智能AI助手</p>
                <div className="openai-type-class">
                    <p className="tool-a-title"><AimOutlined spin /> AI助手模式切换</p>
                    <Radio.Group onChange={onChange} value={value} style={{ display: 'grid', gridTemplateColumns: 'auto auto' }}>
                        <Radio value={1} style={{ color: 'cornflowerblue' }}>聊天模式</Radio>
                        <Radio value={2} style={{ color: 'cornflowerblue' }}>图片模式</Radio>
                    </Radio.Group>
                </div>
                <p className="tool-a-title"><AimOutlined spin /> 诗绣工具推荐</p>
                <div className="div-tools">
                    <Button className="tools-button" type="primary" onClick={()=>showModal("https://file.tlzcf.vip/img.png")}>
                        诗绣IMG库
                    </Button>
                    <Button className="tools-button" type="primary" onClick={()=>showModal("https://file.tlzcf.vip/gjx.png")}>
                        诗绣工具箱
                    </Button>
                    <Button className="tools-button" type="primary" onClick={()=>showModal("https://file.tlzcf.vip/zl.png")}>
                        王者战力助手
                    </Button>
                    <Button className="tools-button" type="primary" onClick={()=>showModal("https://file.tlzcf.vip/wk.png")}>
                        网课答案助手
                    </Button>
                    <Button className="tools-button" type="primary" onClick={()=>showModal("https://file.tlzcf.vip/ssssss.png")}>
                        诗绣壁纸公众号
                    </Button>
                       <a className="tools-a" target="_blank" href="https://www.tlzcf.vip/app/#/"> 诗绣壁纸网入口 </a>
                </div>
                <div className="chat-auth">
                    <p>今日访问次数为:无限</p>
                    <p>当前有效时间为:长期</p>
                    <div className="chat-kami">
                        <Input className="chat-kami-left" placeholder="请输入授权卡密"/>
                        <Button className="chat-kami-right">验证</Button>
                    </div>
                </div>
            </div>
            <div className="chatRight">
                <p className="chatgpt-title"><img className="chatgpt-png" src={chatgptPng}/> <span
                    className="chatgpt-title-span">Welcome ChatGPT</span></p>
                <div className="chatRight-conent">
                    <div className="chat-conent-text" ref={containerRef}>
                        {chatList && chatList.map(item => (
                                <div className="chat-conent-item">
                                    {item.uid === '1001' &&
                                    <div className="chat-item-right">
                                        <div className="chat-title-item-conent-right">
                                            <div className="chat-title-name-right">
                                                <span>{item.name}</span>
                                                &nbsp;
                                                <span className="chat-title-time">{item.time}</span>
                                            </div>
                                            <img className="chat-title-item-img-right" src={meJpg}/>
                                        </div>
                                        <div className="chat-item-conent-txt-right">
                                            {item.msg}
                                        </div>
                                    </div>
                                    }
                                    {item.uid === '1002' &&
                                    <div className="chat-item-left">
                                        <div className="chat-title-item-conent-left">
                                            <img className="chat-title-item-img-left" src={chatgptPng}/>
                                            <div className="chat-title-name-left">
                                                <span>{item.name}</span>
                                                &nbsp;
                                                <span className="chat-title-time">{item.time}</span>
                                            </div>
                                        </div>
                                        <div className="chat-item-conent-txt-left">
                                            {item.type === 1 && <span dangerouslySetInnerHTML={{__html:item.msg}}></span>}
                                            {item.type === 2 && <img className="item-chatImg" src={item.msg}/>}
                                        </div>
                                    </div>
                                    }
                                </div>
                            )
                        )
                        }
                    </div>
                    <div className="chat-div-button">
                        <Input className="chat-input" value={inputValue} onChange={handleInputChange}/>
                        <Button onClick={() => send()} disabled={isButtonDisabled}
                                className="chat-button">{isButtonDisabled ? `请等待${countdown}秒` : '点击按钮'}</Button>
                    </div>
                    <Alert
                        className="item-alert"
                        banner
                        type="info"
                        icon={<WifiOutlined/>}
                        message={
                            <Marquee speed={60} pauseOnHover gradient={false}>
                                离开家乡以前我以为我想要的是雄心壮志和鹏程万里,后来才发现,我们不断追逐的也不过是饱餐一顿和一个不被闹钟吵醒的清晨。
                            </Marquee>
                        }
                    />
                </div>
            </div>
            <Modal title="工具详情" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}  footer={null}>
                <img className="img-tools" src={imgUrl}/>
            </Modal>
        </div>

    )
}

线上体验地址:http://tlzcf.vip:9000/
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/717651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MIT 6.S081 Lab Seven -- 多线程

MIT 6.S081 Lab Seven -- 多线程 引言MultithreadingUthread: switching between threads (moderate)代码解析补充 Using threads (moderate)代码解析 Barrier(moderate)代码解析 引言 本文为 MIT 6.S081 2020 操作系统 实验七解析。 MIT 6.S081课程前置基础参考: 基于RISC-V…

【C++初阶】12. Stack(栈)和Queue(队列)

1. 栈和队列的介绍 栈的介绍 队列的介绍 2. 栈和队列的使用 最小栈 栈的压入、弹出序列 逆波兰表达式求值 拓展&#xff1a;如何从中缀变为后缀 3. 两种设计模式 设计模式目前分为26种&#xff0c;这里就只介绍两种 适配器模式迭代器模式 在日常生活中&#xff0c;我们常…

Vue生态及实践 - Vue Router(1)

目录 路由 Vue-Router Mode Hash Mode HTML5 Mode 代码实操 目标是替换掉原版的vue-router 路由 路由&#xff08;routing&#xff09;就是通过互联的网络把信息从源地址传输到目的地址的活动。 ——wikipedia Vue-Router 传统web开发路由是后端控制的 随着ajax技术的…

【代理服务器】Squid 反向代理与Nginx缓存代理

目录 一、Squid 反向代理1.1工作机制1.2反向代理实验1.3清空iptables规则&#xff0c;关闭防火墙1.4验证 二、使用Nginx做反向代理缓存服务器三CDN简介3.1什么是CDN3.1CDN工作原理 一、Squid 反向代理 如果 Squid 反向代理服务器中缓存了该请求的资源&#xff0c;则将该请求的…

基于Surprise协同过滤实现短视频推荐

前言 前面一文介绍了通过基础的web项目结构实现简单的内容推荐&#xff0c;与其说那个是推荐不如说是一个排序算法。因为热度计算方式虽然解决了内容的时效质量动态化。但是相对用户而言&#xff0c;大家看到的都是几乎一致的内容&#xff08;不一样也可能只是某时间里某视频的…

准确率 99.9% 的离线IP地址定位库

Ip2region 是一个离线 IP 地址定位库&#xff0c;准确率高达 99.9%&#xff0c;搜索性能为 0.0x 毫秒。DB 文件只有几兆字节&#xff0c;其中存储了所有 IP 地址。 支持 Java、PHP、C、Python、Nodejs、Golang、C#、lua 等查询绑定。查询算法使用二叉树、B树和内存搜索算法。 …

基于Java乡镇篮球队管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

探索小程序的世界(专栏导读、基础理论)

文章导读 一、为什么要学习小程序开发1.1 低门槛1.2 市场需求1.3 创业机会1.4 技术发展趋势 二、专栏导读2.1 实战系列2.2 工具系列2.3 游戏系列2.4 插件系列 三、基础理论3.1 微信小程序简易教程框架组件API工具 开发者工具项目结构 3.2 app.json配置pageswindowtabbar 3.3 Ap…

Android Studio实现内容丰富的安卓自行车租赁平台

如需源码可以添加q-------3290510686&#xff0c;也有演示视频演示具体功能&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号105 1.开发环境 android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看公告 3.查…

Linux centos7.6下查看下线指定用户(实操)

Linux系统是一个多用户多任务的分时操作系统&#xff0c;任何一个要使用系统资源的用户&#xff0c;都必须首先向系统管理员申请一个账号&#xff0c;然后以这个账号的身份进入系统。 用户的账号一方面可以帮助系统管理员对使用系统的用户进行跟踪&#xff0c;并控制他们对系统…

【源码】为什么UWB定位技术可用于室内定位?

UWB室内人员定位原理 UWB室内人员定位技术只是属于无线定位技术的一种。流行的无线定位技术包括GPS定位、北斗定位、蓝牙定位、WIFI定位、RFID定位等&#xff0c;其中GPS、北斗主要用在室外定位&#xff0c;蓝牙定位、WIFI定位、RFID定位、UWB定位主要用于室内定位。UWB定位和…

《软件测试开发》概念篇

目录 一.什么是测试 二.测试与开发之间的区别1.工作内容上的区别 2.技能要求上的区别 3.发展前景 测试与调试之间的区别 三.优秀的测试人员所应具备的素质 四.需求 需求的概念 需求的产生&#xff0c;需求是怎么来的&#xff1f; 测试人员眼中的需求 需求的重要性 测…

论文阅读 (94):Substructure Aware Graph Neural Networks (SAGNN, AAAI2023)

文章目录 1 要点1.1 概述1.2 一些概念1.3 代码1.4 引用 2 基础知识2.1 符号2.2 信息传递神经网络 (MPNN) 3 方法3.1 子图提取3.1.1 基于节点的策略3.1.2 基于图的策略 3.2 随机游走返回概率编码3.3 子图信息注入的信息传递 1 要点 1.1 概述 题目&#xff1a;子结构感知图神经…

《YOLOv5/YOLOv7魔术师》专栏介绍 CSDN独家改进创新实战专栏目录

&#x1f4a1;&#x1f4a1;&#x1f4a1;YOLOv5/YOLOv7魔术师&#xff0c;独家首发创新&#xff08;原创&#xff09;&#xff0c;持续更新&#xff0c;最终完结篇数≥100&#xff0c;适用于Yolov5、Yolov7、Yolov8等各个Yolo系列&#xff0c;专栏文章提供每一步步骤和源码&am…

测试员眼中的____是____

- 1 - 测试员眼中的开发是淘气的孩子 只有靠哄、豁、骗 才能让其完成“作业” - 2 - 测试员眼中的产品经理是女票 不管大小事&#xff0c;只要意见有出入 都得与其商量&#xff0c;才能最终拍板 - 3 - 测试员眼中的UI是艺术家 每天都操着画板&#xff08;苹果显示器&#xff…

解除网页禁止复制,复制粘贴没烦恼。

参考 解除网页禁止复制&#xff0c;复制粘贴没烦恼。 https://zhuanlan.zhihu.com/p/344419634 安装SuperCopy插件

游戏出海长期向好趋势未改,茄子科技助力企业把握出海机遇

在中国游戏出海成为更多企业的必选题之时&#xff0c;如何把握出海机遇&#xff0c;在激烈竞争中实现增长&#xff0c;成为中国游戏厂商的着力点。秉承着红海将至的市场发展背景&#xff0c;出海全球化、本地化的战略已经成为企业大势所趋&#xff0c;越来越多的游戏厂商开始挑…

【3 栈和队列】共享栈

利用栈底位置相对不变的特性&#xff0c;可以让两个顺序栈共享一个一维数据空间&#xff0c;将两个栈的栈底分别设置在共享空间的两端&#xff0c;两个栈顶向共享空间中间延伸。 两个栈的栈顶指针都指向栈顶元素&#xff0c; top0-1时0号栈为空&#xff0c;top1MaxSize-1时1号…

智安网络|网络安全威胁多样化和复杂化,防护任务日益艰巨

随着数字化和网络化的加速发展&#xff0c;人们面临的网络安全问题日益增多。由于网络安全威胁的多样性和复杂性&#xff0c;网络安全防护变得越来越困难。 一. 网络安全威胁的复杂性 网络安全威胁种类繁多&#xff0c;主要包括病毒、木马、蠕虫、间谍软件、恶意软件、黑客攻击…

解决使用idea的maven打包springboot项目时,“不支持版本号17”的问题

问题描述 在idea里面使用maven的package功能&#xff0c;对一个springboot项目打包jar包时&#xff0c;出现了“不支持版本号17”的错误 经排查&#xff0c;本地确实装了jdk17的&#xff0c;而且运行mvn -version也提示有java 17 解决办法 最后发现&#xff0c;可能是idea…