/// <summary>
        /// 打印订单及菜品信息
        /// </summary>
        async Task printDine(string dineId, List <int> dineMenuIds, List <PrintType> printTypes)
        {
            DineForPrinting dp = null;

            try {
                dp = await getDineForPrinting(dineId, dineMenuIds);

                if (dp == null)
                {
                    serverLog("获取订单信息失败,请检查网络设置", LogLevel.Error);
                    return;
                }

                serverLog($"发送打印命令 单号: {dineId}", LogLevel.Info);

                if (Config.IsIPPrinter)
                {
                    DinePrinter dinePrinter = new DinePrinter();
                    await dinePrinter.Print(dp, printTypes, dineMenuIds.Count == 0);
                }
                else
                {
                    DineDriverPrinter dineDriverPrinter = new DineDriverPrinter();
                    dineDriverPrinter.Print(dp, printTypes, dineMenuIds.Count == 0);
                }

                serverLog($"发送命令成功 单号: {dineId}", LogLevel.Success);
                printCompleted(dineId);
            }
            catch (Exception e) {
                serverLog($"无法打印 单号: {dineId}, 错误信息: {e.Message}", LogLevel.Error);
                remoteLog(Log.LogLevel.Error, $"DineId: {dineId}, {e.Message}", $"Data: {JsonConvert.SerializeObject(dp)}, Error: {e}");
            }
        }
        /// <summary>
        /// 打印本地测试
        /// </summary>
        async Task printLocalTest(List <PrintType> printTypes, string ipOrName)
        {
            DineForPrinting dp = Config.GetTestProtocol(ipOrName);

            try {
                serverLog($"开始本地测试, 打印机: {ipOrName}", LogLevel.Info);
                serverLog($"发送本地测试单命令", LogLevel.Info);

                if (Config.IsIPPrinter)
                {
                    DinePrinter dinePrinter = new DinePrinter();
                    await dinePrinter.Print(dp, printTypes, true);
                }
                else
                {
                    DineDriverPrinter dineDriverPrinter = new DineDriverPrinter();
                    dineDriverPrinter.Print(dp, printTypes, true);
                }

                serverLog($"发送本地测试单命令成功", LogLevel.Success);
            }
            catch (Exception e) {
                serverLog($"无法打印本地测试单, 错误信息: {e.Message}", LogLevel.Error);
                remoteLog(Log.LogLevel.Error, $"Local Test, {e.Message}", $"Data: {JsonConvert.SerializeObject(dp)}, Error: {e}");
            }
        }
Example #3
0
        /// <summary>
        /// 生成厨房单图片
        /// </summary>
        protected Bitmap generateKitchenOrderBmp(DineForPrinting protocol, DineMenu dineMenu, SetMealMenu setMealMenu)
        {
            Bitmap   bmp        = new Bitmap(protocol.PrinterFormat.PaperSize, maxHeight);
            Graphics g          = Graphics.FromImage(bmp);
            int      realHeight = drawKitchenOrder(g, protocol, dineMenu, setMealMenu);

            return(cutBmp(bmp, realHeight));
        }
Example #4
0
        /// <summary>
        /// 生成传菜单图片
        /// </summary>
        protected Bitmap generateServeOrderBmp(DineForPrinting protocol)
        {
            Bitmap   bmp        = new Bitmap(protocol.PrinterFormat.PaperSize, maxHeight);
            Graphics g          = Graphics.FromImage(bmp);
            int      realHeight = drawServeOrder(g, protocol);

            return(cutBmp(bmp, realHeight));
        }
Example #5
0
        /// <summary>
        /// 生成收银条图片
        /// </summary>
        protected Bitmap generateReciptBmp(DineForPrinting protocol, bool isFullDineMenus)
        {
            Bitmap   bmp        = new Bitmap(protocol.PrinterFormat.PaperSize, maxHeight);
            Graphics g          = Graphics.FromImage(bmp);
            int      realHeight = drawRecipt(g, protocol, isFullDineMenus);

            return(cutBmp(bmp, realHeight));
        }
