master
mosonglin 1 year ago
parent 5c049776bd
commit 911df57a45

@ -1,5 +1,6 @@
import threading import threading
import json import json
import socket
from PIL import Image, ImageTk from PIL import Image, ImageTk
import os import os
import time import time
@ -8,6 +9,168 @@ from tkinter import messagebox
from tkinter import ttk from tkinter import ttk
from tkinterdnd2 import DND_FILES, TkinterDnD from tkinterdnd2 import DND_FILES, TkinterDnD
import shutil import shutil
import qrcode
# -*- coding:utf-8 -*-
#
# author: iflytek
#
# 本demo测试时运行的环境为Windows + Python3.7
# 本demo测试成功运行时所安装的第三方库及其版本如下
# cffi==1.12.3
# gevent==1.4.0
# greenlet==0.4.15
# pycparser==2.19
# six==1.12.0
# websocket==0.2.1
# websocket-client==0.56.0
# 合成小语种需要传输小语种文本、使用小语种发音人vcn、tte=unicode以及修改文本编码方式
# 错误码链接https://www.xfyun.cn/document/error-code code返回错误码时必看
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
import websocket
import pyaudio
import datetime
import hashlib
import base64
import hmac
import json
from urllib.parse import urlencode
import time
import ssl
from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
import _thread as thread
import os
STATUS_FIRST_FRAME = 0 # 第一帧的标识
STATUS_CONTINUE_FRAME = 1 # 中间帧标识
STATUS_LAST_FRAME = 2 # 最后一帧的标识
class Ws_Param(object):
# 初始化
def __init__(self, APPID, APIKey, APISecret, Text):
self.APPID = APPID
self.APIKey = APIKey
self.APISecret = APISecret
self.Text = Text
# 公共参数(common)
self.CommonArgs = {"app_id": self.APPID}
# 业务参数(business),更多个性化参数可在官网查看
self.BusinessArgs = {"aue": "raw", "auf": "audio/L16;rate=12000", "vcn": "xiaoyan", "tte": "utf8"}
self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-8')), "UTF8")}
#使用小语种须使用以下方式此处的unicode指的是 utf16小端的编码方式即"UTF-16LE"”
#self.Data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-16')), "UTF8")}
# 生成url
def create_url(self):
url = 'wss://tts-api.xfyun.cn/v2/tts'
# 生成RFC1123格式的时间戳
now = datetime.now()
date = format_date_time(mktime(now.timetuple()))
# 拼接字符串
signature_origin = "host: " + "ws-api.xfyun.cn" + "\n"
signature_origin += "date: " + date + "\n"
signature_origin += "GET " + "/v2/tts " + "HTTP/1.1"
# 进行hmac-sha256进行加密
signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
digestmod=hashlib.sha256).digest()
signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
self.APIKey, "hmac-sha256", "host date request-line", signature_sha)
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
# 将请求的鉴权参数组合为字典
v = {
"authorization": authorization,
"date": date,
"host": "ws-api.xfyun.cn"
}
# 拼接鉴权参数生成url
url = url + '?' + urlencode(v)
# print("date: ",date)
# print("v: ",v)
# 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释比对相同参数时生成的url与自己代码生成的url是否一致
# print('websocket url :', url)
return url
def on_message(ws, message):
try:
message =json.loads(message)
code = message["code"]
sid = message["sid"]
audio = message["data"]["audio"]
audio = base64.b64decode(audio)
status = message["data"]["status"]
print(message)
if status == 2:
print("ws is closed")
ws.close()
if code != 0:
errMsg = message["message"]
print("sid:%s call error:%s code is:%s" % (sid, errMsg, code))
else:
with open('./demo.pcm', 'ab') as f:
f.write(audio)
except Exception as e:
print("receive msg,but parse exception:", e)
# 收到websocket错误的处理
def on_error(ws, error):
print("### error:", error)
# 收到websocket关闭的处理
def on_close(ws):
print("### closed ###")
# 收到websocket连接建立的处理
def on_open(ws):
def run(*args):
d = {"common": wsParam.CommonArgs,
"business": wsParam.BusinessArgs,
"data": wsParam.Data,
}
d = json.dumps(d)
print("------>开始发送文本数据")
ws.send(d)
if os.path.exists('./demo.pcm'):
os.remove('./demo.pcm')
thread.start_new_thread(run, ())
def saysay(text):
global wsParam
# 测试时候在此处正确填写相关信息即可运行
wsParam = Ws_Param(APPID='758c6465', APISecret='NTdjYWViNzcxZjI1YjFiY2QwOThjNTBl',
APIKey='8c4e835c82e54fbc84a4bf05f8a33972',
Text=text)
websocket.enableTrace(False)
wsUrl = wsParam.create_url()
ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close)
ws.on_open = on_open
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(2), channels=1, rate=12000, output=True)
# 将 pcm 数据直接写入 PyAudio 的数据流
with open("demo.pcm", "rb") as f:
stream.write(f.read())
stream.stop_stream()
stream.close()
p.terminate()
#image_references=[] #image_references=[]
class logIn:#登录界面 class logIn:#登录界面
def __init__(self): def __init__(self):
@ -55,6 +218,7 @@ class admin:#管理员主界面
self.file12=tk.PhotoImage(file=".\\img\\cf.png") self.file12=tk.PhotoImage(file=".\\img\\cf.png")
self.file13=tk.PhotoImage(file=".\\img\\qrxg.png") self.file13=tk.PhotoImage(file=".\\img\\qrxg.png")
self.fileqr=tk.PhotoImage(file=".\\img\\qr.png") self.fileqr=tk.PhotoImage(file=".\\img\\qr.png")
self.filecode=tk.PhotoImage(file=".\img\\qrcode.png")
img=tk.Canvas(self.t,width=560,height=860) img=tk.Canvas(self.t,width=560,height=860)
img.create_image(280,430,image=file) img.create_image(280,430,image=file)
img.place(x=0,y=0) img.place(x=0,y=0)
@ -65,10 +229,42 @@ class admin:#管理员主界面
self.b2=tk.Button(self.t,relief="flat",image=self.file3,command=self.customer,bg="#EEDBCA",activebackground="#EEDBCA") self.b2=tk.Button(self.t,relief="flat",image=self.file3,command=self.customer,bg="#EEDBCA",activebackground="#EEDBCA")
self.b3=tk.Button(self.t,relief="flat",image=self.file4,command=self.food,bg="#EEDBCA",activebackground="#EEDBCA") self.b3=tk.Button(self.t,relief="flat",image=self.file4,command=self.food,bg="#EEDBCA",activebackground="#EEDBCA")
self.b4=tk.Button(self.t,relief="flat",image=self.file5,command=self.psd,bg="#EEDBCA",activebackground="#EEDBCA") self.b4=tk.Button(self.t,relief="flat",image=self.file5,command=self.psd,bg="#EEDBCA",activebackground="#EEDBCA")
self.b1.place(x=180,y=100) self.b5=tk.Button(self.t,relief="flat",image=self.filecode,command=self.qrcode,bg="#EEDBCA",activebackground="#EEDBCA")
self.b2.place(x=180,y=300) self.b1.place(x=180,y=30)
self.b3.place(x=180,y=500) self.b2.place(x=180,y=200)
self.b4.place(x=180,y=700) self.b3.place(x=180,y=370)
self.b4.place(x=180,y=540)
self.b5.place(x=180,y=710)
def makeqr(self):
os.system("start qrcode")
time.sleep(0.5)
ipv4s=socket.gethostbyname_ex(socket.gethostname())[2]
ip=ipv4s[0]
for i in range(1,eval(self.eq1.get())+1):
qrcode.make("http://"+ip+":8080/{}".format(i)).save("qrcode/{}桌.png".format(i))
self.eq1.destroy()
self.b14.destroy()
self.b15.destroy()
self.admin_main()
def reqr(self):
self.eq1.destroy()
self.b14.destroy()
self.b15.destroy()
self.admin_main()
def qrcode(self):
self.b1.destroy()
self.b2.destroy()
self.b3.destroy()
self.b4.destroy()
self.b5.destroy()
self.eq1=tk.Entry(self.t,width=50)
self.eq1.insert("end","请输入最大桌号")
self.eq1.place(x=100,y=200)
self.b14=tk.Button(self.t,relief="flat",activebackground="#EEDBCA",image=self.fileqr,bg="#EEDBCA",command=self.makeqr)
self.b15=tk.Button(self.t,relief="flat",activebackground="#EEDBCA",image=self.file8,bg="#EEDBCA",command=self.reqr)
self.b14.place(x=180,y=480)
self.b15.place(x=180,y=580)
pass
def bif(self): def bif(self):
self.b18.destroy() self.b18.destroy()
self.f2.destroy() self.f2.destroy()
@ -95,29 +291,40 @@ class admin:#管理员主界面
self.e1.destroy() self.e1.destroy()
self.e2.destroy() self.e2.destroy()
self.admin_main() self.admin_main()
def customerbill(self,last): def customerbill(self,last,fl=1):
with open("customerconfig.json",encoding='utf-8') as f: with open("customerconfig.json",encoding='utf-8') as f:
data=json.load(f) data=json.load(f)
if(last!=data): if(last!=data):
last=data last=data
saytext=""
self.tree=ttk.Treeview(self.f2,height=15,show="tree") self.tree=ttk.Treeview(self.f2,height=15,show="tree")
for i in data: for i in data:
self.tree.insert("","end",iid=i,text="桌号:{}".format(i)) self.tree.insert("","end",iid=i,text="桌号:{}".format(i))
for jj in (data[i]): for jj in (data[i]):
for j in jj: for j in jj:
self.tree.insert(i,"end",text="餐品:{} 价格:{}".format(j,jj[j])) self.tree.insert(i,"end",text="餐品:{} 价格:{}".format(j,jj[j]))
self.tree.place(x=0,y=0,width=510) self.tree.place(x=0,y=0,width=510)
time.sleep(1) saytext+="{}桌的客人点餐:".format(i)
if self.flag: self.customerbill(last) for jj in (data[i]):
for j in jj:
saytext+=j
print(fl)
if fl==1:saysay(saytext)
time.sleep(2)
if self.flag: self.customerbill(last,1)
def customer(self): def customer(self):
self.flag=True self.flag=True
self.b1.destroy() self.b1.destroy()
self.b2.destroy() self.b2.destroy()
self.b3.destroy() self.b3.destroy()
self.b4.destroy() self.b4.destroy()
self.b5.destroy()
self.f2=tk.Frame(height=312,width=520,relief='sunken',bd=5) self.f2=tk.Frame(height=312,width=520,relief='sunken',bd=5)
self.f2.place(x=20,y=50) self.f2.place(x=20,y=50)
self.th=threading.Thread(target=lambda:self.customerbill("")) self.th=threading.Thread(target=lambda:self.customerbill(last="",fl=0))
self.th.start() self.th.start()
self.b9=tk.Button(self.t,relief="flat",activebackground="#EEDBCA",image=self.file8,bg="#EEDBCA",command=self.re2) self.b9=tk.Button(self.t,relief="flat",activebackground="#EEDBCA",image=self.file8,bg="#EEDBCA",command=self.re2)
self.b9.place(x=180,y=520) self.b9.place(x=180,y=520)
@ -130,6 +337,8 @@ class admin:#管理员主界面
self.b2.destroy() self.b2.destroy()
self.b3.destroy() self.b3.destroy()
self.b4.destroy() self.b4.destroy()
self.b5.destroy()
self.f2=tk.Frame(height=372,width=520,relief='sunken',bd=5) self.f2=tk.Frame(height=372,width=520,relief='sunken',bd=5)
self.tree2=ttk.Treeview(self.f2,height=18,show="tree") self.tree2=ttk.Treeview(self.f2,height=18,show="tree")
self.f2.place(x=20,y=50) self.f2.place(x=20,y=50)
@ -278,6 +487,8 @@ class admin:#管理员主界面
self.b2.destroy() self.b2.destroy()
self.b3.destroy() self.b3.destroy()
self.b4.destroy() self.b4.destroy()
self.b5.destroy()
self.f3=tk.Frame(height=380,width=520,relief='sunken',bd=5) self.f3=tk.Frame(height=380,width=520,relief='sunken',bd=5)
# #
name=[na['name'] for na in data] name=[na['name'] for na in data]
@ -393,18 +604,32 @@ class admin:#管理员主界面
del data[id-1] del data[id-1]
with open("foodconfig.json",'w',encoding='utf-8') as f: with open("foodconfig.json",'w',encoding='utf-8') as f:
json.dump(data,f,indent=2,sort_keys=True,ensure_ascii=False) json.dump(data,f,indent=2,sort_keys=True,ensure_ascii=False)
self.t.destroy()
new=admin() self.b10.destroy()
new.food() self.b11.destroy()
self.b12.destroy()
self.b18.destroy()
self.f3.destroy()
self.image_references=[]
self.food()
def qrc(self): def qrc(self):
with open("foodconfig.json",encoding='utf-8') as f: with open("foodconfig.json",encoding='utf-8') as f:
data=json.load(f) data=json.load(f)
data.append({"name":self.e1.get(),"price":eval(self.e2.get()),"img":'static/images/'+self.selected_image_path.split("/")[-1]}) data.append({"name":self.e1.get(),"price":eval(self.e2.get()),"img":'static/images/'+self.selected_image_path.split("/")[-1]})
with open("foodconfig.json",'w',encoding='utf-8') as f: with open("foodconfig.json",'w+',encoding='utf-8') as f:
json.dump(data,f,indent=2,sort_keys=True,ensure_ascii=False) json.dump(data,f,indent=2,sort_keys=True,ensure_ascii=False)
shutil.copy(self.selected_image_path, 'static/images') try:shutil.copy(self.selected_image_path, 'static/images')
self.t.destroy() except:pass
admin() self.t1.destroy()
self.t2.destroy()
self.e1.destroy()
self.e2.destroy()
self.f3.destroy()
self.b19.destroy()
self.qr.destroy()
self.imglabel.destroy()
self.food()
def on_drop(self,ev): def on_drop(self,ev):
filepath=ev.data filepath=ev.data
self.selected_image_path=filepath self.selected_image_path=filepath
@ -421,6 +646,7 @@ class admin:#管理员主界面
self.f3.destroy() self.f3.destroy()
self.b19.destroy() self.b19.destroy()
self.qr.destroy() self.qr.destroy()
self.imglabel.destroy()
self.food() self.food()
pass pass
def load_image(self,path, max_height=None): def load_image(self,path, max_height=None):
@ -449,6 +675,7 @@ class admin:#管理员主界面
self.b2.destroy() self.b2.destroy()
self.b3.destroy() self.b3.destroy()
self.b4.destroy() self.b4.destroy()
self.b5.destroy()
self.e1=tk.Entry(self.t,width=50) self.e1=tk.Entry(self.t,width=50)
self.e1.insert("end","请输入原密码") self.e1.insert("end","请输入原密码")
self.e1.place(x=100,y=200) self.e1.place(x=100,y=200)

