python cmd 点餐系统


前言

在目前的系统设计中,常见的是窗口设计开发。因此我想做一款基于命令框的系统,同时带有一定的美观性。成果如下图所示。存C语言也能够实现这些功能,有兴趣,做一期这样的介绍。
Rich 是一个 Python 库,用于将富文本(带有颜色和样式)写入终端,并用于显示高级内容,例如表格、markdown 和语法高亮代码。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


引入库

我们需要用到 rich 库。

pip install rich

数据存储

这里数据存储我就使用Json文本格式对数据进行存储

  1. 菜单数据
    格式如下
[
    {"id": 0, "type": "主食", "list": [
        {"id": 0, "name": "米饭", "price": 2},
        {"id": 1, "name": "馒头", "price": 1},
        {"id": 2, "name": "面条", "price": 3}
    ]
     },
    {
        "id": 1,
        "type": "热菜",
        "list": [
            {"id": 0, "name": "红烧肉", "price": 28},
            {"id": 1, "name": "地三鲜", "price": 18},
            {"id": 2, "name": "宫保鸡丁", "price": 25}
        ]
    },
    {
        "id": 2,
        "type": "凉菜",
        "list": [
            {"id": 0, "name": "拍黄瓜", "price": 9},
            {"id": 1, "name": "凉拌黄瓜", "price": 12},
            {"id": 2, "name": "凉拌皮蛋", "price": 15}
        ]
    },
    {
        "id": 3,
        "type": "饮料",
        "list": [
            {"id": 0, "name": "可乐", "price": 3},
            {"id": 1, "name": "雪碧", "price": 3},
            {"id": 2, "name": "矿泉水", "price": 2}
        ]
    },
    {
        "id": 4,
        "type": "酒水",
        "list": [
            {"id": 0, "name": "白酒", "price": 38},
            {"id": 1, "name": "啤酒", "price": 5}
        ]
    }
]

用python进行读取

# 菜单
with open("res/menu.json", 'r', encoding="utf-8") as fp:
    menu = json.load(fp)
  1. 评论数据
    格式如下
["味道不错,下次还来!", "服务态度很好,下次还来!", "菜品很新鲜,下次还来!", "价格实惠,下次还来!", "环境很好,下次还来!"]

python读取

# 评论
with open("res/comment.json", 'r', encoding="utf-8") as fp:
    comment = json.load(fp)
  1. 点菜数据
    用python读取
# 点餐记录
orders_path = "res/orders.json"
with open(orders_path, 'r', encoding="utf-8") as fp:
    orders = json.load(fp)

界面设计

启动加载页

该页面用于数据加载。但是实际上,我这里做的特别简单。知识有着样式,一个不实用的功能。

def start():
    """
    启动页
    :return:
    """
    os.system("cls")
    panel_group = Group(
        Padding(Text.assemble("欢迎使用", ("点餐系统", "rgb(219,122,112)"), justify="center"), (5, 0)),
    )
    print(Panel(panel_group, title="Welcome", subtitle="点餐系统", border_style="rgb(113,112,219)"))
    with Progress() as progress:
        task = progress.add_task("{}[red]loading...".format(" " * 20), total=1000)
        while not progress.finished:
            progress.update(task, advance=5)
            sleep(0.005)
    PageIndex()

首页面

用 up down键来选择

import msvcrt
import sys

# 首页功能列表
indexFun = [
    {"id": 0, "name": "点餐", "fun": PageOrder},
    {"id": 1, "name": "查看未出单", "fun": NoOrderIssued},
    {"id": 2, "name": "查看已出单", "fun": OrderIssued},
    {"id": 3, "name": "退出", "fun": lambda: exit()}
]


def drawIndex(row):
	"""
	绘画首页面
	"""
    os.system("cls")
    text = Text(justify="center")
    text.append("请选择以下的功能:\n\n")
    for i in range(len(indexFun)):
        if i == row:
            text.append("-{}-  {}\n".format(indexFun[i]["id"], indexFun[i]["name"]), style="rgb(0,0,255)")
        else:
            text.append("-{}-  {}\n".format(indexFun[i]["id"], indexFun[i]["name"]))
    print(Panel(Padding(text, (2, 0)), title="Welcome", subtitle="点餐系统", border_style="rgb(113,112,219)"))

    print("up 上移\tdown 下移\tenter 选择")


def PageIndex():
    """
    首页面
    :return:
    """
    os.system("cls")
    row = 0
    drawIndex(row)
    while True:
        if msvcrt.kbhit():  # 检查是否有按键事件
            choose = msvcrt.getch()  # 获取字符,不需要回车确认
            sys.stdout.flush()  # 刷新输出缓冲区,确保字符立即显示
            if ord(choose) == 72:
                if row == 0:
                    row = len(indexFun) - 1
                else:
                    row -= 1
                drawIndex(row)
            elif ord(choose) == 80:
                if row == len(indexFun) - 1:
                    row = 0
                else:
                    row += 1
                drawIndex(row)
            elif ord(choose) == 13:
                indexFun[row]["fun"]()
                break

点餐页

# 点餐单
console = Console()

order = []