Example #6
0
        /// <summary>
        /// 根据Graphics绘制传菜单
        /// </summary>
        protected int drawServeOrder(Graphics g, DineForPrinting protocol)
        {
            PrinterGraphics printerG = new PrinterGraphics(g, protocol.PrinterFormat.PaperSize, protocol.PrinterFormat.Font, protocol.PrinterFormat.PaddingRight);

            printerG.DrawStringLine(protocol.Dine.Desk.ServeDepartmentName, protocol.PrinterFormat.ServeOrderFontSize);

            printerG.DrawStringLine($"单号: {protocol.Dine.Id}", protocol.PrinterFormat.ServeOrderSmallFontSize);
            printerG.DrawStringLine($"时间: {protocol.Dine.BeginTime.ToString("M-d HH:mm")}", protocol.PrinterFormat.ServeOrderSmallFontSize);

            printerG.DrawStringLine($"餐桌: {protocol.Dine.Desk.Name}", protocol.PrinterFormat.ServeOrderFontSize);

            printHr(printerG);

            printGrid82(printerG, new string[] { "名称", "数量" }, protocol.PrinterFormat.ServeOrderSmallFontSize);

            printHr(printerG);

            foreach (DineMenu dineMenu in protocol.Dine.DineMenus.Where(p => p.Status != HotelDAO.Models.DineMenuStatus.Returned))
            {
                // 打印具体菜品信息
                printGrid82(printerG, new string[] { dineMenu.Menu.Name, dineMenu.Count.ToString() }, protocol.PrinterFormat.ServeOrderFontSize);

                // 如果菜品为套餐,则打印套餐包含的具体菜品信息
                if (dineMenu.Menu.IsSetMeal)
                {
                    List <SetMealMenu> setMealMenus = dineMenu.Menu.SetMealMenus;
                    for (int i = 0; i < setMealMenus.Count; i++)
                    {
                        char tab = '├';
                        if (i == setMealMenus.Count - 1)
                        {
                            tab = '└';
                        }
                        printGrid82(printerG, new string[] { $"{tab} {setMealMenus[i].Name}", setMealMenus[i].Count.ToString() }, protocol.PrinterFormat.ServeOrderFontSize);
                    }
                }

                // 打印菜品的备注信息
                var remarks = dineMenu.Remarks.ToList();
                for (int i = 0; i < dineMenu.Remarks.Count; i++)
                {
                    char tab = '├';
                    if (i == dineMenu.Remarks.Count - 1)
                    {
                        tab = '└';
                    }
                    printGrid82(printerG, new string[] { $"{tab} {remarks[i].Name}", null, }, protocol.PrinterFormat.ServeOrderFontSize);
                }
            }
            ;

            printEnd(printerG);

            return(printerG.GetHeight());
        }