@ -2,18 +2,15 @@
"billist": [ "billist": [
[ [
{ {
"鸡排": 88 "烤牛排": 30
}, },
{ {
"鸡排": 88 "水果": 50
},
{
"鸡排": 88
} }
], ],
[ [
{ {
"鸡排": 88 "汉堡": 20
} }
] ]
] ]

@ -1 +1,15 @@
{} {
"31": [
{
"烤牛排": 30
}
],
"35": [
{
"水果": 50
},
{
"水果": 50
}
]
}

@ -1,7 +1,17 @@
[ [
{ {
"img": "static/images/12.jpg", "img": "static/images/niu.jpg",
"name": "煎饼", "name": "烤牛排",
"price": 123 "price": 30
},
{
"img": "static/images/123.jpg",
"name": "水果",
"price": 50
},
{
"img": "static/images/4.jpg",
"name": "汉堡",
"price": 20
} }
] ]

@ -7,10 +7,62 @@ $def with(foods,num)
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>美食自由</title> <title>美食自由</title>
<style> <style>
#call-tab {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
}
#chat-messages {
width: 300px;
height: 200px;
border: 1px solid #ccc;
overflow-y: scroll;
margin-bottom: 10px;
}
#message-input-call {
width: 200px;
margin-right: 10px;
}
#send-button-call {
background-color: #0084FF;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
table{ table{
margin: 5em 0em; margin: 5em 0em;
} }
</style> </style>
<script>
function sendMessageCall() {
var messageInputCall = document.getElementById('message-input-call');
var messageCall = messageInputCall.value.trim();
if (messageCall !== '') {
// Simulate sending the message to the server (replace this with your actual server endpoint)
// In a real implementation, you would use AJAX or fetch to send the message to the server
console.log('Sending message to server:', messageCall);
// Display the sent message in the chat box
var chatMessages = document.getElementById('chat-messages');
var sentMessage = document.createElement('div');
sentMessage.className = 'message user-message';
sentMessage.innerHTML = '<strong>You:</strong> ' + messageCall;
chatMessages.appendChild(sentMessage);
// Clear the input field
messageInputCall.value = '';
// Scroll to the bottom of the chat box
chatMessages.scrollTop = chatMessages.scrollHeight;
}
}
</script>
<script src="static/jquery/jquery-1.12.4.min.js"></script> <script src="static/jquery/jquery-1.12.4.min.js"></script>
<!--包括所有已编译的插件--> <!--包括所有已编译的插件-->
<script src="static/bootstrap/js/bootstrap.min.js"></script> <script src="static/bootstrap/js/bootstrap.min.js"></script>
@ -54,13 +106,25 @@ $def with(foods,num)
<ul class="nav nav-pills "> <ul class="nav nav-pills ">
<li><a href="#order" data-toggle="pill">点餐</a></li> <li><a href="#order" data-toggle="pill">点餐</a></li>
<li><a href="#ordered" data-toggle="pill">已点</a></li> <li><a href="#ordered" data-toggle="pill">已点</a></li>
<li><a href="#call" data-toggle="pill">备注/反馈</a></li> <li><a href="#call" data-toggle="pill">客服</a></li>
<li><a href="#bill" data-toggle="pill">结算账单</a></li> <li><a href="#bill" data-toggle="pill">结算账单</a></li>
<li><p class="navbar-text">&nbsp;&nbsp;&nbsp;桌号:$num</p></li> <li><p class="navbar-text">&nbsp;&nbsp;&nbsp;桌号:$num</p></li>
</ul> </ul>
</nav> </nav>
<div id="content" class="tab-content"> <div id="content" class="tab-content">
<div class="tab-pane fade" id="call">
<br>
<br>
<br>
<div id="call-tab">
<div id="chat-messages"></div>
<div>
<input type="text" id="message-input-call" placeholder="输入消息...">
<button id="send-button-call" onclick="sendMessageCall()">发送</button>
</div>
</div>
</div>
<div class="tab-pane fade" id="ordered"> <div class="tab-pane fade" id="ordered">
<form action="/ord" method="post"> <form action="/ord" method="post">
<textarea id="hidep"></textarea> <textarea id="hidep"></textarea>
@ -121,5 +185,6 @@ $def with(foods,num)
<li><a id="total">0</a></li> <li><a id="total">0</a></li>
</ul> </ul>
</nav> </nav>
</body> </body>
</html> </html>

@ -1,3 +1,3 @@
{ {
"pwd": "aaa123" "pwd": "a123456"
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

@ -1,2 +0,0 @@
python myweb.py 172.20.10.2:80
pause
Loading…
Cancel
Save