打印 调整

This commit is contained in:
2026-04-15 18:17:41 +08:00
parent 44f896168f
commit 45fbdd514e
33 changed files with 1887 additions and 1155 deletions

View File

@@ -102,8 +102,8 @@ public class HandoverRecordController {
@OperationLog("收银机-交班/关班") @OperationLog("收银机-交班/关班")
@SaAdminCheckPermission(parentName = "交班记录", value = "handoverRecord:handover", name = "收银机-交班/关班") @SaAdminCheckPermission(parentName = "交班记录", value = "handoverRecord:handover", name = "收银机-交班/关班")
public CzgResult<Long> handover(@RequestParam Integer isPrint) { public CzgResult<Long> handover(@RequestParam Integer isPrint) {
Long id = handoverRecordService.handover(); HandoverRecord handoverRecord = handoverRecordService.handover();
handoverRecordService.printHandoverReceipt(id, isPrint); handoverRecordService.printHandoverReceipt(handoverRecord, isPrint);
return CzgResult.success(id); return CzgResult.success(handoverRecord.getId());
} }
} }

View File

@@ -1,11 +1,7 @@
package com.czg.controller.admin; package com.czg.controller.admin;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.czg.account.dto.print.PrinterAddDTO;
import com.czg.account.dto.print.PrinterDelDTO; import com.czg.account.dto.print.PrinterDelDTO;
import com.czg.account.dto.print.PrinterEditDTO;
import com.czg.account.dto.print.PrinterOrderDTO;
import com.czg.account.entity.PrintMachine; import com.czg.account.entity.PrintMachine;
import com.czg.account.service.PrintMachineService; import com.czg.account.service.PrintMachineService;
import com.czg.annotation.SaAdminCheckPermission; import com.czg.annotation.SaAdminCheckPermission;
@@ -48,15 +44,10 @@ public class PrintMachineController {
} }
if (StrUtil.isNotBlank(subType)) { if (StrUtil.isNotBlank(subType)) {
queryWrapper.eq(PrintMachine::getSubType, subType); queryWrapper.eq(PrintMachine::getPrintType, subType);
} }
queryWrapper.orderBy(PrintMachine::getSort, true).orderBy(PrintMachine::getId, false); queryWrapper.orderBy(PrintMachine::getSort, true).orderBy(PrintMachine::getId, false);
Page<PrintMachine> page = printMachineService.page(PageUtil.buildPage(), queryWrapper); Page<PrintMachine> page = printMachineService.page(PageUtil.buildPage(), queryWrapper);
page.getRecords().forEach(item -> {
if (StrUtil.isNotBlank(item.getCategoryIds())) {
item.setCategoryList(JSONArray.parse(item.getCategoryIds()));
}
});
return CzgResult.success(page); return CzgResult.success(page);
} }
@@ -73,15 +64,10 @@ public class PrintMachineController {
} }
queryWrapper.in(PrintMachine::getConnectionType, "USB", "局域网"); queryWrapper.in(PrintMachine::getConnectionType, "USB", "局域网");
if (StrUtil.isNotBlank(subType)) { if (StrUtil.isNotBlank(subType)) {
queryWrapper.eq(PrintMachine::getSubType, subType); queryWrapper.eq(PrintMachine::getPrintType, subType);
} }
queryWrapper.orderBy(PrintMachine::getSort, true).orderBy(PrintMachine::getId, false); queryWrapper.orderBy(PrintMachine::getSort, true).orderBy(PrintMachine::getId, false);
Page<PrintMachine> page = printMachineService.page(PageUtil.buildPage(), queryWrapper); Page<PrintMachine> page = printMachineService.page(PageUtil.buildPage(), queryWrapper);
page.getRecords().forEach(item -> {
if (StrUtil.isNotBlank(item.getCategoryIds())) {
item.setCategoryList(JSONArray.parse(item.getCategoryIds()));
}
});
return CzgResult.success(page); return CzgResult.success(page);
} }
@@ -94,9 +80,6 @@ public class PrintMachineController {
@GetMapping("/detail") @GetMapping("/detail")
public CzgResult<PrintMachine> detail(@RequestParam Integer id) { public CzgResult<PrintMachine> detail(@RequestParam Integer id) {
PrintMachine printMachine = printMachineService.getOne(new QueryWrapper().eq(PrintMachine::getId, id).eq(PrintMachine::getShopId, StpKit.USER.getShopId())); PrintMachine printMachine = printMachineService.getOne(new QueryWrapper().eq(PrintMachine::getId, id).eq(PrintMachine::getShopId, StpKit.USER.getShopId()));
if (printMachine != null && StrUtil.isNotBlank(printMachine.getCategoryIds())) {
printMachine.setCategoryList(JSONArray.parse(printMachine.getCategoryIds()));
}
return CzgResult.success(printMachine); return CzgResult.success(printMachine);
} }
@@ -107,7 +90,7 @@ public class PrintMachineController {
*/ */
@SaAdminCheckPermission(parentName = "打印机管理", value = "printer:add", name = "打印机新增") @SaAdminCheckPermission(parentName = "打印机管理", value = "printer:add", name = "打印机新增")
@PostMapping @PostMapping
public CzgResult<Boolean> add(@RequestBody @Validated PrinterAddDTO printerAddDTO) { public CzgResult<Boolean> add(@RequestBody @Validated PrintMachine printerAddDTO) {
return CzgResult.success(printMachineService.add(StpKit.USER.getShopId(), printerAddDTO)); return CzgResult.success(printMachineService.add(StpKit.USER.getShopId(), printerAddDTO));
} }
@@ -117,7 +100,7 @@ public class PrintMachineController {
*/ */
@SaAdminCheckPermission(parentName = "打印机管理", value = "printer:edit", name = "打印机编辑") @SaAdminCheckPermission(parentName = "打印机管理", value = "printer:edit", name = "打印机编辑")
@PutMapping @PutMapping
public CzgResult<Boolean> edit(@RequestBody @Validated PrinterEditDTO printerEditDTO) { public CzgResult<Boolean> edit(@RequestBody @Validated PrintMachine printerEditDTO) {
return CzgResult.success(printMachineService.edit(StpKit.USER.getShopId(), printerEditDTO)); return CzgResult.success(printMachineService.edit(StpKit.USER.getShopId(), printerEditDTO));
} }

View File

@@ -57,29 +57,24 @@ public class PrintMqListener {
if (orderId == null) { if (orderId == null) {
throw new RuntimeException("订单打印失败未传递orderId"); throw new RuntimeException("订单打印失败未传递orderId");
} }
//该字段表示 网络打印机是否打印订单 本地传参来的
Boolean printOrder = jsonObject.getBoolean("printOrder"); Boolean printOrder = jsonObject.getBoolean("printOrder");
redisService.runFunAndCheckKey(() -> { redisService.runFunAndCheckKey(() -> {
printerHandler.orderHandler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER, null); if (printOrder) {
printerHandler.orderHandler(orderId, PrinterHandler.PrintTypeEnum.ORDER, null);
}
//菜品打印 全是后端
printerHandler.orderHandler(orderId, PrinterHandler.PrintTypeEnum.ONLY_KITCHEN, null);
printerHandler.orderHandler(orderId, PrinterHandler.PrintTypeEnum.ALL_KITCHEN, null);
return null; return null;
}, RedisCst.getLockKey("orderPrint", orderId)); }, RedisCst.getLockKey("orderPrint", orderId));
}); });
} }
/**
* 交班打印
*/
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE})
public void handoverPrint(String id) {
invokeFun(RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, "handoverPrint", "java.order", id, (data) ->
printerHandler.handoverHandler(data));
}
/** @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.OTHER_PRINT_QUEUE})
* 叫号打印 public void otherPrint(Long shopId, Object o, String printTypeEnum) {
*/ PrinterHandler.PrintTypeEnum typeEnum = PrinterHandler.PrintTypeEnum.valueOf(printTypeEnum);
@RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_QUEUE}) printerHandler.otherHandler(shopId, o, typeEnum);
public void callTablePrint(String id) {
invokeFun(RabbitConstants.Queue.CALL_TABLE_QUEUE, "callTable", "java.order", id, (data) ->
printerHandler.callHandler(data));
} }
} }

View File

@@ -70,26 +70,16 @@ public class RabbitConfig {
return BindingBuilder.bind(orderMachinePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE); return BindingBuilder.bind(orderMachinePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE);
} }
//------------------------------------------------------交班打票
//------------------------------------------------------其它打印消息打票
@Bean @Bean
public Queue handoverPrintQueue() { public Queue otherPrintQueue() {
return new Queue(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, true, false, false); return new Queue(activeProfile + "-" + RabbitConstants.Queue.OTHER_PRINT_QUEUE, true, false, false);
} }
@Bean @Bean
public Binding bindingHandoverPrintExchange(Queue handoverPrintQueue, DirectExchange exchange) { public Binding bindingOtherPrintExchange(Queue otherPrintQueue, DirectExchange exchange) {
return BindingBuilder.bind(handoverPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE); return BindingBuilder.bind(otherPrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.OTHER_PRINT_QUEUE);
}
//------------------------------------------------------叫号 打票
@Bean
public Queue callTablePrintQueue() {
return new Queue(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE, true, false, false);
}
@Bean
public Binding bindingCallTablePrintExchange(Queue callTablePrintQueue, DirectExchange exchange) {
return BindingBuilder.bind(callTablePrintQueue).to(exchange).with(activeProfile + "-" + RabbitConstants.Queue.CALL_TABLE_QUEUE);
} }
//------------------------------------------------------订单取消 //------------------------------------------------------订单取消

View File

@@ -14,10 +14,11 @@ public interface RabbitConstants {
public static final String ORDER_STOCK_QUEUE = "order.stock.queue"; public static final String ORDER_STOCK_QUEUE = "order.stock.queue";
public static final String ORDER_REFUND_QUEUE = "order.refund.queue"; public static final String ORDER_REFUND_QUEUE = "order.refund.queue";
public static final String ORDER_CANCEL_QUEUE = "order.cancel.queue"; public static final String ORDER_CANCEL_QUEUE = "order.cancel.queue";
public static final String ORDER_PRINT_QUEUE = "order.print.queue"; public static final String ORDER_PRINT_QUEUE = "order.print.queue";
public static final String ORDER_MACHINE_PRINT_QUEUE = "order.machine.print.queue"; public static final String ORDER_MACHINE_PRINT_QUEUE = "order.machine.print.queue";
public static final String ORDER_HANDOVER_PRINT_QUEUE = "order.handover.print.queue";
public static final String CALL_TABLE_QUEUE = "call.table.print.queue"; public static final String OTHER_PRINT_QUEUE = "other.print.queue";
public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue"; public static final String PRODUCT_INFO_CHANGE_QUEUE = "product.info.change.queue";
public static final String CONS_INFO_CHANGE_QUEUE = "cons.info.change.queue"; public static final String CONS_INFO_CHANGE_QUEUE = "cons.info.change.queue";

View File

@@ -7,6 +7,7 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
@@ -62,37 +63,19 @@ public class RabbitPublisher {
sendMsg(RabbitConstants.Queue.ORDER_PRINT_QUEUE, orderId); sendMsg(RabbitConstants.Queue.ORDER_PRINT_QUEUE, orderId);
} }
} }
/** /**
* 订单打印消息 * 厨房票打印消息
* *
* @param orderId 订单id * @param orderId 订单id
* @param printOrder 是否打印结算单 * @param printOrder 是否打印结算单
*/ */
public void sendKitchenOrderPrintMsg(String orderId, boolean printOrder, String source) { public void sendKitchenOrderPrintMsg(String orderId, boolean printOrder, String source) {
log.info("厨房打印消息, orderId: {}, printOrder: {}, source: {}", orderId, printOrder, source); log.info("厨房菜品单打印消息, orderId: {}, printOrder: {}, source: {}", orderId, printOrder, source);
//厨房票 //厨房票
sendMsg(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, new JSONObject().fluentPut("orderId", orderId).fluentPut("printOrder", printOrder).toString()); sendMsg(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, new JSONObject().fluentPut("orderId", orderId).fluentPut("printOrder", printOrder).toString());
} }
/**
* 退款订单打印消息
*
* @param orderId 订单id
*/
public void sendOrderReturnPrintMsg(String orderId) {
//厨房票
sendMsg(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, new JSONObject().fluentPut("orderId", orderId).fluentPut("printOrder", true).toString());
}
/**
* 交班小票打印消息
*
* @param handoverRecordId 交班记录id
*/
public void sendHandoverPrintMsg(String handoverRecordId) {
sendMsg(RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE, handoverRecordId);
}
/** /**
* 商品信息变动消息 * 商品信息变动消息
* *
@@ -111,15 +94,6 @@ public class RabbitPublisher {
sendMsg(RabbitConstants.Queue.CONS_INFO_CHANGE_QUEUE, shopId); sendMsg(RabbitConstants.Queue.CONS_INFO_CHANGE_QUEUE, shopId);
} }
/**
* 排队叫号小票打印
*
* @param id 叫号队列id
*/
public void printCallNumTicket(Long id) {
sendMsg(RabbitConstants.Queue.CALL_TABLE_QUEUE, id.toString());
}
/** /**
* 1,2,applySmsTemp 模版审核 shop_id,sms_shop_template.id,applySmsTemp * 1,2,applySmsTemp 模版审核 shop_id,sms_shop_template.id,applySmsTemp
* 1,2,sendMarkSms 发送营销短信 shop_id,sms_push_event.id,sendMarkSms * 1,2,sendMarkSms 发送营销短信 shop_id,sms_push_event.id,sendMarkSms
@@ -172,4 +146,25 @@ public class RabbitPublisher {
rabbitTemplate.convertAndSend(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE, activeProfile + "-" + queue, msg); rabbitTemplate.convertAndSend(activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE, activeProfile + "-" + queue, msg);
} }
/**
* 其它类型 打印消息
* STOCK 出入库
* DAY_REPORT 经营日报
* PRODUCT_REPORT 商品报表
* RECHARGE 储值单
* STOCK_CHECK 库存盘点
* HANDOVER 交班单
* CALL 排队取号
* @param printType {@link com.czg.service.order.print.PrinterHandler.PrintTypeEnum}
*/
public void sendOtherPrintMsg(Long shopId, Object data, String printType) {
String exchange = activeProfile + "-" + RabbitConstants.Exchange.CASH_EXCHANGE;
String queueName = activeProfile + "-" + RabbitConstants.Queue.OTHER_PRINT_QUEUE;
Map<String, Object> msg = new HashMap<>();
msg.put("shopId", shopId);
msg.put("data", data);
msg.put("printTypeEnum", printType);
rabbitTemplate.convertAndSend(exchange, queueName, msg);
}
} }