Example #7
0
        /// <summary>
        /// 根据Graphics绘制厨房单
        /// </summary>
        protected int drawKitchenOrder(Graphics g, DineForPrinting protocol, DineMenu dineMenu, SetMealMenu setMealMenu)
        {
            PrinterGraphics printerG = new PrinterGraphics(g, protocol.PrinterFormat.PaperSize, protocol.PrinterFormat.Font, protocol.PrinterFormat.PaddingRight);

            printerG.DrawStringLine(dineMenu.Menu.DepartmentName, protocol.PrinterFormat.KitchenOrderFontSize);

            printerG.DrawStringLine($"单号: {protocol.Dine.Id}", protocol.PrinterFormat.KitchenOrderSmallFontSize);
            printerG.DrawStringLine($"时间: {protocol.Dine.BeginTime.ToString("M-d HH:mm")}", protocol.PrinterFormat.KitchenOrderSmallFontSize);

            if (dineMenu.Status == HotelDAO.Models.DineMenuStatus.Returned)
            {
                string returnStr = "退菜";
                if (dineMenu.ReturnedReason != null)
                {
                    returnStr += $", 理由: {dineMenu.ReturnedReason}";
                }
                printerG.DrawStringLine(returnStr, protocol.PrinterFormat.KitchenOrderFontSize);
            }

            printerG.DrawStringLine($"餐桌: {protocol.Dine.Desk.Name}", protocol.PrinterFormat.KitchenOrderFontSize);

            printGrid82(printerG, new string[] { dineMenu.Menu.Name, dineMenu.Count.ToString() }, protocol.PrinterFormat.KitchenOrderFontSize);

            if (setMealMenu != null)
            {
                printGrid82(printerG, new string[] { $"└ {setMealMenu.Name}", setMealMenu.Count.ToString() }, protocol.PrinterFormat.KitchenOrderFontSize);
            }

            // 打印菜品的备注信息
            var remarks = dineMenu.Remarks.ToList();

            for (int i = 0; i < dineMenu.Remarks.Count; i++)
            {
                char tab = '├';
                if (i == dineMenu.Remarks.Count - 1)
                {
                    tab = '└';
                }
                printGrid82(printerG, new string[] { $"{tab} {remarks[i].Name}", null, }, protocol.PrinterFormat.KitchenOrderFontSize);
            }

            printEnd(printerG);

            return(printerG.GetHeight());
        }
        /// <summary>
        /// 打印远程测试
        /// </summary>
        async Task printRemoteTest(List <PrintType> printTypes, string ipOrName)
        {
            DineForPrinting dp = null;

            try {
                serverLog($"开始测试, 打印机: {ipOrName}", LogLevel.Info);
                dp = await getDineForPrinting("00000000000000");

                if (dp == null)
                {
                    serverLog("获取订单信息失败,请检查网络设置", LogLevel.Error);
                    return;
                }
                dp.Dine.Desk.ReciptPrinter.IpAddress = ipOrName;
                dp.Dine.Desk.ReciptPrinter.Name      = ipOrName;
                dp.Dine.Desk.ServePrinter.IpAddress  = ipOrName;
                dp.Dine.Desk.ServePrinter.Name       = ipOrName;
                foreach (var dineMenu in dp.Dine.DineMenus)
                {
                    dineMenu.Menu.Printer.IpAddress = ipOrName;
                    dineMenu.Menu.Printer.Name      = ipOrName;
                }

                serverLog($"发送测试单命令", LogLevel.Info);

                if (Config.IsIPPrinter)
                {
                    DinePrinter dinePrinter = new DinePrinter();
                    await dinePrinter.Print(dp, printTypes, true);
                }
                else
                {
                    DineDriverPrinter dineDriverPrinter = new DineDriverPrinter();
                    dineDriverPrinter.Print(dp, printTypes, true);
                }

                serverLog($"发送测试单命令成功", LogLevel.Success);
                printCompleted("00000000000000");
            }
            catch (Exception e) {
                serverLog($"无法打印测试单, 错误信息: {e}", LogLevel.Error);
                remoteLog(Log.LogLevel.Error, $"Online Test, {e.Message}", $"Data: {JsonConvert.SerializeObject(dp)}, Error: {e}");
            }
        }
        async Task <DineForPrinting> getDineForPrinting(string dineId, List <int> dineMenuIds = null)
        {
            object postData = new {
                HotelId     = Config.HotelId,
                DineId      = dineId,
                DineMenuIds = dineMenuIds
            };
            string response = await HttpPost.PostAsync(Config.RemoteGetDineForPrintingUrl, postData);

            if (response == null)
            {
                return(null);
            }

            DineForPrinting protocol = JsonConvert.DeserializeObject <DineForPrinting>(response);

            if (protocol.Hotel == null)
            {
                return(null);
            }
            return(protocol);
        }