def PageOrder():
    """
    点餐页
    :return:
    """
    os.system("cls")

    layout = Layout()
    layout.split_column(
        Layout(Panel(Text("菜单", justify="center", style="white on red")), size=3),
        Layout(name="lower")
    )

    tables = []
    for m in menu:
        table = Table()
        table.add_column("菜号", justify="center", style="cyan", no_wrap=True)
        table.add_column("菜名", justify="center", style="cyan", no_wrap=True)
        table.add_column("价格", justify="center", style="magenta")
        for l in m["list"]:
            table.add_row("{}-{}".format(m["id"], l["id"]), l["name"], "{}¥".format(float(l["price"])))
        tables.append(table)

    panel_left = Panel(Columns(tables, equal=True, expand=True), border_style="rgb(113,112,219)", title="菜单",
                       title_align="left")
    layout["lower"].split_row(
        Layout(panel_left, ratio=3),
        Layout(Panel(Columns(comment, equal=True, expand=True), border_style="rgb(113,112,219)", subtitle="评论"))
    )
    print(layout)

    while 1:
        choose = Prompt.ask("请输入需要点菜的编号(e 返回首页)(o 完成|修改)", default="e")
        if choose == "e":
            PageIndex()
            break

        if choose == "o":
            total = 0.0
            table = Table()
            for name in ["菜类型", "菜名", "价格", "数量", "总价"]:
                table.add_column(name, justify="center", style="cyan")

            with Live(table, refresh_per_second=4) as live:
                for orde in order:
                    sleep(0.4)
                    total += orde["price"] * orde["num"]
                    table.add_row(orde["type"], orde["name"],
                                  "{}¥".format(orde["price"]), str(orde["num"]),
                                  "{}¥".format(orde["price"] * orde["num"]))
                table.add_row("-", "-", "-", "-", "-")
                table.add_row("", "", "", "", "{}¥".format(total))
            choose = Prompt.ask("--1 提交 - 2 修改 - 3 返回首页--", choices=["1", "2", "3"], default="1")
            if choose == "1":
                orders.append(order)
                with open(orders_path, "w+", encoding="utf-8") as f:
                    orders.append({"time": time.asctime(time.localtime(time.time())), "order": order, "type": False})
                    json.dump(orders, f)
                with console.status("出票中...", spinner="hearts"):
                    print("购买成功")
                    for i in range(10):
                        time.sleep(0.2)
                PageIndex()
                break
            elif choose == "2":
                c = Prompt.ask("请选择需要修改的行号(从1开始),以及份数.格式为:行号-份数(或者行号,默认0)")
                try:
                    c = c.split("-")
                    if len(c) == 1:
                        order[int(c[0]) - 1]["num"] = 0
                    else:
                        order[int(c[0]) - 1]["num"] = int(c[1])
                except:
                    print("[red]输入有误[/red]")
            elif choose == "3":
                PageIndex()
                break
        try:
            num = [int(i) for i in choose.split("-")]
        except:
            print("[red]输入的内容错误!!![/red]")

        if len(num) == 2:
            o = {"type": "", "name": "", "price": 0.0, "num": 0}
            for m in menu:
                if m["id"] == num[0]:
                    o["type"] = m["type"]
                    for l in m["list"]:
                        if l["id"] == num[1]:
                            o["name"] = l["name"]
                            o["price"] = l["price"]
                            break
                    break
            if o["type"] == "":
                print("[red]没有该菜类!!![/red]")
            elif o["name"] == "":
                print("[red]没有该菜品!!![/red]")
            else:
                while True:
                    choose = Prompt.ask("请输入需要该菜品的数量(默认1份): ", default="1")
                    try:
                        n = int(choose)
                        o["num"] = n
                        order.append(o)
                        break
                    except:
                        print("[red]输入的值类型错误[/red]")
        else:
            print("[red]输入格式有误!!![/red]")

单子查看

def issuedCommon(oss):
	"""
	单子展示样式函数
	"""
    total = 0.0
    table = Table()
    for name in ["时间", "菜类型", "菜名", "价格", "数量", "总价"]:
        table.add_column(name, justify="center", style="cyan")

    with Live(table, refresh_per_second=4) as live:
        for o in oss["order"]:
            sleep(0.4)
            total += o["price"] * o["num"]
            table.add_row(oss["time"], o["type"], o["name"],
                          "{}¥".format(o["price"]), str(o["num"]),
                          "{}¥".format(o["price"] * o["num"]))
        table.add_row("-", "-", "-", "-", "-", "-")
        table.add_row("", "", "", "", "", "{}¥".format(total))


def NoOrderIssued():
    """
    未出单
    :return:
    """
    os.system("cls")
    temp = []
    for oss in orders:
        if not oss["type"]:
            temp.append(oss)
            issuedCommon(oss)
    choose = Prompt.ask("请输入要出单的行号(从1开始,错误输入返回首页面)")
    try:
        for i in range(len(orders)):
            if temp[int(choose) - 1]["time"] == orders[i]["time"]:
                orders[i]["type"] = True
                with open(orders_path, "w+", encoding="utf-8") as f:
                    json.dump(orders, f)
                with console.status("修改中...", spinner="monkey"):
                    print("出单成功")
                    for i in range(10):
                        time.sleep(0.2)
                break
            else:
                with console.status("出单失败...", spinner="monkey"):
                    print("出单失败")
                    for i in range(10):
                        time.sleep(0.2)
                break
        PageIndex()
    except:
        PageIndex()


def OrderIssued():
    """
    已出单
    :return:
    """
    os.system("cls")
    for oss in orders:
        if oss["type"]:
            issuedCommon(oss)
    console.input("任意键返回")
    PageIndex()


# 首页功能列表
indexFun = [
    {"id": 0, "name": "点餐", "fun": PageOrder},
    {"id": 1, "name": "查看未出单", "fun": NoOrderIssued},
    {"id": 2, "name": "查看已出单", "fun": OrderIssued},
    {"id": 3, "name": "退出", "fun": lambda: exit()}
]

总结

这总简单的系统,代码就这么多了。最后,运行的时候主要在电脑的 cmd上运行。编译器上带的终端里面有些样式也 看不见。有问题,或者不懂的,直接问都可以。后面出C语言版本的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值