View File

@@ -3,6 +3,7 @@ package com.czg.config;
/** /**
* *
* key常量 * key常量
*
* @author Administrator * @author Administrator
*/ */
public interface RedisCst { public interface RedisCst {
@@ -12,7 +13,6 @@ public interface RedisCst {
String SYS_LOG_KEY = "sys:log:"; String SYS_LOG_KEY = "sys:log:";
/** /**
* key过期监听 * key过期监听
*/ */
@@ -50,11 +50,18 @@ public interface RedisCst {
// 排队取号全局号码 // 排队取号全局号码
String TABLE_CALL_NUMBER = "table:call:number:"; String TABLE_CALL_NUMBER = "table:call:number:";
String PRINT_ORDER_DETAIL = "print:order:detail:";
// 点歌地址url // 点歌地址url
String SONG_URL = "song:"; String SONG_URL = "song:";
class kitchen {
//后厨总单
public static final String ALL = "print:kitchen:all";
//菜品单
public static final String NORMAL = "print:kitchen:normal";
//退菜单
public static final String REFUND_ALL = "print:kitchen:refundAll";
}
static String getLockKey(String sign, Object... args) { static String getLockKey(String sign, Object... args) {
StringBuilder key = new StringBuilder(LOCK_KEY + ":" + sign + ":"); StringBuilder key = new StringBuilder(LOCK_KEY + ":" + sign + ":");
@@ -70,9 +77,31 @@ public interface RedisCst {
return TABLE_CALL_NUMBER + shopId + ":" + callTableId; return TABLE_CALL_NUMBER + shopId + ":" + callTableId;
} }
/**
* 后厨总单
*
* @param machineId 打印机设备id
*/
static String kitchenAll(Long orderId, Long machineId) {
return kitchen.ALL + orderId + ":" + machineId;
}
static String getPrintOrderDetailKey(Long orderId, Long detailId) { /**
return PRINT_ORDER_DETAIL + orderId + ":" + detailId; * 后厨单个菜品单
*
* @param machineId 打印机设备id
*/
static String kitchenNormal(Long orderId, Long machineId, Long detailId) {
return kitchen.NORMAL + orderId + ":" + machineId + ":" + detailId;
}
/**
* 后厨总单
*
* @param machineId 打印机设备id
*/
static String kitchenRefundAll(Long orderId, Long machineId) {
return kitchen.REFUND_ALL + orderId + ":" + machineId;
} }
static String getSongUrlKey(Long shopId) { static String getSongUrlKey(Long shopId) {

View File

@@ -4,16 +4,15 @@ import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.io.Serial;
import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/** /**
* 打印机设备 实体类。 * 打印机设备 实体类。
* *
@@ -21,7 +20,7 @@ import lombok.NoArgsConstructor;
* @since 2025-02-20 * @since 2025-02-20
*/ */
@Data @Data
@Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Table("tb_print_machine") @Table("tb_print_machine")
@@ -30,8 +29,16 @@ public class PrintMachine implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@Id(keyType = KeyType.Auto) @Id(keyType = KeyType.Auto)
private Integer id; private Long id;
/**
* 店铺Id
*/
private Long shopId;
/** /**
* 设备名称 * 设备名称
@@ -39,12 +46,22 @@ public class PrintMachine implements Serializable {
private String name; private String name;
/** /**
* 现在打印机支持USB 和 网络、蓝牙 * 连接方式 USB、云打印、局域网
*/ */
private String connectionType; private String connectionType;
/** /**
* ip地址 * 打印类型 label标签 cash小票
*/
private String printType;
/**
* 打印机品牌 飞鹅/云想印
*/
private String brand;
/**
* ip地址/MAC地址
*/ */
private String address; private String address;
@@ -53,46 +70,6 @@ public class PrintMachine implements Serializable {
*/ */
private String port; private String port;
/**
* 打印类型分类label标签cash小票kitchen出品
*/
private String subType;
/**
* 状态 online
*/
private Integer status;
/**
* 店铺Id
*/
private Long shopId;
/**
* 分类Id
*/
private String categoryIds;
/**
* 现在打印机支持USB 和 网络两种
*/
private String contentType;
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
/**
* 分类
*/
private List<Object> categoryList;
/**
* 排序
*/
private Integer sort;
/** /**
* 小票尺寸 58mm 80mm * 小票尺寸 58mm 80mm
@@ -100,31 +77,58 @@ public class PrintMachine implements Serializable {
private String receiptSize; private String receiptSize;
/** /**
* 分类打印 0-所有 1-部分分类 2-部分商品 * 打印数量
*/
private Integer printNum;
/**
* 打印内容 数组
* GUEST_ORDER("客看单"),PRE_ORDER("预结算单"),ORDER("订单结算单"),RETURN_ORDER("退菜单"),REFUND_ORDER("退款单"),
* ALL_KITCHEN("后厨整单"),ONLY_KITCHEN("后厨分单"),REFUND_KITCHEN("后厨退菜单"),
* HANDOVER("交班单"),CALL("排队取号"),RECHARGE("储值单"),STOCK("出入库单"),STOCK_CHECK("盘点单"),
* PRODUCT_REPORT("商品报表"),DAY_REPORT("经营日报"),DAY_ORDER("日结单")
*/
private String printContentType;
/**
* 打印模式(厨房打印菜品) all整单 /only单个
*/
private String kitchenPrintMode;
/**
* 分类打印 0-所有 1-部分分类
*/ */
private String classifyPrint; private String classifyPrint;
/** /**
* 打印数量 c1m1^2=顾客+商家[2张] m1^1=商家[1张] c1^1顾客[1张] c2m1^3顾客2+商家1[3张] * 分类Id
*/ */
private String printQty; private String categoryIds;
/** /**
* 打印方式 all-全部打印 normal-仅打印结账单「前台」one-仅打印制作单「厨房」 * 0 禁用 1启用
*/ */
private String printMethod; private Integer status;
/** /**
* 打印类型JSON数组 refund-确认退款单 handover-交班单 queue-排队取号 * 媒体声音开关 0关1开
*/
private String printType;
/**
* 媒体音开关 0-关 1-开
*/ */
private Integer volumeSwitch; private Integer volumeSwitch;
/**
* 交班打印机开关 0-关 1-开
*/
private Integer handoverSwitch;
} /**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
/**
* 更新时间
*/
@Column(onUpdateValue = "now()")
private LocalDateTime updateTime;
/**
* 排序
*/
private Integer sort;
}

View File

@@ -51,14 +51,14 @@ public interface HandoverRecordService extends IService<HandoverRecord> {
* *
* @return 交班记录ID * @return 交班记录ID
*/ */
Long handover(); HandoverRecord handover();
/** /**
* 交班打印小票 * 交班打印小票
* *
* @param handoverRecordId 交班记录id * @param record 交班记录
* @param isPrint 是否打印 1-是 0-否 * @param isPrint 是否打印 1-是 0-否
*/ */
void printHandoverReceipt(Long handoverRecordId, Integer isPrint); void printHandoverReceipt(HandoverRecord record, Integer isPrint);
} }

View File

@@ -1,11 +1,7 @@
package com.czg.account.service; package com.czg.account.service;
import com.czg.account.dto.print.PrinterAddDTO;
import com.czg.account.dto.print.PrinterEditDTO;
import com.czg.account.dto.print.PrinterOrderDTO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.czg.account.entity.PrintMachine; import com.czg.account.entity.PrintMachine;
import com.mybatisflex.core.service.IService;
/** /**
* 打印机设备 服务层。 * 打印机设备 服务层。
@@ -15,9 +11,9 @@ import com.czg.account.entity.PrintMachine;
*/ */
public interface PrintMachineService extends IService<PrintMachine> { public interface PrintMachineService extends IService<PrintMachine> {
boolean add(Long shopId, PrinterAddDTO printerAddDTO); boolean add(Long shopId, PrintMachine printMachine);
Boolean edit(Long shopId, PrinterEditDTO printerEditDTO); Boolean edit(Long shopId, PrintMachine printMachine);
} }

View File

@@ -20,11 +20,8 @@ public class OrderInfoPrintDTO implements Serializable {
@NotNull(message = "id不为空") @NotNull(message = "id不为空")
private Long id; private Long id;
/** /**
* 0 菜品和结算单同时打印
* 1 预结算单 * 1 预结算单
* 2 结算单 * 2 结算单
* 3 退菜/退款
* 4 交班
*/ */
@NotNull(message = "打印类型不为空") @NotNull(message = "打印类型不为空")
private Integer type; private Integer type;

View File

@@ -40,9 +40,9 @@ public interface OrderInfoRpcService {
/** /**
* 订单交班回调 发送答应交班小票消息至MQ * 订单交班回调 发送答应交班小票消息至MQ
* *
* @param handoverRecordId 交班记录id * @param record 交班记录id
*/ */
void sendHandoverReceiptPrintMsgToMq(Long handoverRecordId); void sendHandoverReceiptPrintMsgToMq(Long shopId, HandoverRecord record);
/** /**
* 交班售出商品明细 * 交班售出商品明细

View File

@@ -0,0 +1,158 @@
package com.czg.print;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* 经营日报
* @author Administrator
*/
@Data
@Accessors(chain = true)
public class DayReportPrintDTO {
/**
* 店铺名称
*/
private String shopName;
/**
* 操作人
*/
private String operator;
/**
* 统计时间
*/
private String statisticsTime;
/**
* 退款金额
*/
private BigDecimal refundAmount;
/**
* 退菜数量
*/
private Long returnDishCount;
/**
* 营业额
*/
private TurnoverSts turnover;
/**
* 订单
*/
private OrderSts order;
/**
* 数据统计
*/
private Sts sts;
/**
* 营业额 类
*/
@Data
@Accessors(chain = true)
public static class TurnoverSts {
/**
* 营业额
*/
private BigDecimal turnover;
/**
* 微信支付金额
*/
private BigDecimal wechat;
/**
* 支付宝支付金额
*/
private BigDecimal alipay;
/**
* 二维码收款
*/
private BigDecimal selfScan;
/**
* 扫码收款
*/
private BigDecimal barScan;
/**
* 现金收款
*/
private BigDecimal cash;
/**
* 充值
*/
private BigDecimal recharge;
/**
* 挂账
*/
private BigDecimal owed;
/**
* 余额支付
*/
private BigDecimal balance;
}
/**
* 订单 类
*/
@Data
@Accessors(chain = true)
public static class OrderSts {
/**
* 订单金额
*/
private BigDecimal orderAmount;
/**
* 订单总数
*/
private Long orderCount;
}
/**
* 数据统计 类
*/
@Data
@Accessors(chain = true)
public static class Sts {
/**
* 就餐人数
*/
private Long customerCount;
/**
* 客单价
* 实付金额(包含现金支付 包含会员支付 包含挂账)/就餐人数
* 没有具体人数时默认一桌按照1人计算
*/
private BigDecimal avgPayAmount;
/**
* 翻台率
* (订单数-桌台数)/桌台数*100%
*/
private BigDecimal turnoverRate;
/**
* 商品成本
*/
private BigDecimal productCostAmount;
/**
* 毛利率(订单实付金额-商品成本)/订单实付金额*100%
*/
private BigDecimal profitRate;
}
}

View File

@@ -0,0 +1,44 @@
package com.czg.print;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 订单打印实体
* @author ww
*/
@Data
@Accessors(chain = true)
public class OrderPrintDTO {
// 打印标题 结算单/客看单/预结算单 退菜单/退款单
private String printTitle;
private String shopName;
//打印类型 收银-堂食
private String printType;
//台桌区域-台桌号
private String pickupNum;
private String orderNo;
//结账时间
private String tradeDate;
//操作人名称
private String operator;
private String payAmount;
private String originalAmount;
private String payType;
private String remark;
//取餐码
private String outNumber;
private String discountAmount;
private String seatNum;
private String seatAmount;
private String packFee;
// 是否退款单
private boolean isReturn;
//退款单用
private String refundAmount;
//退款方式 现金退款/原路退回
private String refundType;
//退款原因
private String refundReason;
}

View File

@@ -0,0 +1,94 @@
package com.czg.print;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* 商品报表打印实体
*
* @author ww
*/
@Data
@Accessors(chain = true)
public class ProductReportPrintDTO {
/**
* 店铺名称
*/
private String shopName;
/**
* 打印时间
*/
private String printTime;
/**
* 操作人
*/
private String operator;
/**
* 统计时间
*/
private String statisticsTime;
/**
* 总计商品数量
*/
private BigDecimal totalProductCount;
/**
* 总计实收金额
*/
private BigDecimal totalActualAmount;
/**
* 商品明细列表
* 分类名称,商品集合
*/
private Map<String, List<ProductItem>> items;
public ProductItem createProductItem(String productName, BigDecimal number, BigDecimal actualAmount, BigDecimal salesAmount) {
ProductItem item = new ProductItem();
item.setProductName(productName);
item.setNumber(number);
item.setActualAmount(actualAmount);
item.setSalesAmount(salesAmount);
return item;
}
/**
* 商品明细项
*
* @author ww
*/
@Data
@Accessors(chain = true)
public static class ProductItem {
/**
* 商品名称(第二列商品名称)
*/
private String productName;
/**
* 数量(第三列数量)
*/
private BigDecimal number;
/**
* 实收(第四列)
*/
private BigDecimal actualAmount;
/**
* 销售额(第五列)
*/
private BigDecimal salesAmount;
}
}

View File

@@ -0,0 +1,44 @@
package com.czg.print;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 储值单
* @author ww
*/
@Data
@Accessors(chain = true)
public class RechargePrintDTO {
//店铺名称
private String shopName;
private String userId;
private String userName;
private String userPhone;
//支付时间
private LocalDateTime payTime;
//充值金额
private BigDecimal rechargeAmount;
//赠送金额
private BigDecimal giftAmount;
//赠送积分
private BigDecimal giftPoints;
//赠送优惠券 张
private Integer giftCoupon;
//充值后余额
private BigDecimal balance;
//已付金额
private BigDecimal payAmount;
//支付方式
private String payType;
//操作员
private String operator;
//充值编号
private String rechargeId;
}

View File

@@ -0,0 +1,87 @@
package com.czg.print;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* 盘点单打印实体
* @author ww
*/
@Data
@Accessors(chain = true)
public class StockCheckPrintDTO {
/**
* 店铺名称
*/
private String shopName;
/**
* 耗材明细列表
*/
private List<StockCheckItem> items;
/**
* 账存数量
*/
private Integer winLossNumberCount;
/**
* 盈亏金额
*/
private BigDecimal winLossAmount;
/**
* 备注
*/
private String remark;
/**
* 操作员
*/
private String operator;
public StockCheckItem createStockCheckItem(String consName, BigDecimal price, String unit, BigDecimal actualNumber, BigDecimal winLossNumber) {
return new StockCheckItem(consName, price, unit, actualNumber, winLossNumber);
}
/**
* 入库耗材明细
*
* @author ww
*/
@Data
@Accessors(chain = true)
@AllArgsConstructor
public static class StockCheckItem {
/**
* 耗材名称
*/
private String consName;
/**
* 单价
*/
private BigDecimal price;
/**
* 单位
*/
private String unit;
/**
* 实际数
*/
private BigDecimal actualNumber;
/**
* 盈亏数
*/
private BigDecimal winLossNumber;
}
}

View File

@@ -0,0 +1,101 @@
package com.czg.print;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* 入库打印单
*
* @author ww
*/
@Data
@Accessors(chain = true)
public class StockPrintDTO {
//IN OUT
private String type;
/**
* 店铺名称
*/
private String shopName;
/**
* 出入库时间
*/
private LocalDateTime inStockTime;
/**
* 出入库耗材明细列表
*/
private List<InStockItem> items;
/**
* 耗材总种类数
*/
private Integer consCount;
/**
* 出入库总数量
*/
private BigDecimal stockNumberCount;
/**
* 总金额
*/
private BigDecimal amountCount;
/**
* 操作员
*/
private String operator;
/**
* 打印时间
*/
private LocalDateTime printTime;
public InStockItem createInStockItem(String consName, String unit, BigDecimal stockNumber, BigDecimal amount) {
InStockItem item = new InStockItem();
item.setConsName(consName);
item.setUnit(unit);
item.setStockNumber(stockNumber);
item.setAmount(amount);
return item;
}
/**
* 入库耗材明细
*
* @author ww
*/
@Data
@Accessors(chain = true)
public static class InStockItem {
/**
* 耗材名称
*/
private String consName;
/**
* 库存单位
*/
private String unit;
/**
* 出入数量
*/
private BigDecimal stockNumber;
/**
* 金额
*/
private BigDecimal amount;
}
}

View File

@@ -31,6 +31,9 @@ public class ConsCheckStockParam implements Serializable {
*/ */
@NotBlank(message = "耗材名称不能为空", groups = DefaultGroup.class) @NotBlank(message = "耗材名称不能为空", groups = DefaultGroup.class)
private String conName; private String conName;
@NotBlank(message = "操作员不能为空", groups = DefaultGroup.class)
private String operator;
/** /**
* 账存数量 * 账存数量
*/ */

View File

@@ -69,4 +69,9 @@ public class ConsInOutStockHeadParam implements Serializable {
* 未入库信息 * 未入库信息
*/ */
private List<SaleOrderDTO.Item> unInCons; private List<SaleOrderDTO.Item> unInCons;
/**
* 操作员
*/
private String operator;
} }

View File

@@ -221,7 +221,7 @@ public class CallTableServiceImpl extends ServiceImpl<CallTableMapper, CallTable
callQueueService.save(callQueue); callQueueService.save(callQueue);
// 打印排号票信息 // 打印排号票信息
rabbitPublisher.printCallNumTicket(callQueue.getId()); rabbitPublisher.sendOtherPrintMsg(callQueue.getShopId(), callQueue, "CALL");
return new CallTableNumDTO().setTableName(callTable.getName()).setTableNote(callTable.getNote()) return new CallTableNumDTO().setTableName(callTable.getName()).setTableNote(callTable.getNote())
.setCallNum(callQueue.getCallNum()).setQueueId(callQueue.getId()); .setCallNum(callQueue.getCallNum()).setQueueId(callQueue.getId());
@@ -341,6 +341,7 @@ public class CallTableServiceImpl extends ServiceImpl<CallTableMapper, CallTable
} }
return 1; return 1;
} }
private String getStrByState(Integer state) { private String getStrByState(Integer state) {
return switch (state) { return switch (state) {
case -1 -> "已取消"; case -1 -> "已取消";

View File

@@ -11,7 +11,6 @@ import com.alibaba.fastjson2.JSONWriter;
import com.czg.account.dto.HandoverRecordDTO; import com.czg.account.dto.HandoverRecordDTO;
import com.czg.account.entity.HandoverRecord; import com.czg.account.entity.HandoverRecord;
import com.czg.account.service.HandoverRecordService; import com.czg.account.service.HandoverRecordService;
import com.czg.account.vo.HandoverCategoryListVo;
import com.czg.account.vo.HandoverProductListVo; import com.czg.account.vo.HandoverProductListVo;
import com.czg.account.vo.HandoverTotalVo; import com.czg.account.vo.HandoverTotalVo;
import com.czg.constants.SystemConstants; import com.czg.constants.SystemConstants;
@@ -117,20 +116,20 @@ public class HandoverRecordServiceImpl extends ServiceImpl<HandoverRecordMapper,
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long handover() { public HandoverRecord handover() {
HandoverTotalVo data = totalHandoverData(); HandoverTotalVo data = totalHandoverData();
HandoverRecord entity = BeanUtil.copyProperties(data, HandoverRecord.class); HandoverRecord entity = BeanUtil.copyProperties(data, HandoverRecord.class);
entity.setCategoryData(JSON.toJSONString(data.getCategoryList(), JSONWriter.Feature.WriteMapNullValue)); entity.setCategoryData(JSON.toJSONString(data.getCategoryList(), JSONWriter.Feature.WriteMapNullValue));
List<HandoverProductListVo> productData = data.getDetailList(); List<HandoverProductListVo> productData = data.getDetailList();
entity.setProductData(JSON.toJSONString(productData, JSONWriter.Feature.WriteMapNullValue)); entity.setProductData(JSON.toJSONString(productData, JSONWriter.Feature.WriteMapNullValue));
super.updateById(entity); super.updateById(entity);
return entity.getId(); return entity;
} }
@Override @Override
public void printHandoverReceipt(Long handoverRecordId, Integer isPrint) { public void printHandoverReceipt(HandoverRecord record, Integer isPrint) {
if (isPrint == SystemConstants.OneZero.ONE) { if (isPrint == SystemConstants.OneZero.ONE) {
orderInfoRpcService.sendHandoverReceiptPrintMsgToMq(handoverRecordId); orderInfoRpcService.sendHandoverReceiptPrintMsgToMq(record.getShopId(), record);
} }
} }
} }

View File

@@ -3,8 +3,6 @@ package com.czg.service.account.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.czg.account.dto.print.PrinterAddDTO;
import com.czg.account.dto.print.PrinterEditDTO;
import com.czg.account.entity.PrintMachine; import com.czg.account.entity.PrintMachine;
import com.czg.account.service.PrintMachineService; import com.czg.account.service.PrintMachineService;
import com.czg.exception.CzgException; import com.czg.exception.CzgException;
@@ -20,32 +18,36 @@ import org.apache.dubbo.config.annotation.DubboService;
* @since 2025-02-20 * @since 2025-02-20
*/ */
@DubboService @DubboService
public class PrintMachineServiceImpl extends ServiceImpl<PrintMachineMapper, PrintMachine> implements PrintMachineService{ public class PrintMachineServiceImpl extends ServiceImpl<PrintMachineMapper, PrintMachine> implements PrintMachineService {
@Override @Override
public boolean add(Long shopId, PrinterAddDTO dto) { public boolean add(Long shopId, PrintMachine dto) {
//分类打印选择部分打印时必传JsonArray字符串数据 如:[{"id":125,"name":"意式咖啡"},{"id":127,"name":"饮品"}] //分类打印选择部分打印时必传JsonArray字符串数据 如:[{"id":125,"name":"意式咖啡"},{"id":127,"name":"饮品"}]
if ("1".equals(dto.getClassifyPrint()) || "2".equals(dto.getClassifyPrint())) { if ("1".equals(dto.getClassifyPrint())) {
if (StrUtil.isBlank(dto.getCategoryList())) { if (StrUtil.isBlank(dto.getCategoryIds()) || dto.getCategoryIds().length() < 3) {
throw new CzgException("分类打印选择部分打印时,必须勾选需要部分打印的菜品"); throw new CzgException("分类打印选择部分打印时,必须勾选需要部分打印的菜品");
} }
if (!JSONUtil.isTypeJSONArray(dto.getCategoryList())) { if (!JSONUtil.isTypeJSONArray(dto.getCategoryIds())) {
throw new CzgException("传递的部分打印菜品数据不合法"); throw new CzgException("传递的部分打印菜品数据不合法");
} }
if (StrUtil.isBlank(dto.getCategoryIds())) {
throw new CzgException("分类打印选择部分打印时传递的部分打印菜品id数据不能为空");
}
} else { } else {
dto.setCategoryIds(null); dto.setCategoryIds(null);
dto.setCategoryList(null);
} }
PrintMachine entity = BeanUtil.copyProperties(dto, PrintMachine.class); return save(dto);
entity.setShopId(shopId);
return save(entity);
} }
@Override @Override
public Boolean edit(Long shopId, PrinterEditDTO printerEditDTO) { public Boolean edit(Long shopId, PrintMachine printerEditDTO) {
if ("1".equals(printerEditDTO.getClassifyPrint())) {
if (StrUtil.isBlank(printerEditDTO.getCategoryIds()) || printerEditDTO.getCategoryIds().length() < 3) {
throw new CzgException("分类打印选择部分打印时,必须勾选需要部分打印的菜品");
}
if (!JSONUtil.isTypeJSONArray(printerEditDTO.getCategoryIds())) {
throw new CzgException("传递的部分打印菜品数据不合法");
}
} else {
printerEditDTO.setCategoryIds(null);
}
PrintMachine printMachine = getOne(new QueryWrapper().eq(PrintMachine::getShopId, shopId).eq(PrintMachine::getId, printerEditDTO.getId())); PrintMachine printMachine = getOne(new QueryWrapper().eq(PrintMachine::getShopId, shopId).eq(PrintMachine::getId, printerEditDTO.getId()));
if (printMachine == null) { if (printMachine == null) {
throw new CzgException("打印机不存在"); throw new CzgException("打印机不存在");

View File

@@ -1,18 +1,14 @@
package com.czg.service.order.print; package com.czg.service.order.print;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.UnicodeUtil; import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil; import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.czg.account.dto.HandoverRecordDTO; import com.czg.account.dto.HandoverRecordDTO;
import com.czg.account.entity.PrintMachine; import com.czg.account.entity.PrintMachine;
import com.czg.account.entity.ShopInfo;
import com.czg.order.entity.OrderDetail; import com.czg.order.entity.OrderDetail;
import com.czg.order.entity.OrderInfo; import com.czg.order.entity.OrderInfo;
import com.czg.service.order.enums.OrderStatusEnums; import com.czg.print.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
@@ -22,9 +18,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -67,57 +61,71 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
} }
@Override @Override
protected void normalDishesPrint(String operator, OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) { protected void onlyKitchenPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) {
String buildDishPrintData = buildDishPrintData(false, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(), String buildDishPrintData = buildOnlyKitchenPrintData(getPickupNum(orderInfo), orderDetail);
orderDetail.getNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent());
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) { if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
} }
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(orderInfo.getId(), machine, "新订", buildDishPrintData, resp); printMachineLogService.save(orderInfo.getId(), machine, "后厨商品", buildDishPrintData, resp);
} }
@Override @Override
protected void returnDishesPrint(String operator, OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) { public OrderPrintDTO allKitchenPrint(OrderInfo orderInfo, List<OrderDetail> orderDetails, PrintMachine machine) {
String buildDishPrintData = buildDishPrintData(true, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(), OrderPrintDTO orderPrintDTO = super.allKitchenPrint(orderInfo, orderDetails, machine);
orderDetail.getReturnNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent()); String buildDishPrintData = buildAllKitchenPrintData(orderPrintDTO, orderDetails);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1"); if (1 == machine.getVolumeSwitch()) {
printMachineLogService.save(orderInfo.getId(), machine, "厨房退菜", buildDishPrintData, resp); voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
}
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(orderInfo.getId(), machine, "后厨总单", buildDishPrintData, resp);
return null;
} }
@Override @Override
public PrintInfoDTO returnOrderPrint(String printTitle,String operator, String refundAmount, String refundReason, String refundType, public OrderPrintDTO returnKitchenPrint(String operator, OrderInfo orderInfo, List<OrderDetail> orderDetail, PrintMachine machine) {
OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { OrderPrintDTO orderPrintDTO = super.returnKitchenPrint(operator, orderInfo, orderDetail, machine);
PrintInfoDTO printInfoDTO = super.returnOrderPrint(printTitle,operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList); String buildDishPrintData = buildAllKitchenPrintData(orderPrintDTO, orderDetail);
String data = buildRefundOrderPrintData(printInfoDTO, detailList); String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"退菜消息,请及时处理\"}";
}
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(orderInfo.getId(), machine, "后厨退菜", buildDishPrintData, resp);
return null;
}
@Override
public OrderPrintDTO returnOrderPrint(String printTitle, String operator, String refundAmount, String refundReason, String refundType,
OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
OrderPrintDTO orderPrintDTO = super.returnOrderPrint(printTitle, operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList);
String data = buildRefundOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "退款单"); sendOrderPrint(data, orderInfo.getId(), machine, "退款单");
return null; return null;
} }
@Override @Override
public PrintInfoDTO guestOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { public OrderPrintDTO guestOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = super.guestOrderPrint(orderInfo, machine, detailList); OrderPrintDTO orderPrintDTO = super.guestOrderPrint(orderInfo, machine, detailList);
String data = buildGuestOrderPrintData(printInfoDTO, detailList); String data = buildGuestOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "客看单"); sendOrderPrint(data, orderInfo.getId(), machine, "客看单");
return null; return null;
} }
@Override @Override
public PrintInfoDTO preOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { public OrderPrintDTO preOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = super.preOrderPrint(orderInfo, machine, detailList); OrderPrintDTO orderPrintDTO = super.preOrderPrint(orderInfo, machine, detailList);
String data = buildOrderPrintData(printInfoDTO, detailList); String data = buildOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "预结算单"); sendOrderPrint(data, orderInfo.getId(), machine, "预结算单");
return null; return null;
} }
@Override @Override
public PrintInfoDTO orderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { public OrderPrintDTO orderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = super.orderPrint(orderInfo, machine, detailList); OrderPrintDTO orderPrintDTO = super.orderPrint(orderInfo, machine, detailList);
String data = buildOrderPrintData(printInfoDTO, detailList); String data = buildOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "结算单"); sendOrderPrint(data, orderInfo.getId(), machine, "结算单");
return null; return null;
@@ -130,15 +138,55 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一条新的排号记录\"}"; voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一条新的排号记录\"}";
} }
String data = buildCallTicketData(shopName, tableName, callNum, preNum, codeUrl, shopNote, takeTime); String data = buildCallTicketData(shopName, tableName, callNum, preNum, codeUrl, shopNote, takeTime);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, "1"); String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "叫号单", data, resp); printMachineLogService.save(machine, "叫号单", data, resp);
} }
@Override
protected void stockPrint(PrintMachine machine, StockPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildStockData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "IN".equals(record.getType()) ? "入库单" : "出库单", data, resp);
}
@Override
protected void dayReportPrint(PrintMachine machine, DayReportPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildDayReportData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "经营日报单", data, resp);
}
@Override
protected void productReportPrint(PrintMachine machine, ProductReportPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildProductReportData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "商品报表单", data, resp);
}
@Override
protected void rechargePrint(PrintMachine machine, RechargePrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildRechargeData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "储值单", data, resp);
}
@Override
protected void stockCheckPrint(PrintMachine machine, StockCheckPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildStockCheckData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "盘点单", data, resp);
}
@Override @Override
protected void handoverPrint(PrintMachine machine, HandoverRecordDTO record) { protected void handoverPrint(PrintMachine machine, HandoverRecordDTO record) {
String string = buildHandoverData(record); String string = buildHandoverData(record);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
sendPrintRequest(machine.getAddress(), string, voiceJson, "1"); sendPrintRequest(machine.getAddress(), string, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
} }
/** /**
@@ -153,11 +201,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
if (1 == machine.getVolumeSwitch()) { if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
} }
String printerNum = "1"; String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
if (StrUtil.isNotBlank(machine.getPrintQty())) {
printerNum = machine.getPrintQty().split("\\^")[1];
}
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum);
printMachineLogService.save(orderId, machine, bizType, data, resp); printMachineLogService.save(orderId, machine, bizType, data, resp);
} }
@@ -244,20 +288,4 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
} }
return msg; return msg;
} }
/**
* 计算优惠金额:优先使用 discountAllAmount如果为 null 则用原价 - 实付计算
*/
private String calculateDiscountAmount(OrderInfo orderInfo) {
if (orderInfo.getDiscountAllAmount() != null) {
return orderInfo.getDiscountAllAmount().toPlainString();
}
// 兜底计算:原价 + 餐位费 + 打包费 - 实付
BigDecimal originalTotal = orderInfo.getOriginAmount()
.add(orderInfo.getSeatAmount() != null ? orderInfo.getSeatAmount() : BigDecimal.ZERO)
.add(orderInfo.getPackFee() != null ? orderInfo.getPackFee() : BigDecimal.ZERO);
BigDecimal discount = originalTotal.subtract(orderInfo.getPayAmount());
return discount.compareTo(BigDecimal.ZERO) >= 0 ? discount.toPlainString() : "0.00";
}
} }