Example #10
0
        public static DineForPrinting GetTestProtocol(string ipOrName)
        {
            DineForPrinting p = new DineForPrinting {
                Hotel = new Hotel {
                    Id        = 1,
                    Name      = "本地测试饭店名",
                    Address   = "本地测试饭店地址",
                    OpenTime  = new TimeSpan(8, 0, 0),
                    CloseTime = new TimeSpan(22, 0, 0),
                    Tel       = "000-00000000",
                    Usable    = true
                },
                Dine = new Dine {
                    Id           = "00000000000000",
                    Status       = HotelDAO.Models.DineStatus.Untreated,
                    Type         = HotelDAO.Models.DineType.ToStay,
                    HeadCount    = 10,
                    Price        = 123.56m,
                    OriPrice     = 987.65m,
                    Change       = 123.456m,
                    Discount     = 0.5,
                    DiscountName = "本地测试折扣名",
                    DiscountType = HotelDAO.Models.DiscountType.PayKind,
                    BeginTime    = DateTime.Now,
                    IsPaid       = true,
                    IsOnline     = true,
                    UserId       = "0000000000",
                    Waiter       = new Staff {
                        Id   = "00000000",
                        Name = "本地测试服务员名"
                    },
                    Clerk = new Staff {
                        Id   = "00000000",
                        Name = "本地测试收银员名"
                    },
                    Remarks = new List <Remark> {
                        new Remark {
                            Id = 1, Name = "本地测试备注1", Price = 12.34m
                        },
                        new Remark {
                            Id = 2, Name = "本地测试备注2", Price = 56.78m
                        },
                        new Remark {
                            Id = 3, Name = "本地测试备注3", Price = 90.12m
                        },
                        new Remark {
                            Id = 4, Name = "本地测试备注4", Price = 34.56m
                        }
                    },
                    Desk = new Desk {
                        Id            = "000",
                        QrCode        = "111",
                        Name          = "本地测试桌名",
                        Description   = "本地测试桌子备注信息",
                        AreaType      = HotelDAO.Models.AreaType.Normal,
                        ReciptPrinter = new Printer {
                            Id        = 0,
                            Name      = ipOrName,
                            IpAddress = ipOrName,
                            Usable    = true
                        },
                        ServePrinter = new Printer {
                            Id        = 1,
                            Name      = ipOrName,
                            IpAddress = ipOrName,
                            Usable    = true
                        },
                        ReciptDepartmentName = "测试收银部门名",
                        ServeDepartmentName  = "测试传菜部门名"
                    },
                    DineMenus       = new List <DineMenu>(),
                    DinePaidDetails = new List <DinePaidDetail> {
                        new DinePaidDetail {
                            Price    = 12.34m,
                            RecordId = "1234567890abcdeABCDE",
                            PayKind  = new PayKind {
                                Id   = 0,
                                Name = "本地测试支付1",
                                Type = HotelDAO.Models.PayKindType.Online
                            }
                        },
                        new DinePaidDetail {
                            Price    = 12.34m,
                            RecordId = "1234567890abcdeABCDE",
                            PayKind  = new PayKind {
                                Id   = 0,
                                Name = "本地测试支付2",
                                Type = HotelDAO.Models.PayKindType.Offline
                            }
                        },
                        new DinePaidDetail {
                            Price    = 12.34m,
                            RecordId = "1234567890abcdeABCDE",
                            PayKind  = new PayKind {
                                Id   = 0,
                                Name = "本地测试支付3",
                                Type = HotelDAO.Models.PayKindType.Points
                            }
                        }
                    }
                },
                User = new User {
                    Id          = "00000000",
                    Email       = "*****@*****.**",
                    UserName    = "******",
                    PhoneNumber = "12345678900"
                },
                PrinterFormat = new PrinterFormat {
                    PaperSize                 = 278,
                    Font                      = " 宋体",
                    ColorDepth                = 55,
                    ReciptBigFontSize         = 10,
                    ReciptFontSize            = 10,
                    ReciptSmallFontSize       = 7,
                    KitchenOrderFontSize      = 10,
                    KitchenOrderSmallFontSize = 8,
                    ServeOrderFontSize        = 10,
                    ServeOrderSmallFontSize   = 8,
                    ShiftBigFontSize          = 12,
                    ShiftFontSize             = 8,
                    ShiftSmallFontSize        = 7,
                    PaddingRight              = 0
                }
            };

            for (int i = 1; i <= 2; i++)
            {
                p.Dine.DineMenus.Add(new DineMenu {
                    Status      = HotelDAO.Models.DineMenuStatus.Normal,
                    Count       = 10,
                    OriPrice    = 156.78m,
                    Price       = 12.34m,
                    RemarkPrice = 12.34m,
                    Remarks     = new List <Remark> {
                        new Remark {
                            Id = 0, Name = "本地测试备注1", Price = 12.34m
                        },
                        new Remark {
                            Id = 1, Name = "本地测试备注2", Price = 56.78m
                        },
                        new Remark {
                            Id = 2, Name = "本地测试备注3", Price = 90.12m
                        },
                        new Remark {
                            Id = 3, Name = "本地测试备注4", Price = 34.56m
                        }
                    },
                    Menu = new Menu {
                        Id        = $"0000{i}",
                        Code      = "test",
                        Name      = $"本地测试菜品名{i}",
                        NameAbbr  = $"本地测试{i}",
                        Unit      = "份",
                        IsSetMeal = false,
                        Printer   = new Printer {
                            Id        = 2,
                            Name      = ipOrName,
                            IpAddress = ipOrName,
                            Usable    = true
                        },
                        DepartmentName = $"测试厨房名{i}"
                    }
                });
            }

            return(p);
        }
