diff --git a/model/用例图_莫松霖_美食自由.vsdx b/model/用例图_莫松霖_美食自由.vsdx index 1aa509b..10d5a9a 100644 Binary files a/model/用例图_莫松霖_美食自由.vsdx and b/model/用例图_莫松霖_美食自由.vsdx differ diff --git a/other/other/pther.txt b/other/other/pther.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/myweb3/admin.py b/src/myweb3/admin.py index 8e30e90..4bfbcee 100644 --- a/src/myweb3/admin.py +++ b/src/myweb3/admin.py @@ -1,5 +1,6 @@ import threading import json +import socket from PIL import Image, ImageTk import os import time @@ -8,6 +9,168 @@ from tkinter import messagebox from tkinter import ttk from tkinterdnd2 import DND_FILES, TkinterDnD 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=[] class logIn:#登录界面 def __init__(self): @@ -55,6 +218,7 @@ class admin:#管理员主界面 self.file12=tk.PhotoImage(file=".\\img\\cf.png") self.file13=tk.PhotoImage(file=".\\img\\qrxg.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.create_image(280,430,image=file) 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.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.b1.place(x=180,y=100) - self.b2.place(x=180,y=300) - self.b3.place(x=180,y=500) - self.b4.place(x=180,y=700) + self.b5=tk.Button(self.t,relief="flat",image=self.filecode,command=self.qrcode,bg="#EEDBCA",activebackground="#EEDBCA") + self.b1.place(x=180,y=30) + self.b2.place(x=180,y=200) + 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): self.b18.destroy() self.f2.destroy() @@ -95,29 +291,40 @@ class admin:#管理员主界面 self.e1.destroy() self.e2.destroy() self.admin_main() - def customerbill(self,last): + def customerbill(self,last,fl=1): with open("customerconfig.json",encoding='utf-8') as f: data=json.load(f) if(last!=data): last=data + saytext="" self.tree=ttk.Treeview(self.f2,height=15,show="tree") for i in data: self.tree.insert("","end",iid=i,text="桌号:{}".format(i)) + for jj in (data[i]): for j in jj: self.tree.insert(i,"end",text="餐品:{} 价格:{}".format(j,jj[j])) self.tree.place(x=0,y=0,width=510) - time.sleep(1) - if self.flag: self.customerbill(last) + saytext+="{}桌的客人点餐:".format(i) + 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): self.flag=True self.b1.destroy() self.b2.destroy() self.b3.destroy() self.b4.destroy() + self.b5.destroy() + self.f2=tk.Frame(height=312,width=520,relief='sunken',bd=5) 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.b9=tk.Button(self.t,relief="flat",activebackground="#EEDBCA",image=self.file8,bg="#EEDBCA",command=self.re2) self.b9.place(x=180,y=520) @@ -130,6 +337,8 @@ class admin:#管理员主界面 self.b2.destroy() self.b3.destroy() self.b4.destroy() + self.b5.destroy() + self.f2=tk.Frame(height=372,width=520,relief='sunken',bd=5) self.tree2=ttk.Treeview(self.f2,height=18,show="tree") self.f2.place(x=20,y=50) @@ -278,6 +487,8 @@ class admin:#管理员主界面 self.b2.destroy() self.b3.destroy() self.b4.destroy() + self.b5.destroy() + self.f3=tk.Frame(height=380,width=520,relief='sunken',bd=5) # name=[na['name'] for na in data] @@ -393,18 +604,32 @@ class admin:#管理员主界面 del data[id-1] with open("foodconfig.json",'w',encoding='utf-8') as f: json.dump(data,f,indent=2,sort_keys=True,ensure_ascii=False) - self.t.destroy() - new=admin() - new.food() + + self.b10.destroy() + self.b11.destroy() + self.b12.destroy() + self.b18.destroy() + self.f3.destroy() + self.image_references=[] + self.food() def qrc(self): with open("foodconfig.json",encoding='utf-8') as 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]}) - 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) - shutil.copy(self.selected_image_path, 'static/images') - self.t.destroy() - admin() + try:shutil.copy(self.selected_image_path, 'static/images') + except:pass + 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): filepath=ev.data self.selected_image_path=filepath @@ -421,6 +646,7 @@ class admin:#管理员主界面 self.f3.destroy() self.b19.destroy() self.qr.destroy() + self.imglabel.destroy() self.food() pass def load_image(self,path, max_height=None): @@ -449,6 +675,7 @@ class admin:#管理员主界面 self.b2.destroy() self.b3.destroy() self.b4.destroy() + self.b5.destroy() self.e1=tk.Entry(self.t,width=50) self.e1.insert("end","请输入原密码") self.e1.place(x=100,y=200) diff --git a/src/myweb3/bill.json b/src/myweb3/bill.json index 510daf0..10ab85a 100644 --- a/src/myweb3/bill.json +++ b/src/myweb3/bill.json @@ -2,18 +2,15 @@ "billist": [ [ { - "鸡排": 88 + "烤牛排": 30 }, { - "鸡排": 88 - }, - { - "鸡排": 88 + "水果": 50 } ], [ { - "鸡排": 88 + "汉堡": 20 } ] ] diff --git a/src/myweb3/customerconfig.json b/src/myweb3/customerconfig.json index 9e26dfe..7dec22b 100644 --- a/src/myweb3/customerconfig.json +++ b/src/myweb3/customerconfig.json @@ -1 +1,15 @@ -{} \ No newline at end of file +{ + "31": [ + { + "烤牛排": 30 + } + ], + "35": [ + { + "水果": 50 + }, + { + "水果": 50 + } + ] +} \ No newline at end of file diff --git a/src/myweb3/foodconfig.json b/src/myweb3/foodconfig.json index 2950d67..e988c33 100644 --- a/src/myweb3/foodconfig.json +++ b/src/myweb3/foodconfig.json @@ -1,7 +1,17 @@ [ { - "img": "static/images/12.jpg", - "name": "煎饼", - "price": 123 + "img": "static/images/niu.jpg", + "name": "烤牛排", + "price": 30 + }, + { + "img": "static/images/123.jpg", + "name": "水果", + "price": 50 + }, + { + "img": "static/images/4.jpg", + "name": "汉堡", + "price": 20 } ] \ No newline at end of file diff --git a/src/myweb3/index.html b/src/myweb3/index.html index 5ba963f..08c476d 100644 --- a/src/myweb3/index.html +++ b/src/myweb3/index.html @@ -7,10 +7,62 @@ $def with(foods,num) 美食自由 + @@ -54,13 +106,25 @@ $def with(foods,num)
+
+
+
+
+
+
+
+ + +
+
+
@@ -120,6 +184,7 @@ $def with(foods,num)
  • 0
  • - + + \ No newline at end of file diff --git a/src/myweb3/pwd.json b/src/myweb3/pwd.json index 04f4f17..8145f00 100644 --- a/src/myweb3/pwd.json +++ b/src/myweb3/pwd.json @@ -1,3 +1,3 @@ { - "pwd": "aaa123" + "pwd": "a123456" } \ No newline at end of file diff --git a/src/myweb3/static/images/6.jpg b/src/myweb3/static/images/6.jpg deleted file mode 100644 index cc6a7bf..0000000 Binary files a/src/myweb3/static/images/6.jpg and /dev/null differ diff --git a/src/myweb3/校园网启动.bat b/src/myweb3/校园网启动.bat deleted file mode 100644 index 7c019ed..0000000 --- a/src/myweb3/校园网启动.bat +++ /dev/null @@ -1,2 +0,0 @@ -python myweb.py 172.20.10.2:80 -pause \ No newline at end of file