implement chat
This commit is contained in:
parent
3b1abe06be
commit
794502df69
@ -7,6 +7,7 @@ SQLALCHEMY_DATABASE_URI=sqlite:///sqlite.db
|
|||||||
[network]
|
[network]
|
||||||
PROXY=http://127.0.0.1:7890
|
PROXY=http://127.0.0.1:7890
|
||||||
|
|
||||||
[gpt]
|
[openai]
|
||||||
SECRET_KEY=
|
API_KEY=
|
||||||
MODEL_NAME=gpt-3.5-turbo
|
MODEL_NAME=gpt-3.5-turbo
|
||||||
|
PROMPT=You are a helpful assistant
|
||||||
|
@ -14,6 +14,10 @@ def create_app():
|
|||||||
|
|
||||||
app.config['SECRET_KEY'] = conf['app']['SECRET_KEY']
|
app.config['SECRET_KEY'] = conf['app']['SECRET_KEY']
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = conf['app']['SQLALCHEMY_DATABASE_URI']
|
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)
|
db.init_app(app)
|
||||||
login_manager = LoginManager()
|
login_manager = LoginManager()
|
||||||
|
@ -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 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__)
|
main = Blueprint('main', __name__)
|
||||||
|
|
||||||
@ -40,4 +42,53 @@ def manage():
|
|||||||
@main.route('/chat')
|
@main.route('/chat')
|
||||||
@login_required
|
@login_required
|
||||||
def chat():
|
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
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from flask_login import UserMixin
|
from flask_login import UserMixin
|
||||||
from . import db
|
from . import db
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
|
||||||
|
|
||||||
class User(UserMixin, db.Model):
|
class User(UserMixin, db.Model):
|
||||||
@ -10,3 +11,13 @@ class User(UserMixin, db.Model):
|
|||||||
name = db.Column(db.String(100), nullable=False)
|
name = db.Column(db.String(100), nullable=False)
|
||||||
role = db.Column(db.String(100), nullable=False)
|
role = db.Column(db.String(100), nullable=False)
|
||||||
isActivated = db.Column(db.Boolean, 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())
|
||||||
|
@ -49,12 +49,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container has-text-centered">
|
<div class="container has-text-centered">
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<script>
|
<script>
|
||||||
{% if user and user.is_authenticated %}
|
{% if user and user.is_authenticated %}
|
||||||
var navbar_hide_element = ["navbar-login", "navbar-signup"];
|
var navbar_hide_element = ["navbar-login", "navbar-signup"];
|
||||||
|
101
project/templates/chat.html
Normal file
101
project/templates/chat.html
Normal 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 %}
|
@ -1,4 +1,6 @@
|
|||||||
Flask==2.2.3
|
Flask==2.2.3
|
||||||
Flask_Login==0.6.2
|
Flask_Login==0.6.2
|
||||||
flask_sqlalchemy==3.0.3
|
flask_sqlalchemy==3.0.3
|
||||||
|
openai==0.27.2
|
||||||
|
SQLAlchemy==2.0.7
|
||||||
Werkzeug==2.2.3
|
Werkzeug==2.2.3
|
||||||
|
Reference in New Issue
Block a user