Example #11
0
        public async Task Print(DineForPrinting protocol, List <PrintType> printTypes, bool isFullDineMenus)
        {
            handleIPPrinterFormat(protocol.PrinterFormat);

            List <Task> allTasks = new List <Task>();

            foreach (PrintType type in printTypes)
            {
                if (type == PrintType.Recipt)
                {
                    if (protocol.Dine.Desk.ReciptPrinter == null)
                    {
                        continue;
                    }

                    IPAddress ip  = IPAddress.Parse(protocol.Dine.Desk.ReciptPrinter.IpAddress);
                    Bitmap    bmp = generateReciptBmp(protocol, isFullDineMenus);
                    allTasks.Add(IPPrinter.GetInstance().Print(ip, bmp, protocol.PrinterFormat.ColorDepth));
                }
                else if (type == PrintType.ServeOrder)
                {
                    if (protocol.Dine.Desk.ServePrinter == null)
                    {
                        continue;
                    }

                    IPAddress ip  = IPAddress.Parse(protocol.Dine.Desk.ServePrinter.IpAddress);
                    Bitmap    bmp = generateServeOrderBmp(protocol);
                    allTasks.Add(IPPrinter.GetInstance().Print(ip, bmp, protocol.PrinterFormat.ColorDepth));
                }
                else if (type == PrintType.KitchenOrder)
                {
                    foreach (DineMenu dineMenu in protocol.Dine.DineMenus.Where(p => p.Status != HotelDAO.Models.DineMenuStatus.Returned))
                    {
                        if (dineMenu.Menu.Printer == null)
                        {
                            continue;
                        }

                        if (!dineMenu.Menu.IsSetMeal)
                        {
                            IPAddress ip  = IPAddress.Parse(dineMenu.Menu.Printer.IpAddress);
                            Bitmap    bmp = generateKitchenOrderBmp(protocol, dineMenu, null);
                            allTasks.Add(IPPrinter.GetInstance().Print(ip, bmp, protocol.PrinterFormat.ColorDepth));
                        }
                        else
                        {
                            foreach (SetMealMenu setMealMenu in dineMenu.Menu.SetMealMenus)
                            {
                                IPAddress ip  = IPAddress.Parse(dineMenu.Menu.Printer.IpAddress);
                                Bitmap    bmp = generateKitchenOrderBmp(protocol, dineMenu, setMealMenu);
                                allTasks.Add(IPPrinter.GetInstance().Print(ip, bmp, protocol.PrinterFormat.ColorDepth));
                            }
                        }
                    }
                }
            }

            foreach (var t in allTasks)
            {
                await t;
            }
        }
