implement chat

This commit is contained in:
wangjiacai 2023-04-03 01:00:24 +08:00
parent 3b1abe06be
commit 794502df69
7 changed files with 178 additions and 10 deletions

View File

@ -7,6 +7,7 @@ SQLALCHEMY_DATABASE_URI=sqlite:///sqlite.db
[network]
PROXY=http://127.0.0.1:7890
[gpt]
SECRET_KEY=
[openai]
API_KEY=
MODEL_NAME=gpt-3.5-turbo
PROMPT=You are a helpful assistant

View File

@ -14,6 +14,10 @@ def create_app():
app.config['SECRET_KEY'] = conf['app']['SECRET_KEY']
app.config['SQLALCHEMY_DATABASE_URI'] = conf['app']['SQLALCHEMY_DATABASE_URI']
app.config['NETWORK_PROXY'] = conf['network']['PROXY']
app.config['OPENAI_API_KEY'] = conf['openai']['API_KEY']
app.config['OPENAI_MODEL_NAME'] = conf['openai']['MODEL_NAME']
app.config['OPENAI_PROMPT'] = conf['openai']['PROMPT']
db.init_app(app)
login_manager = LoginManager()

View File

@ -1,6 +1,8 @@
from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask import Blueprint, render_template, current_app, request, flash, redirect, url_for
from flask_login import login_required, current_user, login_manager
from .models import User
from .models import User, Conversation
from . import db
import openai
main = Blueprint('main', __name__)
@ -40,4 +42,53 @@ def manage():
@main.route('/chat')
@login_required
def chat():
return "暂未实现"
if current_user.isActivated:
return render_template('chat.html', user=current_user)
else:
flash("您的账户暂未被激活")
return redirect(url_for('main.index'))
return redirect(url_for('main.index'))
@main.route('/chat', methods=['POST'])
@login_required
def chat_post():
openai.api_key = current_app.config['OPENAI_API_KEY']
openai.proxy = current_app.config['NETWORK_PROXY']
msg = request.form.get("msg")
new_conversation = Conversation(userid=current_user.id,
useremail=current_user.email,
username=current_user.name,
request=msg,
response="")
db.session.add(new_conversation)
db.session.commit()
if current_user.is_authenticated and current_user.isActivated:
openai_resp = openai.ChatCompletion.create(
model=current_app.config['OPENAI_MODEL_NAME'],
messages=[
{"role": "system",
"content": current_app.config['OPENAI_PROMPT']},
{"role": "user", "content": msg}
]
)
msg_resp = openai_resp['choices'][0]['message']['content']
if msg_resp:
response = {"message": msg_resp, "status": "success"}
else:
response = {"message": "请求错误", "status": "success"}
else:
response = {"message": "请先登录/激活", "status": "fail"}
new_conversation = Conversation(userid=current_user.id,
useremail=current_user.email,
username=current_user.name,
request=msg,
response=msg_resp)
db.session.add(new_conversation)
db.session.commit()
return response

View File

@ -1,5 +1,6 @@
from flask_login import UserMixin
from . import db
from sqlalchemy.sql import func
class User(UserMixin, db.Model):
@ -10,3 +11,13 @@ class User(UserMixin, db.Model):
name = db.Column(db.String(100), nullable=False)
role = db.Column(db.String(100), nullable=False)
isActivated = db.Column(db.Boolean, nullable=False)
class Conversation(db.Model):
id = db.Column(db.Integer, primary_key=True)
userid = db.Column(db.Integer)
useremail = db.Column(db.String(100), nullable=False)
username = db.Column(db.String(100), nullable=False)
request = db.Column(db.String(10000))
response = db.Column(db.String(10000))
datetime = db.Column(db.DateTime, server_default=func.now())

View File

@ -49,12 +49,10 @@
</div>
</div>
</nav>
<div class="hero-body">
<div class="container has-text-centered">
{% block content %}
{% endblock content %}
</div>
</div>
<script>
{% if user and user.is_authenticated %}
var navbar_hide_element = ["navbar-login", "navbar-signup"];

101
project/templates/chat.html Normal file
View File

@ -0,0 +1,101 @@
{% extends "base.html" %}
{% block content %}
{% if user and user.is_authenticated %}
{% if user.isActivated %}
<div id="chat-window" class="jumbotron jumbotron-fluid">
<ul id="msg-list">
</ul>
</div>
<div class="fixed-bottom form-inline">
<textarea id="msgbox" class="form-control" style="min-width:80%"></textarea>
<button id="btn-send"
class="btn btn-info"
type="button"
onclick="send_message()"
disabled>
<svg xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-send"
viewBox="0 0 16 16">
<path d="M15.854.146a.5.5 0 0 1 .11.54l-5.819 14.547a.75.75 0 0 1-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 0 1 .124-1.33L15.314.037a.5.5 0 0 1 .54.11ZM6.636 10.07l2.761 4.338L14.13 2.576 6.636 10.07Zm6.787-8.201L1.591 6.602l4.339 2.76 7.494-7.493Z"/>
</svg>
</button>
</div>
<script>
var msgbox = document.getElementById("msgbox");
var btn_send = document.getElementById("btn-send");
msgbox.addEventListener('input', (e) => {
msgbox.style.height = "100px";
msgbox.style.height = e.target.scrollHeight + 'px';
if (msgbox.value){
btn_send.disabled = false;
} else{
btn_send.disabled = true;
}
});
</script>
<script>
function send_message() {
var data= {
msgtype: "text",
msg: msgbox.value
}
if (data.msg) {
var msg_list = document.getElementById("msg-list")
var li = document.createElement('li');
var span = document.createElement('span');
li.appendChild(span)
li.style.textAlign="right"
li.style.marginBottom="20px"
span.innerHTML=data.msg
span.style.backgroundColor="lightblue"
span.style.borderRadius="10px"
span.style.padding="5px"
msg_list.appendChild(li)
}
msgbox.value=""
btn_send.disabled = true;
$.ajax({
type: 'POST',
url: "{{ url_for('main.chat') }}",
data: data,
success: null,
dataType: null
}).always(function (response) {
if (response?.status == "success") {
var msg_list = document.getElementById("msg-list")
var li = document.createElement('li');
var span = document.createElement('span');
li.appendChild(span)
span.innerText=response.message
li.style.textAlign="left"
li.style.marginBottom="20px"
span.style.backgroundColor="lightgreen"
span.style.borderRadius="10px"
span.style.padding="5px"
msg_list.appendChild(li)
msg_list.appendChild(document.createElement('br'))
}
});
}
</script>
{% else %}
<p class="text-warning">您的账号暂未激活,请等待管理员激活此账号。</p>
{% endif %}
{% else %}
<a href="{{ url_for('auth.login') }}">
<button type="button" class="btn btn-primary">登录</button>
</a>
<a href="{{ url_for('auth.signup') }}">
<button type="button" class="btn btn-default">注册</button>
</a>
{% endif %}
{% with messages = get_flashed_messages() %}
{% if messages %}<div class="notification is-danger">{{ messages[0] }}</div>{% endif %}
{% endwith %}
{% endblock content %}

View File

@ -1,4 +1,6 @@
Flask==2.2.3
Flask_Login==0.6.2
flask_sqlalchemy==3.0.3
openai==0.27.2
SQLAlchemy==2.0.7
Werkzeug==2.2.3