View File

@@ -1,42 +1,56 @@
package com.czg.service.order.print; package com.czg.service.order.print;
import org.springframework.context.annotation.Bean; import com.czg.exception.CzgException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* 打印机责任链初始化 * 打印机责任链初始化
*
* @author Administrator * @author Administrator
*/ */
@Slf4j
@Configuration @Configuration
public class PrintConfig { public class PrintConfig {
@Resource @Resource
private List<PrinterHandler> printers; private ApplicationContext applicationContext;
// 直接使用实例变量,不需要静态
private Map<String, PrinterHandler> printerMap;
// 初始化责任链
@PostConstruct @PostConstruct
public void initChain() { public void init() {
// 检查打印处理器列表是否为空 Map<String, PrinterHandler> printers = applicationContext.getBeansOfType(PrinterHandler.class);
if (printers != null && !printers.isEmpty()) { printerMap = new ConcurrentHashMap<>();
for (int i = 0; i < printers.size() - 1; i++) {
// 设置当前处理器的下一个处理器 printers.forEach((beanName, printer) -> {
printers.get(i).setNextPrinter(printers.get(i + 1)); String brand = printer.printerBrand;
if (brand != null && !brand.trim().isEmpty()) {
printerMap.put(brand, printer);
} }
});
log.info("已注册打印机: {}", printerMap.keySet());
}
/**
* 获取打印机
*/
public PrinterHandler getPrinter(String key) {
PrinterHandler printer = printerMap.get(key);
if (printer == null) {
throw new CzgException("未找到打印机: " + key);
} }
return printer;
} }
@Bean
@Primary
public PrinterHandler printerHandler() {
// 返回责任链的起始处理器
return printers.getFirst();
}
} }