Example #12
0
        public void Print(DineForPrinting protocol, List <PrintType> printTypes, bool isFullDineMenus)
        {
            foreach (PrintType type in printTypes)
            {
                if (type == PrintType.Recipt)
                {
                    if (protocol.Dine.Desk.ReciptPrinter == null)
                    {
                        continue;
                    }

                    PrintDocument pd = new PrintDocument();
                    pd.PrinterSettings.PrinterName   = protocol.Dine.Desk.ReciptPrinter.Name;
                    pd.DefaultPageSettings.PaperSize = new PaperSize("Custom", protocol.PrinterFormat.PaperSize, maxHeight);
                    pd.PrintPage += (sender, e) => {
                        drawRecipt(e.Graphics, protocol, isFullDineMenus);
                    };
                    pd.Print();
                }
                else if (type == PrintType.ServeOrder)
                {
                    if (protocol.Dine.Desk.ServePrinter == null)
                    {
                        continue;
                    }

                    PrintDocument pd = new PrintDocument();
                    pd.PrinterSettings.PrinterName   = protocol.Dine.Desk.ServePrinter.Name;
                    pd.DefaultPageSettings.PaperSize = new PaperSize("Custom", protocol.PrinterFormat.PaperSize, maxHeight);
                    pd.PrintPage += (sender, e) => {
                        drawServeOrder(e.Graphics, protocol);
                    };
                    pd.Print();
                }
                else if (type == PrintType.KitchenOrder)
                {
                    foreach (DineMenu dineMenu in protocol.Dine.DineMenus.Where(p => p.Status != HotelDAO.Models.DineMenuStatus.Returned))
                    {
                        if (dineMenu.Menu.Printer == null)
                        {
                            continue;
                        }

                        if (!dineMenu.Menu.IsSetMeal)
                        {
                            PrintDocument pd = new PrintDocument();
                            pd.PrinterSettings.PrinterName   = dineMenu.Menu.Printer.Name;
                            pd.DefaultPageSettings.PaperSize = new PaperSize("Custom", protocol.PrinterFormat.PaperSize, maxHeight);
                            pd.PrintPage += (sender, e) => {
                                drawKitchenOrder(e.Graphics, protocol, dineMenu, null);
                            };
                            pd.Print();
                        }
                        else
                        {
                            foreach (SetMealMenu setMealMenu in dineMenu.Menu.SetMealMenus)
                            {
                                PrintDocument pd = new PrintDocument();
                                pd.PrinterSettings.PrinterName   = dineMenu.Menu.Printer.Name;
                                pd.DefaultPageSettings.PaperSize = new PaperSize("Custom", protocol.PrinterFormat.PaperSize, maxHeight);
                                pd.PrintPage += (sender, e) => {
                                    drawKitchenOrder(e.Graphics, protocol, dineMenu, setMealMenu);
                                };
                                pd.Print();
                            }
                        }
                    }
                }
            }
        }
Example #13
0
        /// <summary>
        /// 根据Graphics绘制收银条
        /// </summary>
        protected int drawRecipt(Graphics g, DineForPrinting protocol, bool isFullDineMenus)
        {
            PrinterGraphics printerG = new PrinterGraphics(g, protocol.PrinterFormat.PaperSize, protocol.PrinterFormat.Font, protocol.PrinterFormat.PaddingRight);

            printerG.DrawStringLine($"欢迎光临{protocol.Hotel.Name}", protocol.PrinterFormat.ReciptBigFontSize, align: StringAlignment.Center);
            printerG.DrawStringLine($"TEL: {protocol.Hotel.Tel}", protocol.PrinterFormat.ReciptSmallFontSize, align: StringAlignment.Center);
            printerG.DrawStringLine($"{protocol.Hotel.Address}", protocol.PrinterFormat.ReciptSmallFontSize, align: StringAlignment.Center);
            printerG.DrawStringLine($"收据", protocol.PrinterFormat.ReciptSmallFontSize, align: StringAlignment.Center);
            printerG.TrimY(5);

            printerG.DrawStringLine($"单号: {protocol.Dine.Id}", protocol.PrinterFormat.ReciptFontSize);
            printerG.DrawStringLine($"时间: {protocol.Dine.BeginTime.ToString("M-d HH:mm")}", protocol.PrinterFormat.ReciptFontSize);

            if (protocol.Dine.Type == HotelDAO.Models.DineType.ToStay)
            {
                printerG.DrawStringLine($"餐桌: {protocol.Dine.Desk.Name}", protocol.PrinterFormat.ReciptFontSize);
            }
            else if (protocol.Dine.Type == HotelDAO.Models.DineType.ToGo)
            {
                printerG.DrawStringLine($"外卖: {protocol.Dine.Desk.Name}", protocol.PrinterFormat.ReciptBigFontSize);
                if (protocol.Dine.TakeOut.RecordId != null)
                {
                    printerG.DrawStringLine($"外卖平台编号: {protocol.Dine.TakeOut.RecordId}", protocol.PrinterFormat.ReciptBigFontSize);
                }
                printerG.DrawStringLine($"手机: {protocol.User.PhoneNumber}", protocol.PrinterFormat.ReciptBigFontSize);
                printerG.DrawStringLine($"地址: {protocol.Dine.TakeOut.Address}", protocol.PrinterFormat.ReciptBigFontSize);
            }

            printHr(printerG);

            printGridRecipt(printerG, new string[] { "名称", "数量", "单价", "折后小计" }, protocol.PrinterFormat.ReciptFontSize);

            printHr(printerG);

            decimal priceAll = 0m;

            foreach (DineMenu dineMenu in protocol.Dine.DineMenus.Where(p => p.Status != HotelDAO.Models.DineMenuStatus.Returned))
            {
                // 打印具体菜品信息
                printGridRecipt(printerG, new string[] {
                    dineMenu.Menu.Name,
                    dineMenu.Count.ToString(),
                    dineMenu.OriPrice.ToString(),
                    (dineMenu.Price * dineMenu.Count).ToString()
                }, protocol.PrinterFormat.ReciptFontSize);

                priceAll += dineMenu.Price * dineMenu.Count;

                // 如果菜品为套餐,则打印套餐包含的具体菜品信息
                if (dineMenu.Menu.IsSetMeal)
                {
                    List <SetMealMenu> setMealMenus = dineMenu.Menu.SetMealMenus;
                    for (int i = 0; i < setMealMenus.Count; i++)
                    {
                        char tab = '├';
                        if (i == setMealMenus.Count - 1)
                        {
                            tab = '└';
                        }
                        printGridRecipt(printerG, new string[] {
                            $"{tab} {setMealMenus[i].Name}",
                            setMealMenus[i].Count.ToString(),
                            null, null
                        }, protocol.PrinterFormat.ReciptFontSize);
                    }
                }

                // 打印菜品的备注信息
                var remarks = dineMenu.Remarks.ToList();
                for (int i = 0; i < dineMenu.Remarks.Count; i++)
                {
                    char tab = '├';
                    if (i == dineMenu.Remarks.Count - 1)
                    {
                        tab = '└';
                    }
                    printGridRecipt(printerG, new string[] {
                        $"{tab} {remarks[i].Name}",
                        null,
                        0 == remarks[i].Price ? null : remarks[i].Price.ToString(),
                        0 == remarks[i].Price ? null : remarks[i].Price.ToString()
                    }, protocol.PrinterFormat.ReciptFontSize);

                    priceAll += remarks[i].Price;
                }
            }
            ;

            printHr(printerG);

            if (isFullDineMenus)
            {
                priceAll = protocol.Dine.Price;
            }
            printGrid55f(printerG, new string[] { "总计", priceAll.ToString() }, protocol.PrinterFormat.ReciptBigFontSize);

            if (protocol.Dine.Discount < 1)
            {
                printerG.DrawStringLine($"{protocol.Dine.DiscountName}: {protocol.Dine.Discount * 10}折", protocol.PrinterFormat.ReciptFontSize);
            }

            string paidWay = protocol.Dine.IsOnline ? "线上支付" : "线下支付";

            printerG.DrawStringLine($"支付方式: {paidWay}", protocol.PrinterFormat.ReciptFontSize);
            foreach (DinePaidDetail dinePaidDetail in protocol.Dine.DinePaidDetails)
            {
                decimal dinePaidDetailPrice = dinePaidDetail.Price;
                if (dinePaidDetail.PayKind.Type == HotelDAO.Models.PayKindType.Cash)
                {
                    dinePaidDetailPrice += protocol.Dine.Change;
                }
                printerG.DrawStringLine($"{dinePaidDetail.PayKind.Name}: ¥{dinePaidDetailPrice}", protocol.PrinterFormat.ReciptFontSize);
            }
            if (protocol.Dine.IsPaid)
            {
                printerG.DrawStringLine($"找零: ¥{protocol.Dine.Change}", protocol.PrinterFormat.ReciptFontSize);
            }
            else
            {
                printerG.DrawStringLine("未支付", protocol.PrinterFormat.ReciptFontSize);
            }

            printEnd(printerG);

            g.Dispose();

            return(printerG.GetHeight());
        }