View File

@@ -1,6 +1,6 @@
package com.czg.service.order.print; package com.czg.service.order.print;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
@@ -9,6 +9,8 @@ import com.czg.account.dto.HandoverRecordDTO;
import com.czg.account.dto.PrintOrderDetailDTO; import com.czg.account.dto.PrintOrderDetailDTO;
import com.czg.account.entity.*; import com.czg.account.entity.*;
import com.czg.account.service.*; import com.czg.account.service.*;
import com.czg.exception.CzgException;
import com.czg.print.*;
import com.czg.config.RedisCst; import com.czg.config.RedisCst;
import com.czg.constants.ParamCodeCst; import com.czg.constants.ParamCodeCst;
import com.czg.market.service.OrderInfoService; import com.czg.market.service.OrderInfoService;
@@ -25,13 +27,11 @@ import com.czg.service.RedisService;
import com.czg.service.order.enums.OrderStatusEnums; import com.czg.service.order.enums.OrderStatusEnums;
import com.czg.system.dto.SysParamsDTO; import com.czg.system.dto.SysParamsDTO;
import com.czg.system.service.SysParamsService; import com.czg.system.service.SysParamsService;
import com.czg.utils.FunUtils;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
@@ -48,10 +48,9 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
@ToString @ToString
public abstract class PrinterHandler { public abstract class PrinterHandler {
@Setter public String printerBrand;
protected PrinterHandler nextPrinter; @Resource
protected String printerBrand; protected PrintConfig printConfig;
@Resource @Resource
protected RestTemplate restTemplate; protected RestTemplate restTemplate;
@Resource @Resource
@@ -88,157 +87,206 @@ public abstract class PrinterHandler {
@Getter @Getter
public enum PrintTypeEnum { public enum PrintTypeEnum {
HANDOVER("交班", "handover"), GUEST_ORDER("客看单"),
PRE_ORDER("预结算单"),
ORDER("订单结算单"),
RETURN_ORDER("退菜单"),
REFUND_ORDER("退款单"),
ONE_AND_ORDER("菜品和结算单同时打印", "oneAndOrder"), ALL_KITCHEN("后厨整单"),
PRE_ORDER("预结算单", "preOrder"), ONLY_KITCHEN("后厨分单"),
ORDER("订单结算单", "order"), REFUND_KITCHEN("后厨退菜单"),
GUEST_ORDER("客看单", "guestOrder"),
RETURN_FOOD("退菜", "returnFood"), HANDOVER("交班单"),
RETURN_ORDER("退单", "returnOrder"), CALL("排队取号"),
RECHARGE("储值单"),
STOCK("出入库单"),
STOCK_CHECK("盘点单"),
PRODUCT_REPORT("商品报表"),
DAY_REPORT("经营日报"),
DAY_ORDER("日结单");
ONE("菜品", "one"),
CALL("叫号", "call");
private final String name; private final String name;
private final String code;
PrintTypeEnum(String name, String code) { PrintTypeEnum(String name) {
this.name = name; this.name = name;
this.code = code;
} }
} }
@Data
@Accessors(chain = true)
public static class PrintDetailInfo {
private boolean isPrint;
// private boolean isReturn;
private long orderId;
private long detailId;
private BigDecimal printNum;
private BigDecimal printReturnNum;
}
@Data
@Accessors(chain = true)
public static class PrintInfoDTO {
private long count;
// 打印标题 结算单/客看单/预结算单 退菜单/退款单
private String printTitle;
private String shopName;
//打印类型 收银-堂食
private String printType;
//台桌区域-台桌号
private String pickupNum;
private String orderNo;
//结账时间
private String tradeDate;
//操作人名称
private String operator;
private String payAmount;
private String originalAmount;
//余额
// private String balance;
private String payType;
private String remark;
//取餐码
private String outNumber;
private String discountAmount;
// private String discountRadio;
// private String orderNum;
private String seatNum;
private String seatAmount;
private String packFee;
// 是否退款单
private boolean isReturn;
//退款单用
private String refundAmount;
//退款方式 现金退款/原路退回
private String refundType;
//退款原因
private String refundReason;
}
public PrinterHandler(String printerBrand) { public PrinterHandler(String printerBrand) {
this.printerBrand = printerBrand; this.printerBrand = printerBrand;
} }
/**
* 处理订单打印
*
* @param data 传递的数据
* @param printTypeEnum GUEST_ORDER ORDER PRE_ORDER ONLY_KITCHEN ALL_KITCHEN
*/
public void orderHandler(String data, PrintTypeEnum printTypeEnum, Integer placeNum) {
OrderInfo orderInfo = orderInfoService.getById(data);
if (orderInfo == null) {
throw new RuntimeException("订单打印失败,订单不存在");
}
List<OrderDetail> orderDetailList = new ArrayList<>();
orderDetailList = switch (printTypeEnum) {
case PrintTypeEnum.GUEST_ORDER -> {
orderInfo.setPlaceNum(placeNum);
yield orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()).eq(OrderDetail::getPlaceNum, placeNum));
}
case PrintTypeEnum.ORDER, PrintTypeEnum.PRE_ORDER, PrintTypeEnum.ONLY_KITCHEN, PrintTypeEnum.ALL_KITCHEN ->
orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
default -> orderDetailList;
};
for (PrintMachine machine : getPrintMachine(orderInfo.getShopId(), printTypeEnum)) {
PrinterHandler printer = printConfig.getPrinter(machine.getBrand());
redisService.set("order:print:" + orderInfo.getId(), "", 180);
switch (printTypeEnum) {
case PrintTypeEnum.GUEST_ORDER:
log.info("准备开始打印客看订单");
printer.guestOrderPrint(orderInfo, machine, orderDetailList);
break;
case PrintTypeEnum.ORDER:
log.info("准备开始打印订单");
printer.orderPrint(machine, orderInfo, orderDetailList);
break;
case PrintTypeEnum.PRE_ORDER:
log.info("准备开始打印预结算订单");
printer.preOrderPrint(machine, orderInfo, orderDetailList);
break;
case PrintTypeEnum.ONLY_KITCHEN:
// 判断订单是否是先付费或者已结算
if (!"after-pay".equals(orderInfo.getPayMode()) && (OrderStatusEnums.UNPAID.getCode().equals(orderInfo.getStatus()) || OrderStatusEnums.CANCELLED.getCode().equals(orderInfo.getStatus()))) {
log.warn("此订单未支付, 订单信息: {}", orderInfo.getId());
}
List<OrderDetail> tbOrderDetailList = getCanPrintOrderDetails(machine, orderInfo.getId(), orderDetailList);
if (CollUtil.isEmpty(tbOrderDetailList)) {
log.info("此订单无打印菜品, 订单信息: {}", orderInfo.getId());
break;
}
log.info("准备开始打印菜品单");
//后厨单菜品
tbOrderDetailList.forEach(item -> {
Boolean b = redisService.hasKey(RedisCst.kitchenNormal(orderInfo.getId(), machine.getId(), item.getId()));
if (!b) {
FunUtils.safeRunVoid(() -> onlyKitchenPrint(orderInfo, item, machine),
"订单id:{} ,后厨分单打印失败", orderInfo.getId());
// 保存已打印信息
redisService.set(RedisCst.kitchenNormal(orderInfo.getId(), machine.getId(), item.getId()), "", 180);
}
});
break;
case PrintTypeEnum.ALL_KITCHEN:
Boolean exit = redisService.hasKey(RedisCst.kitchenAll(orderInfo.getId(), machine.getId()));
if (exit) {
break;
}
// 判断订单是否是先付费或者已结算
if (!"after-pay".equals(orderInfo.getPayMode()) && (OrderStatusEnums.UNPAID.getCode().equals(orderInfo.getStatus()) || OrderStatusEnums.CANCELLED.getCode().equals(orderInfo.getStatus()))) {
log.warn("此订单未支付, 订单信息: {}", orderInfo.getId());
}
List<OrderDetail> allOrderDetailList = getCanPrintOrderDetails(machine, orderInfo.getId(), orderDetailList);
if (CollUtil.isEmpty(allOrderDetailList)) {
log.info("此订单无打印菜品, 订单信息: {}", orderInfo.getId());
break;
}
log.info("准备开始打印后厨整单");
printer.allKitchenPrint(orderInfo, allOrderDetailList, machine);
redisService.set(RedisCst.kitchenAll(orderInfo.getId(), machine.getId()), "", 180);
break;
}
}
}
/**
* 处理其它打印
*
* @param data 传递的数据
* @param printTypeEnum IN_STOCK DAY_REPORT PRODUCT_REPORT RECHARGE STOCK_CHECK
*/
public void otherHandler(Long shopId, Object data, PrintTypeEnum printTypeEnum) {
if (shopId == null || Objects.isNull(data)) {
log.info("otherHandler 打印数据为空, shopId: {}, data: {}", shopId, data);
return;
}
switch (printTypeEnum) {
case PrintTypeEnum.STOCK:
getPrintMachine(shopId, printTypeEnum)
.forEach(machine -> printConfig.getPrinter(machine.getBrand()).stockPrint(machine, (StockPrintDTO) data));
break;
case PrintTypeEnum.DAY_REPORT:
getPrintMachine(shopId, printTypeEnum)
.forEach(machine -> printConfig.getPrinter(machine.getBrand()).dayReportPrint(machine, (DayReportPrintDTO) data));
break;
case PrintTypeEnum.PRODUCT_REPORT:
getPrintMachine(shopId, printTypeEnum)
.forEach(machine -> printConfig.getPrinter(machine.getBrand()).productReportPrint(machine, (ProductReportPrintDTO) data));
break;
case PrintTypeEnum.RECHARGE:
getPrintMachine(shopId, printTypeEnum)
.forEach(machine -> printConfig.getPrinter(machine.getBrand()).rechargePrint(machine, (RechargePrintDTO) data));
break;
case PrintTypeEnum.STOCK_CHECK:
getPrintMachine(shopId, printTypeEnum)
.forEach(machine -> printConfig.getPrinter(machine.getBrand()).stockCheckPrint(machine, (StockCheckPrintDTO) data));
break;
case PrintTypeEnum.HANDOVER:
log.info("准备开始打印交班");
getPrintMachine(shopId, printTypeEnum)
.forEach(machine -> printConfig.getPrinter(machine.getBrand()).handoverPrint(machine, (HandoverRecordDTO) data));
break;
case PrintTypeEnum.CALL:
log.info("准备开始打印叫号单");
getPrintMachine(shopId, printTypeEnum)
.forEach(machine -> printConfig.getPrinter(machine.getBrand()).callNumPrintBefore(machine, (CallQueue) data));
break;
default:
throw new CzgException("otherHandler 未知打印类型");
}
}
/** /**
* 获取可用打印机 * 获取可用打印机
* *
* @param shopId 店铺id * @param shopId 店铺id
* @param subType 打印类型分类label标签 cash小票 kitchen出品 * @param contentType GUEST_ORDER("客看单"),
* @param printMethod 打印方式 all-全部打印 normal-仅打印结账单「前台」one-仅打印制作单「厨房」 * PRE_ORDER("预结算单"),
* @param printType 打印类型JSON数组 refund-确认退款单 handover-交班单 queue-排队取号 * ORDER("订单结算单"),
* RETURN_ORDER("退菜单"),
* REFUND_ORDER("退款单"),
* <p>
* ALL_KITCHEN("后厨整单"),
* ONLY_KITCHEN("后厨分单"),
* REFUND_KITCHEN("后厨退菜单"),
* <p>
* HANDOVER("交班单"),
* CALL("排队取号"),
* RECHARGE("储值单"),
* STOCK("出入库单"),
* STOCK_CHECK("盘点单"),
* PRODUCT_REPORT("商品报表"),
* DAY_REPORT("经营日报"),
* DAY_ORDER("日结单");
* @return 打印机列表 * @return 打印机列表
*/ */
private List<PrintMachine> getPrintMachine(Long shopId, String subType, String printMethod, String printType) { private List<PrintMachine> getPrintMachine(Long shopId, PrintTypeEnum contentType) {
QueryWrapper wrapper = new QueryWrapper() QueryWrapper wrapper = new QueryWrapper()
.eq(PrintMachine::getStatus, 1) .eq(PrintMachine::getStatus, 1)
.eq(PrintMachine::getShopId, shopId) .eq(PrintMachine::getShopId, shopId)
.eq(PrintMachine::getSubType, subType) .eq(PrintMachine::getPrintType, "cash")
.eq(PrintMachine::getConnectionType, "网络"); .like(PrintMachine::getPrintContentType, contentType)
.eq(PrintMachine::getConnectionType, "云打印");
if (StrUtil.isNotEmpty(printMethod)) {
List<String> arrayList = switch (printMethod) {
case "all" -> Arrays.asList("one", "normal", "all");
case "one" -> Arrays.asList("one", "all");
case "normal" -> Arrays.asList("normal", "all");
default -> new ArrayList<>();
};
if (!arrayList.isEmpty()) {
wrapper.in(PrintMachine::getPrintMethod, arrayList);
}
}
if ("callTicket".equals(printType)) {
printType = "queue";
}
if (StrUtil.isNotEmpty(printType)) {
wrapper.like(PrintMachine::getPrintType, printType);
}
List<PrintMachine> list = printMachineService.list(wrapper); List<PrintMachine> list = printMachineService.list(wrapper);
if (list.isEmpty()) { if (list.isEmpty()) {
log.error("店铺未配置打印机店铺id: {}", shopId); log.error("店铺未配置打印机店铺id: {}", shopId);
return list; return list;
} }
log.info("打印机列表: {}", list); log.info("打印机列表: {}", list);
return list; return list;
} }
/**
* 处理订单打印
*
* @param data 传递的数据
* @param printTypeEnum order preOrder one
*/
public void orderHandler(String data, PrintTypeEnum printTypeEnum, Integer placeNum) {
String printMethod;
OrderInfo orderInfo = orderInfoService.getById(data);
if (orderInfo == null) {
throw new RuntimeException("订单打印失败,订单不存在");
}
switch (printTypeEnum) {
case PrintTypeEnum.GUEST_ORDER:
case PrintTypeEnum.PRE_ORDER:
case PrintTypeEnum.ORDER:
printMethod = "normal";
break;
case PrintTypeEnum.ONE:
printMethod = "one";
break;
case PrintTypeEnum.ONE_AND_ORDER:
printMethod = "all";
break;
default:
throw new RuntimeException("未知打印类型");
}
getPrintMachine(orderInfo.getShopId(), "cash", printMethod, "").forEach(machine -> {
handleRequest(machine, placeNum, orderInfo, printTypeEnum);
});
}
/** /**
* 处理退菜退款订单打印 * 处理退菜退款订单打印
@@ -253,269 +301,69 @@ public abstract class PrinterHandler {
*/ */
public void refundOrderHandler(String printTitle, String operator, String refundAmount, String refundReason, String refundType, public void refundOrderHandler(String printTitle, String operator, String refundAmount, String refundReason, String refundType,
OrderInfo orderInfo, List<OrderDetail> detailList) { OrderInfo orderInfo, List<OrderDetail> detailList) {
getPrintMachine(orderInfo.getShopId(), "cash", "normal", "").forEach(machine -> { //前台退菜单
refundHandleRequest(machine, printTitle, operator, refundAmount, refundReason, refundType, orderInfo, detailList); if ("退菜单".equals(printTitle)) {
getPrintMachine(orderInfo.getShopId(), PrintTypeEnum.RETURN_ORDER).forEach(machine ->
printConfig.getPrinter(machine.getBrand()).returnOrderPrint(printTitle, operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList));
} else if ("退款单".equals(printTitle)) {
getPrintMachine(orderInfo.getShopId(), PrintTypeEnum.REFUND_ORDER).forEach(machine ->
printConfig.getPrinter(machine.getBrand()).returnOrderPrint(printTitle, operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList));
} else {
log.error("未知的前台退款打印类型: {}", printTitle);
}
}
/**
* 处理退菜退款订单打印
*/
public void kitchenRefundAllHandler(String operator, OrderInfo orderInfo, List<OrderDetail> detailList) {
//后厨退菜单
getPrintMachine(orderInfo.getShopId(), PrintTypeEnum.REFUND_KITCHEN).forEach(machine -> {
Boolean isPrint = redisService.hasKey(RedisCst.kitchenRefundAll(orderInfo.getId(), machine.getId()));
if (!isPrint) {
printConfig.getPrinter(machine.getBrand()).returnKitchenPrint(operator, orderInfo, detailList, machine);
redisService.set(RedisCst.kitchenRefundAll(orderInfo.getId(), machine.getId()), "", 180);
}
}); });
} }
/**
* 叫号打印
*
* @param data 传递的数据
*/
public void callHandler(String data) {
CallQueue queue = callQueueService.getById(data); protected List<OrderDetail> getCanPrintOrderDetails(PrintMachine machine, Long orderId, List<OrderDetail> tbOrderDetailList) {
if (queue == null) { Set<Long> canPrintProSet = new HashSet<>();
throw new RuntimeException("叫号信息不存在: " + data); boolean partPrint = false;
if ("1".equals(machine.getClassifyPrint())) {
partPrint = true;
List categoryIds = JSONObject.parseObject(StrUtil.emptyToDefault(machine.getCategoryIds(), "[]"), List.class);
if (CollUtil.isEmpty(categoryIds)) {
return Collections.emptyList();
}
List<Long> productIds = tbOrderDetailList.stream().map(OrderDetail::getProductId).collect(Collectors.toList());
canPrintProSet = productService.list(new QueryWrapper()
.in(Product::getCategoryId, categoryIds)
.in(Product::getId, productIds))
.stream()
.map(Product::getId)
.collect(Collectors.toSet());
} }
Long shopId = queue.getShopId();
if (shopId == null) {
throw new RuntimeException("店铺不存在, id:" + shopId);
}
getPrintMachine(shopId, "cash", "", "queue").forEach(machine -> handleRequest(machine, null, queue, PrintTypeEnum.CALL));
}
/**
* 交班打印
*
* @param data 传递的数据
*/
public void handoverHandler(String data) {
HandoverRecordDTO record = handoverRecordService.getHandoverRecordById(Long.parseLong(data));
if (record == null) {
throw new RuntimeException("交班票打印失败,交班记录不存在");
}
Long shopId = record.getShopId();
if (shopId == null) {
throw new RuntimeException("店铺不存在, id:" + shopId);
}
getPrintMachine(shopId, "cash", "", "handover").forEach(machine -> handleRequest(machine, null, record, PrintTypeEnum.HANDOVER));
}
private void handleRequest(PrintMachine machine, Integer placeNum, Object data, PrintTypeEnum printTypeEnum) {
if (canHandleRequest(machine.getContentType(), machine.getConnectionType())) {
log.info("打印机: {}, 传递信息: {}", machine.getName(), data);
print(machine, placeNum, data, printTypeEnum);
} else if (nextPrinter != null) {
log.info("当前打印机无法处理: {},将请求传递给下一个打印机:{}...", this.printerBrand, nextPrinter.printerBrand);
nextPrinter.handleRequest(machine, placeNum, data, printTypeEnum);
} else {
log.warn("未找到匹配打印机");
}
}
private void refundHandleRequest(PrintMachine machine, String printTitle, String operator, String refundAmount, String refundReason, String refundType,
OrderInfo orderInfo, List<OrderDetail> detailList) {
if (canHandleRequest(machine.getContentType(), machine.getConnectionType())) {
log.info("退款打印机: {}, 传递信息: {}", machine.getName(), orderInfo.getId());
returnOrderPrint(printTitle, operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList);
} else if (nextPrinter != null) {
log.info("当前打印机无法处理: {},将请求传递给下一个打印机:{}...", this.printerBrand, nextPrinter.printerBrand);
nextPrinter.refundHandleRequest(machine, printTitle, operator, refundAmount, refundReason, refundType, orderInfo, detailList);
} else {
log.warn("未找到匹配打印机");
}
}
boolean canHandleRequest(String currentBrand, String connectType) {
log.info("handle判断是否可处理: {}, 连接类型: {}, handler类型: {}", currentBrand, connectType, printerBrand);
if (StrUtil.isBlank(printerBrand)) {
throw new RuntimeException("打印机品牌未赋值");
}
return printerBrand.equals(currentBrand) && "网络".equals(connectType);
}
protected List<OrderDetail> getCanPrintOrderDetails(boolean partPrint, Long orderId, List<OrderDetail> tbOrderDetailList, List<?> categoryIds) {
List<Long> productIds = tbOrderDetailList.stream().map(OrderDetail::getProductId).collect(Collectors.toList());
Map<Long, Boolean> canPrintProMap = categoryIds.isEmpty() ? new HashMap<>() :
productService.list(new QueryWrapper().in(Product::getCategoryId, categoryIds).in(Product::getId, productIds))
.stream().collect(Collectors.toMap(Product::getId, i -> true));
ArrayList<OrderDetail> orderDetails = new ArrayList<>(); ArrayList<OrderDetail> orderDetails = new ArrayList<>();
tbOrderDetailList.forEach(item -> { for (OrderDetail item : tbOrderDetailList) {
Object o = redisService.get(RedisCst.getPrintOrderDetailKey(orderId, item.getId())); //-999 台位费
if (item.getNum().compareTo(BigDecimal.ZERO) <= 0 || item.getProductId().equals(-999L)) {
if (item.getIsPrint() != null && item.getIsPrint() == 1 && (canPrintProMap.get(item.getProductId()) != null || !partPrint)) { continue;
item.setReturnNum(item.getReturnNum() == null ? BigDecimal.ZERO : item.getReturnNum()); }
PrintDetailInfo printDetailInfo = o != null ? JSONObject.parseObject((String) o, PrintDetailInfo.class) : null; Boolean isPrint = redisService.hasKey(RedisCst.kitchenNormal(orderId, machine.getId(), item.getId()));
if (printDetailInfo != null) { if (isPrint) {
if (item.getNum().compareTo(BigDecimal.ZERO) != 0 && item.getNum().compareTo(printDetailInfo.getPrintNum()) <= 0) { continue;
log.info("此菜品已打印, {} {} {}", item.getProductName(), item.getSkuName(), printDetailInfo); }
} if (item.getIsPrint() != null && item.getIsPrint() == 1 && (!partPrint || canPrintProSet.contains(item.getProductId()))) {
orderDetails.add(item);
if (item.getReturnNum().compareTo(BigDecimal.ZERO) != 0 && item.getReturnNum().compareTo(printDetailInfo.getPrintReturnNum()) <= 0) {
log.info("此退菜菜品已打印, {} {} {}", item.getProductName(), item.getSkuName(), printDetailInfo);
}
item.setNum(item.getNum().subtract(printDetailInfo.getPrintNum()));
item.setReturnNum(item.getReturnNum().subtract(printDetailInfo.getPrintReturnNum()));
orderDetails.add(item);
} else {
orderDetails.add(item);
}
} else { } else {
log.info("此菜品不在打印分类或属于免打, {} {} {}", item.getProductName(), item.getSkuName(), item.getId()); log.info("此菜品不在打印分类或属于免打, {} {} {}", item.getProductName(), item.getSkuName(), item.getId());
} }
}); }
return orderDetails; return orderDetails;
} }
protected void print(PrintMachine machine, Integer placeNum, Object data, PrintTypeEnum printTypeEnum) {
switch (printTypeEnum) {
case PrintTypeEnum.HANDOVER:
log.info("准备开始打印交班");
if (data instanceof HandoverRecordDTO record) {
handoverPrint(machine, record);
} else {
throw new RuntimeException("传递数据类型有误");
}
break;
case PrintTypeEnum.GUEST_ORDER:
log.info("准备开始打印客看订单");
if (data instanceof OrderInfo orderInfo) {
orderInfo.setPlaceNum(placeNum);
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()).eq(OrderDetail::getPlaceNum, placeNum));
guestOrderPrint(orderInfo, machine, orderDetailList);
} else {
throw new RuntimeException("传递数据类型有误");
}
break;
case PrintTypeEnum.ORDER:
log.info("准备开始打印订单");
if (data instanceof OrderInfo orderInfo) {
redisService.set("order:print:" + orderInfo.getId(), "", 180);
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
orderPrint(machine, orderInfo, orderDetailList);
} else {
throw new RuntimeException("传递数据类型有误");
}
break;
case PrintTypeEnum.PRE_ORDER:
log.info("准备开始打印预结算订单");
if (data instanceof OrderInfo orderInfo) {
redisService.set("order:print:" + orderInfo.getId(), "", 180);
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
preOrderPrint(machine, orderInfo, orderDetailList);
} else {
throw new RuntimeException("传递数据类型有误");
}
break;
case PrintTypeEnum.ONE:
log.info("准备开始打印菜品单");
if (data instanceof OrderInfo orderInfo) {
redisService.set("order:print:" + orderInfo.getId(), "", 180);
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
onlyKitchen(machine, orderInfo, orderDetailList);
} else {
throw new RuntimeException("传递数据类型有误");
}
break;
case PrintTypeEnum.CALL:
log.info("准备开始打印叫号单");
if (data instanceof CallQueue queue) {
onlyCallNumPrint(machine, queue);
} else {
throw new RuntimeException("传递数据类型有误");
}
break;
case PrintTypeEnum.ONE_AND_ORDER:
log.info("准备开始打印菜品以及结算单");
if (data instanceof OrderInfo orderInfo) {
redisService.set("order:print:" + orderInfo.getId(), "", 180);
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
switch (machine.getPrintMethod()) {
case "all":
orderPrint(machine, orderInfo, orderDetailList);
onlyKitchen(machine, orderInfo, orderDetailList);
break;
case "one":
log.info("打印机仅打印one");
onlyKitchen(machine, orderInfo, orderDetailList);
break;
case "normal":
log.info("打印机仅打印normal");
orderPrint(machine, orderInfo, orderDetailList);
break;
default:
throw new RuntimeException("打印方法有误");
}
} else {
throw new RuntimeException("传递数据类型有误");
}
}
}
/**
* 仅打印制作单「厨房」
*/
private void onlyKitchen(PrintMachine machine, OrderInfo orderInfo, List<OrderDetail> tbOrderDetailList) {
// 判断订单是否是先付费或者已结算
if (!"after-pay".equals(orderInfo.getPayMode()) && (OrderStatusEnums.UNPAID.getCode().equals(orderInfo.getStatus()) || OrderStatusEnums.CANCELLED.getCode().equals(orderInfo.getStatus()))) {
log.warn("此订单未支付, 订单信息: {}", orderInfo);
}
List<?> categoryIds = JSONObject.parseObject(StrUtil.emptyToDefault(machine.getCategoryIds(), "[]"), List.class);
if (StrUtil.isEmpty(machine.getClassifyPrint())) {
log.error("分类打印是空, classifyPrint: {}", machine.getClassifyPrint());
return;
}
// 已打印详情信息
Map<Long, OrderDetail> detailMap = tbOrderDetailList.stream().map(item -> BeanUtil.copyProperties(item, OrderDetail.class)).collect(Collectors.toMap(OrderDetail::getId, i -> i));
tbOrderDetailList = getCanPrintOrderDetails("1".equals(machine.getClassifyPrint()), orderInfo.getId(), tbOrderDetailList, categoryIds);
tbOrderDetailList.parallelStream().filter(o -> ObjectUtil.defaultIfNull(o.getIsPrint(), 0) == 1).forEach(item -> {
if (item.getNum().compareTo(BigDecimal.ZERO) <= 0 && item.getReturnNum().compareTo(BigDecimal.ZERO) <= 0) {
return;
}
Integer isWaitCall = ObjectUtil.defaultIfNull(item.getIsWaitCall(), 0);
if (isWaitCall == 1) {
if (!item.getProductName().contains("【等叫】")) {
item.setProductName("【等叫】" + item.getProductName());
}
}
Integer isTemporary = ObjectUtil.defaultIfNull(item.getIsTemporary(), 0);
if (isTemporary == 1) {
item.setProductId(0L);
item.setSkuId(0L);
if (!item.getProductName().contains("【临】")) {
item.setProductName("【临】" + item.getProductName());
}
}
boolean isGift = item.getIsGift() != null && item.getIsGift() == 1;
if (isGift && !item.getProductName().contains("【赠】")) {
item.setProductName("【赠】" + item.getProductName());
}
// 台位费不打印
if (item.getProductId().equals(-999L)) {
log.info("台位费商品,不打印");
return;
}
if (item.getReturnNum().compareTo(BigDecimal.ZERO) > 0) {
returnDishesPrint("操作人名称", orderInfo, item, machine);
}
if (item.getNum().compareTo(BigDecimal.ZERO) > 0) {
normalDishesPrint("操作人名称", orderInfo, item, machine);
}
// 保存已打印信息
OrderDetail orderDetail = detailMap.get(item.getId());
redisService.set(RedisCst.getPrintOrderDetailKey(orderInfo.getId(), item.getId()),
JSONObject.toJSONString(new PrintDetailInfo().setPrint(item.getIsPrint() == 1).setDetailId(item.getId())
.setPrintNum(orderDetail.getNum()).setPrintReturnNum(orderDetail.getReturnNum())), 3600 * 24);
});
}
/** /**
* 打印预结算单「前台」 * 打印预结算单「前台」
*/ */
@@ -617,7 +465,7 @@ public abstract class PrinterHandler {
/** /**
* 打印排队小票 * 打印排队小票
*/ */
private void onlyCallNumPrint(PrintMachine machine, CallQueue queue) { private void callNumPrintBefore(PrintMachine machine, CallQueue queue) {
if (queue == null) { if (queue == null) {
log.warn("叫号记录不存在"); log.warn("叫号记录不存在");
return; return;
@@ -648,26 +496,26 @@ public abstract class PrinterHandler {
} }
public PrintInfoDTO returnOrderPrint(String printTitle, String operator, String refundAmount, String refundReason, String refundType, public OrderPrintDTO returnOrderPrint(String printTitle, String operator, String refundAmount, String refundReason, String refundType,
OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId()); ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
PrintInfoDTO printInfoDTO = new PrintInfoDTO().setShopName(shopInfo.getShopName()).setPrintType("收银-堂食") OrderPrintDTO orderPrintDTO = new OrderPrintDTO().setShopName(shopInfo.getShopName()).setPrintType("收银-堂食")
.setOrderNo(orderInfo.getOrderNo()) .setOrderNo(orderInfo.getOrderNo())
.setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy/MM/dd HH:mm:ss")) .setTradeDate(DateUtil.format(orderInfo.getCreateTime(), "yyyy/MM/dd HH:mm:ss"))
.setOperator(operator) .setOperator(operator)
.setReturn(true) .setReturn(true)
.setPrintTitle(printTitle); .setPrintTitle(printTitle);
printInfoDTO.setSeatNum(orderInfo.getSeatNum() == null ? "" : orderInfo.getSeatNum().toString()); orderPrintDTO.setSeatNum(orderInfo.getSeatNum() == null ? "" : orderInfo.getSeatNum().toString());
printInfoDTO.setPickupNum(orderInfo.getTableName()); orderPrintDTO.setPickupNum(orderInfo.getTableName());
printInfoDTO.setRefundAmount(refundAmount); orderPrintDTO.setRefundAmount(refundAmount);
printInfoDTO.setRefundReason(refundReason); orderPrintDTO.setRefundReason(refundReason);
printInfoDTO.setRefundType("cash".equals(refundType) ? "线下退款" : "原路退回"); orderPrintDTO.setRefundType("cash".equals(refundType) ? "线下退款" : "原路退回");
return printInfoDTO; return orderPrintDTO;
} }
public PrintInfoDTO guestOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { public OrderPrintDTO guestOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = getPrintInfoDTO(orderInfo, "客看单"); OrderPrintDTO orderPrintDTO = getPrintInfoDTO(orderInfo, "客看单");
BigDecimal originalAmount = BigDecimal.ZERO; BigDecimal originalAmount = BigDecimal.ZERO;
for (OrderDetail orderDetail : detailList) { for (OrderDetail orderDetail : detailList) {
@@ -692,24 +540,24 @@ public abstract class PrinterHandler {
orderDetail.setProductName("【赠】%s".formatted(orderDetail.getProductName())); orderDetail.setProductName("【赠】%s".formatted(orderDetail.getProductName()));
} }
} }
log.info("客看单 第{}次下单--------------------------------------------", orderInfo.getPlaceNum()); // log.info("客看单 第{}次下单--------------------------------------------", orderInfo.getPlaceNum());
if (orderInfo.getPlaceNum() != null && orderInfo.getPlaceNum() != 1) { if (orderInfo.getPlaceNum() != null && orderInfo.getPlaceNum() != 1) {
orderInfo.setSeatAmount(BigDecimal.ZERO); orderInfo.setSeatAmount(BigDecimal.ZERO);
printInfoDTO.setSeatAmount(""); orderPrintDTO.setSeatAmount("");
} }
printInfoDTO.setOriginalAmount((originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee())) orderPrintDTO.setOriginalAmount((originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee()))
.setScale(2, RoundingMode.HALF_UP).toPlainString()); .setScale(2, RoundingMode.HALF_UP).toPlainString());
printInfoDTO.setPayAmount((originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee()) orderPrintDTO.setPayAmount((originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee())
.subtract(orderInfo.getDiscountAllAmount())).setScale(2, RoundingMode.HALF_UP).toPlainString()); .subtract(orderInfo.getDiscountAllAmount())).setScale(2, RoundingMode.HALF_UP).toPlainString());
if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) { if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) {
printInfoDTO.setPackFee(orderInfo.getPackFee().toPlainString()); orderPrintDTO.setPackFee(orderInfo.getPackFee().toPlainString());
} }
return printInfoDTO; return orderPrintDTO;
} }
public PrintInfoDTO preOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { public OrderPrintDTO preOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = getPrintInfoDTO(orderInfo, "预结算单"); OrderPrintDTO orderPrintDTO = getPrintInfoDTO(orderInfo, "预结算单");
BigDecimal originalAmount = BigDecimal.ZERO; BigDecimal originalAmount = BigDecimal.ZERO;
for (OrderDetail orderDetail : detailList) { for (OrderDetail orderDetail : detailList) {
@@ -721,97 +569,48 @@ public abstract class PrinterHandler {
originalAmount = originalAmount.add((orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(orderDetail.getRefundNum())).multiply(orderDetail.getPrice())); originalAmount = originalAmount.add((orderDetail.getNum().subtract(orderDetail.getReturnNum()).subtract(orderDetail.getRefundNum())).multiply(orderDetail.getPrice()));
} }
} }
printInfoDTO.setOriginalAmount((originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee())) orderPrintDTO.setOriginalAmount((originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee()))
.setScale(2, RoundingMode.HALF_UP).toPlainString()); .setScale(2, RoundingMode.HALF_UP).toPlainString());
printInfoDTO.setPayAmount(originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee()) orderPrintDTO.setPayAmount(originalAmount.add(orderInfo.getSeatAmount()).add(orderInfo.getPackFee())
.subtract(orderInfo.getDiscountAllAmount()).setScale(2, RoundingMode.HALF_UP).toPlainString()); .subtract(orderInfo.getDiscountAllAmount()).setScale(2, RoundingMode.HALF_UP).toPlainString());
if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) { if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) {
printInfoDTO.setPackFee(orderInfo.getPackFee().toPlainString()); orderPrintDTO.setPackFee(orderInfo.getPackFee().toPlainString());
} }
return printInfoDTO; return orderPrintDTO;
} }
public PrintInfoDTO orderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) { public OrderPrintDTO orderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = getPrintInfoDTO(orderInfo, "结算单"); OrderPrintDTO orderPrintDTO = getPrintInfoDTO(orderInfo, "结算单");
BigDecimal originalAmount = orderInfo.getOriginAmount() == null ? BigDecimal.ZERO : orderInfo.getOriginAmount(); BigDecimal originalAmount = orderInfo.getOriginAmount() == null ? BigDecimal.ZERO : orderInfo.getOriginAmount();
printInfoDTO.setOriginalAmount(originalAmount.toPlainString()); orderPrintDTO.setOriginalAmount(originalAmount.toPlainString());
printInfoDTO.setPayAmount(originalAmount.subtract(orderInfo.getDiscountAllAmount()).setScale(2, RoundingMode.HALF_UP).toPlainString()); orderPrintDTO.setPayAmount(originalAmount.subtract(orderInfo.getDiscountAllAmount()).setScale(2, RoundingMode.HALF_UP).toPlainString());
if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) { if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) {
printInfoDTO.setPackFee(orderInfo.getPackFee().toPlainString()); orderPrintDTO.setPackFee(orderInfo.getPackFee().toPlainString());
} }
return printInfoDTO; return orderPrintDTO;
}
private PrintInfoDTO getPrintInfoDTO(OrderInfo orderInfo, String printTitle) {
ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
long count = orderInfoService.count(new QueryWrapper().eq(OrderInfo::getTradeDay, orderInfo.getTradeDay())
.eq(OrderInfo::getStatus, OrderStatusEnums.DONE.getCode())
.eq(OrderInfo::getShopId, orderInfo.getShopId())
.le(OrderInfo::getCreateTime, orderInfo.getCreateTime()));
PrintInfoDTO printInfoDTO = new PrintInfoDTO().setShopName(shopInfo.getShopName())
.setPrintTitle(printTitle)
.setPickupNum(orderInfo.getTableName())
.setOrderNo(orderInfo.getOrderNo()).setPayAmount(orderInfo.getPayAmount().toPlainString()).setReturn(false)
.setOutNumber(orderInfo.getTakeCode()).setCount(count).setRemark(orderInfo.getRemark())
// 使用累计的总优惠金额null 表示没有优惠
.setDiscountAmount(orderInfo.getDiscountAllAmount() != null
? orderInfo.getDiscountAllAmount().toPlainString()
: "0.00");
printInfoDTO.setSeatNum(orderInfo.getSeatNum() == null ? "" : orderInfo.getSeatNum().toString());
if (orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0) {
printInfoDTO.setSeatAmount(orderInfo.getSeatAmount().divide(BigDecimal.valueOf(orderInfo.getSeatNum()), 2, RoundingMode.DOWN).toPlainString());
}
if (StrUtil.isNotBlank(orderInfo.getDineMode())) {
switch (orderInfo.getDineMode()) {
case "dine-in" -> printInfoDTO.setPrintType("收银-堂食");
case "take-out" -> printInfoDTO.setPrintType("收银-外带");
case "take-away" -> printInfoDTO.setPrintType("收银-外卖");
}
if (!"dine-in".equals(orderInfo.getDineMode())) {
orderInfo.setSeatAmount(BigDecimal.ZERO);
printInfoDTO.setSeatAmount("");
}
}
if (orderInfo.getStaffId() != null) {
ShopStaff detail = shopStaffService.getOne(new QueryWrapper().eq(ShopStaff::getId, orderInfo.getStaffId()).eq(ShopStaff::getShopId, orderInfo.getShopId()));
if (detail != null) {
printInfoDTO.setOperator(detail.getName());
} else {
printInfoDTO.setOperator("");
}
} else {
printInfoDTO.setOperator("");
}
if ("结算单".equals(printTitle)) {
if (StrUtil.isNotBlank(orderInfo.getPayType())) {
switch (orderInfo.getPayType()) {
case "main_scan" -> printInfoDTO.setPayType("二维码收款");
case "back_scan" -> printInfoDTO.setPayType("扫码收款");
case "wechat_mini" -> printInfoDTO.setPayType("微信小程序");
case "alipay_mini" -> printInfoDTO.setPayType("支付宝小程序");
case "vip_pay" -> printInfoDTO.setPayType("余额支付");
case "cash_pay" -> printInfoDTO.setPayType("现金支付");
case "credit_pay" -> printInfoDTO.setPayType("挂账支付");
case "free_pay" -> printInfoDTO.setPayType("霸王餐支付");
}
}
printInfoDTO.setTradeDate(DateUtil.format(orderInfo.getPaidTime(), "yyyy/MM/dd HH:mm:ss"));
}
return printInfoDTO;
} }
/** /**
* 菜品打印 * 后厨 总单打印
*/ */
protected abstract void normalDishesPrint(String operator, OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine); public OrderPrintDTO allKitchenPrint(OrderInfo orderInfo, List<OrderDetail> orderDetails, PrintMachine machine) {
return getPrintInfoDTO(orderInfo, "后厨总单");
}
/** /**
* 菜品 退菜打印 * 后厨 菜品打印
*/ */
protected abstract void returnDishesPrint(String operator, OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine); protected abstract void onlyKitchenPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine);
/**
* 后厨 退菜整单打印
*/
public OrderPrintDTO returnKitchenPrint(String operator, OrderInfo orderInfo, List<OrderDetail> orderDetail, PrintMachine machine) {
OrderPrintDTO printInfo = getPrintInfoDTO(orderInfo, "后厨退菜单");
printInfo.setOperator(operator);
return printInfo;
}
/** /**
* 叫号打印 * 叫号打印
@@ -819,9 +618,91 @@ public abstract class PrinterHandler {
protected abstract void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum, protected abstract void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum,
String codeUrl, LocalDateTime takeTime, String shopNote); String codeUrl, LocalDateTime takeTime, String shopNote);
/**
* 出入库打印单
*/
protected abstract void stockPrint(PrintMachine machine, StockPrintDTO record);
/**
* 经营日报打印
*/
protected abstract void dayReportPrint(PrintMachine machine, DayReportPrintDTO record);
/**
* 商品报表打印
*/
protected abstract void productReportPrint(PrintMachine machine, ProductReportPrintDTO record);
/**
* 储值单打印
*/
protected abstract void rechargePrint(PrintMachine machine, RechargePrintDTO record);
/**
* 库存盘点打印
*/
protected abstract void stockCheckPrint(PrintMachine machine, StockCheckPrintDTO record);
/** /**
* 交班打印 * 交班打印
*/ */
protected abstract void handoverPrint(PrintMachine machine, HandoverRecordDTO record); protected abstract void handoverPrint(PrintMachine machine, HandoverRecordDTO record);
private OrderPrintDTO getPrintInfoDTO(OrderInfo orderInfo, String printTitle) {
ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
OrderPrintDTO orderPrintDTO = new OrderPrintDTO().setShopName(shopInfo.getShopName())
.setPrintTitle(printTitle)
.setPickupNum(orderInfo.getTableName())
.setOrderNo(orderInfo.getOrderNo()).setPayAmount(orderInfo.getPayAmount().toPlainString()).setReturn(false)
.setOutNumber(orderInfo.getTakeCode())
.setRemark(orderInfo.getRemark())
// 使用累计的总优惠金额null 表示没有优惠
.setDiscountAmount(orderInfo.getDiscountAllAmount() != null
? orderInfo.getDiscountAllAmount().toPlainString()
: "0.00");
orderPrintDTO.setSeatNum(orderInfo.getSeatNum() == null ? "" : orderInfo.getSeatNum().toString());
if (orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0) {
orderPrintDTO.setSeatAmount(orderInfo.getSeatAmount().divide(BigDecimal.valueOf(orderInfo.getSeatNum()), 2, RoundingMode.DOWN).toPlainString());
}
if (StrUtil.isNotBlank(orderInfo.getDineMode())) {
switch (orderInfo.getDineMode()) {
case "dine-in" -> orderPrintDTO.setPrintType("收银-堂食");
case "take-out" -> orderPrintDTO.setPrintType("收银-外带");
case "take-away" -> orderPrintDTO.setPrintType("收银-外卖");
}
if (!"dine-in".equals(orderInfo.getDineMode())) {
orderInfo.setSeatAmount(BigDecimal.ZERO);
orderPrintDTO.setSeatAmount("");
}
}
if (orderInfo.getStaffId() != null) {
ShopStaff detail = shopStaffService.getOne(new QueryWrapper().eq(ShopStaff::getId, orderInfo.getStaffId()).eq(ShopStaff::getShopId, orderInfo.getShopId()));
if (detail != null) {
orderPrintDTO.setOperator(detail.getName());
} else {
orderPrintDTO.setOperator("");
}
} else {
orderPrintDTO.setOperator("");
}
if ("结算单".equals(printTitle)) {
if (StrUtil.isNotBlank(orderInfo.getPayType())) {
switch (orderInfo.getPayType()) {
case "main_scan" -> orderPrintDTO.setPayType("二维码收款");
case "back_scan" -> orderPrintDTO.setPayType("扫码收款");
case "wechat_mini" -> orderPrintDTO.setPayType("微信小程序");
case "alipay_mini" -> orderPrintDTO.setPayType("支付宝小程序");
case "vip_pay" -> orderPrintDTO.setPayType("余额支付");
case "cash_pay" -> orderPrintDTO.setPayType("现金支付");
case "credit_pay" -> orderPrintDTO.setPayType("挂账支付");
case "free_pay" -> orderPrintDTO.setPayType("霸王餐支付");
}
}
orderPrintDTO.setTradeDate(DateUtil.format(orderInfo.getPaidTime(), "yyyy/MM/dd HH:mm:ss"));
}
return orderPrintDTO;
}
} }

View File

@@ -1,13 +1,12 @@
package com.czg.service.order.print; package com.czg.service.order.print;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil; import cn.hutool.http.HttpUtil;
import com.czg.account.dto.HandoverRecordDTO; import com.czg.account.dto.HandoverRecordDTO;
import com.czg.account.entity.PrintMachine; import com.czg.account.entity.PrintMachine;
import com.czg.order.entity.OrderDetail; import com.czg.order.entity.OrderDetail;
import com.czg.order.entity.OrderInfo; import com.czg.order.entity.OrderInfo;
import com.czg.print.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
@@ -56,12 +55,157 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl {
.setBr("<BR>") .setBr("<BR>")
.setBold(new String[]{"<B>", "</B>"}); .setBold(new String[]{"<B>", "</B>"});
@Override
protected void onlyKitchenPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) {
String buildDishPrintData = buildOnlyKitchenPrintData(getPickupNum(orderInfo), orderDetail);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
}
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(orderInfo.getId(), machine, "后厨商品单", buildDishPrintData, resp);
}
@Override
public OrderPrintDTO allKitchenPrint(OrderInfo orderInfo, List<OrderDetail> orderDetails, PrintMachine machine) {
OrderPrintDTO orderPrintDTO = super.allKitchenPrint(orderInfo, orderDetails, machine);
String buildDishPrintData = buildAllKitchenPrintData(orderPrintDTO, orderDetails);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
}
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(orderInfo.getId(), machine, "后厨总单", buildDishPrintData, resp);
return null;
}
@Override
public OrderPrintDTO returnKitchenPrint(String operator, OrderInfo orderInfo, List<OrderDetail> orderDetail, PrintMachine machine) {
OrderPrintDTO orderPrintDTO = super.returnKitchenPrint(operator, orderInfo, orderDetail, machine);
String buildDishPrintData = buildAllKitchenPrintData(orderPrintDTO, orderDetail);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"退菜消息,请及时处理\"}";
}
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(orderInfo.getId(), machine, "后厨退菜", buildDishPrintData, resp);
return null;
}
@Override
public OrderPrintDTO returnOrderPrint(String printTitle, String operator, String refundAmount, String refundReason, String refundType,
OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
OrderPrintDTO orderPrintDTO = super.returnOrderPrint(printTitle, operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList);
String data = buildRefundOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "退款单");
return null;
}
@Override
public OrderPrintDTO guestOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
OrderPrintDTO orderPrintDTO = super.guestOrderPrint(orderInfo, machine, detailList);
String data = buildGuestOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "客看单");
return null;
}
@Override
public OrderPrintDTO preOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
OrderPrintDTO orderPrintDTO = super.preOrderPrint(orderInfo, machine, detailList);
String data = buildOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "预结算单");
return null;
}
@Override
public OrderPrintDTO orderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
OrderPrintDTO orderPrintDTO = super.orderPrint(orderInfo, machine, detailList);
String data = buildOrderPrintData(orderPrintDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "结算单");
return null;
}
/**
* 叫号单打印
*/
@Override
protected void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum, String codeUrl, LocalDateTime takeTime, String shopNote) {
String resp = buildCallTicketData(shopName, tableName, callNum, preNum, codeUrl, shopNote, takeTime);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一条新的排号记录\"}";
}
sendPrintRequest(machine.getAddress(), resp, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
}
@Override
protected void stockPrint(PrintMachine machine, StockPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildStockData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "入库单", data, resp);
}
@Override
protected void dayReportPrint(PrintMachine machine, DayReportPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildDayReportData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "经营日报单", data, resp);
}
@Override
protected void productReportPrint(PrintMachine machine, ProductReportPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildProductReportData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "商品报表单", data, resp);
}
@Override
protected void rechargePrint(PrintMachine machine, RechargePrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildRechargeData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "储值单", data, resp);
}
@Override
protected void stockCheckPrint(PrintMachine machine, StockCheckPrintDTO record) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String data = buildStockCheckData(record);
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(machine, "盘点单", data, resp);
}
/**
* 交班单打印
*/
@Override
protected void handoverPrint(PrintMachine machine, HandoverRecordDTO record) {
String string = buildHandoverData(record);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
sendPrintRequest(machine.getAddress(), string, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
}
private void sendOrderPrint(String data, Long orderId, PrintMachine machine, String bizType) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
}
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, machine.getPrintNum() == null ? "1" : machine.getPrintNum().toString());
printMachineLogService.save(orderId, machine, bizType, data, resp);
}
@Override @Override
public PrintSignLabel getSignLabelInfo() { public PrintSignLabel getSignLabelInfo() {
return printSignLabel; return printSignLabel;
} }
@Override @Override
public String sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum) { public String sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum) {
log.info("开始请求云享印,请求数据:{}, {}", voiceData, metaPrintData); log.info("开始请求云享印,请求数据:{}, {}", voiceData, metaPrintData);
@@ -98,85 +242,6 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl {
return httpResponse; return httpResponse;
} }
@Override
protected void normalDishesPrint(String operator, OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) {
String buildDishPrintData = buildDishPrintData(false, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(),
orderDetail.getNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent());
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
}
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1");
printMachineLogService.save(orderInfo.getId(), machine, "新订单", buildDishPrintData, resp);
}
@Override
protected void returnDishesPrint(String operator, OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) {
String buildDishPrintData = buildDishPrintData(true, getPickupNum(orderInfo), DateUtil.format(orderDetail.getCreateTime(), "yyyy-MM-dd HH:mm:ss"), orderDetail.getProductName(), orderDetail.getSkuName(),
orderDetail.getReturnNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent());
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1");
printMachineLogService.save(orderInfo.getId(), machine, "退款单", buildDishPrintData, resp);
}
@Override
public PrintInfoDTO returnOrderPrint(String printTitle, String operator, String refundAmount, String refundReason, String refundType,
OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = super.returnOrderPrint(printTitle, operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList);
String data = buildRefundOrderPrintData(printInfoDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "退款单");
return null;
}
@Override
public PrintInfoDTO guestOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = super.guestOrderPrint(orderInfo, machine, detailList);
String data = buildGuestOrderPrintData(printInfoDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "客看单");
return null;
}
@Override
public PrintInfoDTO preOrderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = super.preOrderPrint(orderInfo, machine, detailList);
String data = buildOrderPrintData(printInfoDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "预结算单");
return null;
}
@Override
public PrintInfoDTO orderPrint(OrderInfo orderInfo, PrintMachine machine, List<OrderDetail> detailList) {
PrintInfoDTO printInfoDTO = super.orderPrint(orderInfo, machine, detailList);
String data = buildOrderPrintData(printInfoDTO, detailList);
sendOrderPrint(data, orderInfo.getId(), machine, "结算单");
return null;
}
/**
* 叫号单打印
*/
@Override
protected void callNumPrint(PrintMachine machine, String callNum, String shopName, String tableName, String tableNote, String preNum, String codeUrl, LocalDateTime takeTime, String shopNote) {
String resp = buildCallTicketData(shopName, tableName, callNum, preNum, codeUrl, shopNote, takeTime);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一条新的排号记录\"}";
}
sendPrintRequest(machine.getAddress(), resp, voiceJson, "1");
}
/**
* 交班单打印
*/
@Override
protected void handoverPrint(PrintMachine machine, HandoverRecordDTO record) {
String string = buildHandoverData(record);
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
sendPrintRequest(machine.getAddress(), string, voiceJson, "1");
}
/** /**
* 获取TOKEN值 * 获取TOKEN值
@@ -200,20 +265,6 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl {
return SecureUtil.md5(token + APP_SECRET).toUpperCase(); return SecureUtil.md5(token + APP_SECRET).toUpperCase();
} }
private void sendOrderPrint(String data, Long orderId, PrintMachine machine, String bizType) {
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
if (1 == machine.getVolumeSwitch()) {
voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
}
String printerNum = "1";
if (StrUtil.isNotBlank(machine.getPrintQty())) {
printerNum = machine.getPrintQty().split("\\^")[1];
}
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum);
printMachineLogService.save(orderId, machine, bizType, data, resp);
}
/** /**
* 检查打印状态 * 检查打印状态
* *

View File

@@ -332,11 +332,13 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
if ("after-pay".equals(orderInfo.getPayMode())) { if ("after-pay".equals(orderInfo.getPayMode())) {
// //
log.info("后付费生成订单{},第{}", orderInfo.getId(), orderInfo.getPlaceNum()); log.info("后付费生成订单{},第{}", orderInfo.getId(), orderInfo.getPlaceNum());
//客看单
printerHandler.orderHandler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.GUEST_ORDER, orderInfo.getPlaceNum()); printerHandler.orderHandler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.GUEST_ORDER, orderInfo.getPlaceNum());
//发送打票信息 后付费推送多次 需要处理
//orderId_0_0 订单ID_先付后付(1先付0后付)_订单状态 0未完成 1完成_第几次下单 //orderId_0_0 订单ID_先付后付(1先付0后付)_订单状态 0未完成 1完成_第几次下单
//orderInfo.getId() + "_" + (!"after-pay".equals(orderInfo.getPayMode()) ? 1 : 0) + "_0" //orderInfo.getId() + "_" + (!"after-pay".equals(orderInfo.getPayMode()) ? 1 : 0) + "_0"
//后付费 菜品单
rabbitPublisher.sendKitchenOrderPrintMsg(orderInfo.getId() + "_0_0", false, "后付费打印"); rabbitPublisher.sendKitchenOrderPrintMsg(orderInfo.getId() + "_0_0", false, "后付费打印");
// 消息通知 本地打印机执行
rabbitPublisher.sendOrderPrintMsg(orderInfo.getId() + "_0_0_" + orderInfo.getPlaceNum(), true, "后付费打印"); rabbitPublisher.sendOrderPrintMsg(orderInfo.getId() + "_0_0_" + orderInfo.getPlaceNum(), true, "后付费打印");
} else { } else {
redisService.set(RedisCst.classKeyExpired.EXPIRED_ORDER + orderInfo.getId(), "", 60 * 15); redisService.set(RedisCst.classKeyExpired.EXPIRED_ORDER + orderInfo.getId(), "", 60 * 15);
@@ -1616,9 +1618,6 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
} }
switch (orderInfoPrintDTO.getType()) { switch (orderInfoPrintDTO.getType()) {
case 0://菜品和结算单同时打印
printerHandler.orderHandler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.ONE_AND_ORDER, null);
break;
case 1://预结算单 case 1://预结算单
printerHandler.orderHandler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.PRE_ORDER, null); printerHandler.orderHandler(orderInfo.getId().toString(), PrinterHandler.PrintTypeEnum.PRE_ORDER, null);
break; break;

View File

@@ -1,7 +1,6 @@
package com.czg.service.order.service.impl; package com.czg.service.order.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.czg.account.entity.HandoverRecord; import com.czg.account.entity.HandoverRecord;
@@ -25,7 +24,8 @@ import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.*; import java.util.ArrayList;
import java.util.List;
/** /**
* 订单Rpc ServiceImpl * 订单Rpc ServiceImpl
@@ -169,7 +169,8 @@ public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {
} }
@Override @Override
public void sendHandoverReceiptPrintMsgToMq(Long handoverRecordId) { public void sendHandoverReceiptPrintMsgToMq(Long shopId, HandoverRecord record) {
rabbitPublisher.sendHandoverPrintMsg(Convert.toStr(handoverRecordId)); rabbitPublisher.sendOtherPrintMsg(shopId, record, "HANDOVER");
} }
} }

View File

@@ -381,7 +381,7 @@ public class OrderPayServiceImpl implements OrderPayService {
} }
boolean isFirstRefund = orderInfo.getRefundAmount().compareTo(BigDecimal.ZERO) == 0; boolean isFirstRefund = orderInfo.getRefundAmount().compareTo(BigDecimal.ZERO) == 0;
ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId()); ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
Map<Long,BigDecimal> productStockMap = new HashMap<>(); Map<Long, BigDecimal> productStockMap = new HashMap<>();
boolean isPay = true; boolean isPay = true;
String refPayOrderNo = "REFO" + IdUtil.getSnowflakeNextId(); String refPayOrderNo = "REFO" + IdUtil.getSnowflakeNextId();
if (orderInfo.getStatus().equals(OrderStatusEnums.UNPAID.getCode())) { if (orderInfo.getStatus().equals(OrderStatusEnums.UNPAID.getCode())) {
@@ -524,13 +524,20 @@ public class OrderPayServiceImpl implements OrderPayService {
orderInfoService.updateById(orderInfo); orderInfoService.updateById(orderInfo);
//退款后续 退款单/退菜单 //退款后续 退款单/退菜单
if (param.isPrint()) { if (param.isPrint()) {
printerHandler.refundOrderHandler(printTitle, StrUtil.isNotBlank(param.getOperator()) ? param.getOperator() : "" String finalPrintTitle = printTitle;
, isPay ? param.getRefundAmount().toPlainString() : "0" boolean finalIsPay = isPay;
, param.getRefundReason(), orderInfo.getRefundType(), orderInfo, param.getRefundDetails()); FunUtils.safeRunVoid(() -> printerHandler.refundOrderHandler(finalPrintTitle, StrUtil.isNotBlank(param.getOperator()) ? param.getOperator() : ""
, finalIsPay ? param.getRefundAmount().toPlainString() : "0"
, param.getRefundReason(), orderInfo.getRefundType(), orderInfo, param.getRefundDetails()),
"订单id:{} 退款,前台打印消息失败", orderInfo.getId());
} }
//后厨退菜单
FunUtils.safeRunVoid(() -> printerHandler.kitchenRefundAllHandler(StrUtil.isNotBlank(param.getOperator()) ? param.getOperator() : "", orderInfo, param.getRefundDetails()),
"订单id:{} 退款,后厨退菜单打印消息失败", orderInfo.getId());
//退款返还库存 //退款返还库存
if (!productStockMap.isEmpty()) { if (!productStockMap.isEmpty()) {
orderInfoCustomService.refundStock(shopInfo, orderInfo.getId(), productStockMap, param.isRefundStock()); FunUtils.safeRunVoid(() -> orderInfoCustomService.refundStock(shopInfo, orderInfo.getId(), productStockMap, param.isRefundStock()),
"订单id:{} 退款,库存处理失败", orderInfo.getId());
} }
refundOrderAfter(orderInfo.getId(), orderInfo.getShopId(), orderInfo.getUserId(), orderInfo.getOrderNo(), refundOrderAfter(orderInfo.getId(), orderInfo.getShopId(), orderInfo.getUserId(), orderInfo.getOrderNo(),
orderInfo.getPointsNum(), isFirstRefund, orderInfo.getStatus().equals(OrderStatusEnums.REFUND.getCode())); orderInfo.getPointsNum(), isFirstRefund, orderInfo.getStatus().equals(OrderStatusEnums.REFUND.getCode()));

View File

@@ -93,7 +93,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
String respMsg = "打印中"; String respMsg = "打印中";
JSONObject resp = JSONObject.parseObject(respJson); JSONObject resp = JSONObject.parseObject(respJson);
// 云想印 // 云想印
if ("云想印".equals(config.getContentType())) { if ("云想印".equals(config.getBrand())) {
int code = resp.getIntValue("code"); int code = resp.getIntValue("code");
JSONObject respData = resp.getJSONObject("data"); JSONObject respData = resp.getJSONObject("data");
JSONObject data = respData.getJSONObject("data"); JSONObject data = respData.getJSONObject("data");
@@ -112,7 +112,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
entity.setTaskId(respData.getString("orderId")); entity.setTaskId(respData.getString("orderId"));
} }
// 飞鹅云打印机暂时没有适配先return不做打印记录 // 飞鹅云打印机暂时没有适配先return不做打印记录
} else if ("飞鹅".equals(config.getContentType())) { } else if ("飞鹅".equals(config.getBrand())) {
int ret = resp.getIntValue("ret"); int ret = resp.getIntValue("ret");
if (ret != 0) { if (ret != 0) {
failFlag = 1; failFlag = 1;
@@ -170,7 +170,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
try { try {
// 1. 云想印打印机状态查询 // 1. 云想印打印机状态查询
if ("云想印".equals(config.getContentType())) { if ("云想印".equals(config.getBrand())) {
String jsonStr = yxyPrinter.checkPrintStatus(config.getAddress(), entity.getTaskId()); String jsonStr = yxyPrinter.checkPrintStatus(config.getAddress(), entity.getTaskId());
log.info("云想印打印状态查询结果(第{}次,虚拟线程:{}{}", log.info("云想印打印状态查询结果(第{}次,虚拟线程:{}{}",
currentTimes, Thread.currentThread().getName(), jsonStr); currentTimes, Thread.currentThread().getName(), jsonStr);
@@ -185,7 +185,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
} }
} }
// 2. 飞鹅云打印机状态查询 // 2. 飞鹅云打印机状态查询
else if ("飞鹅".equals(config.getContentType())) { else if ("飞鹅".equals(config.getBrand())) {
Boolean success = feiPrinter.checkFPrintStatus(entity.getTaskId()); Boolean success = feiPrinter.checkFPrintStatus(entity.getTaskId());
if (success == null) { if (success == null) {
entity.setFailFlag(1); entity.setFailFlag(1);

View File

@@ -10,6 +10,8 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.czg.config.RabbitPublisher; import com.czg.config.RabbitPublisher;
import com.czg.exception.CzgException; import com.czg.exception.CzgException;
import com.czg.print.StockCheckPrintDTO;
import com.czg.print.StockPrintDTO;
import com.czg.product.dto.ConsStockFlowDTO; import com.czg.product.dto.ConsStockFlowDTO;
import com.czg.product.entity.ConsInfo; import com.czg.product.entity.ConsInfo;
import com.czg.product.entity.ConsStockFlow; import com.czg.product.entity.ConsStockFlow;
@@ -23,6 +25,7 @@ import com.czg.service.product.mapper.ConsInfoMapper;
import com.czg.service.product.mapper.ConsStockFlowMapper; import com.czg.service.product.mapper.ConsStockFlowMapper;
import com.czg.service.product.mapper.ProductMapper; import com.czg.service.product.mapper.ProductMapper;
import com.czg.service.product.util.WxAccountUtil; import com.czg.service.product.util.WxAccountUtil;
import com.czg.utils.FunUtils;
import com.czg.utils.PageUtil; import com.czg.utils.PageUtil;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
@@ -36,6 +39,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -108,7 +112,7 @@ public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, C
for (ConsInfo consInfo : updateStockList) { for (ConsInfo consInfo : updateStockList) {
consInfoMapper.update(consInfo); consInfoMapper.update(consInfo);
} }
FunUtils.transactionSafeRun(() -> sendInOutPrintMsg("IN", shopId, param));
return param; return param;
} }
@@ -145,6 +149,33 @@ public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, C
for (ConsInfo consInfo : updateStockList) { for (ConsInfo consInfo : updateStockList) {
consInfoMapper.update(consInfo); consInfoMapper.update(consInfo);
} }
FunUtils.transactionSafeRun(() -> sendInOutPrintMsg("OUT", shopId, param));
}
private void sendInOutPrintMsg(String type, Long shopId, ConsInOutStockHeadParam param) {
StockPrintDTO stockPrint = new StockPrintDTO();
stockPrint.setType(type);
stockPrint.setPrintTime(LocalDateTime.now());
stockPrint.setOperator(param.getOperator());
stockPrint.setConsCount(param.getBodyList().size());
List<StockPrintDTO.InStockItem> items = new ArrayList<>();
BigDecimal totalInOutNumber = BigDecimal.ZERO;
BigDecimal totalAmount = BigDecimal.ZERO;
for (ConsInOutStockBodyParam cons : param.getBodyList()) {
StockPrintDTO.InStockItem item = new StockPrintDTO.InStockItem();
item.setConsName(cons.getConName());
item.setUnit(cons.getUnitName());
item.setStockNumber(cons.getInOutNumber());
item.setAmount(cons.getSubTotal());
items.add(item);
totalInOutNumber = NumberUtil.add(totalInOutNumber, cons.getInOutNumber());
totalAmount = NumberUtil.add(totalAmount, cons.getSubTotal());
}
stockPrint.setStockNumberCount(totalInOutNumber);
stockPrint.setAmountCount(totalAmount);
stockPrint.setItems(items);
//库存盘点
rabbitPublisher.sendOtherPrintMsg(shopId, stockPrint, "STOCK");
} }
@Override @Override
@@ -183,6 +214,19 @@ public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, C
consInfo.setStockNumber(entity.getAfterNumber()); consInfo.setStockNumber(entity.getAfterNumber());
consInfoMapper.update(consInfo); consInfoMapper.update(consInfo);
saveFlow(entity, consInfo.getConWarning()); saveFlow(entity, consInfo.getConWarning());
FunUtils.transactionSafeRun(() -> {
StockCheckPrintDTO stockCheckPrintDTO = new StockCheckPrintDTO();
stockCheckPrintDTO.setWinLossNumberCount(winLossNumber.intValue());
stockCheckPrintDTO.setWinLossAmount(entity.getSubTotal());
stockCheckPrintDTO.setRemark(entity.getRemark());
stockCheckPrintDTO.setOperator(param.getOperator());
List<StockCheckPrintDTO.StockCheckItem> items = new ArrayList<>();
items.add(new StockCheckPrintDTO.StockCheckItem(consInfo.getConName(), param.getPrice(), consInfo.getConUnit(), param.getActualNumber(), param.getWinLossNumber()));
stockCheckPrintDTO.setItems(items);
//库存盘点
rabbitPublisher.sendOtherPrintMsg(shopId, stockCheckPrintDTO, "STOCK_CHECK");
});
} }
@Override @Override