From 09806185d87e4120802b72a84659c2a5c4941e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E5=AE=97=E6=A5=A0?= Date: Fri, 5 Jan 2024 16:53:18 +0800 Subject: [PATCH] 1 --- business/jxstore/cms/print.go | 467 ++++++++++++++++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 business/jxstore/cms/print.go diff --git a/business/jxstore/cms/print.go b/business/jxstore/cms/print.go new file mode 100644 index 000000000..d282cac94 --- /dev/null +++ b/business/jxstore/cms/print.go @@ -0,0 +1,467 @@ +package cms + +import ( + "encoding/json" + "errors" + "fmt" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" + "net" + "regexp" + "time" +) + +const ( + sounda = "sounda" //提示音a + soundb = "soundb" //提示音b + soundc = "soundc" //提示音c + soundd = "soundd" //提示音d + sounde = "sounde" //报警音e + soundf = "soundf" //报警音f + soundg = "soundg" //报警音g +) + +type PrintInfo struct { + PrintNo string + AppID int +} + +var ( + regexpMobile = regexp.MustCompile("^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$") + soundMap = map[string]string{ + "sounda": "sounda", + "soundb": "soundb", + "soundc": "soundc", + "soundd": "soundd", + "sounde": "sounde", + "soundf": "soundf", + "soundg": "soundg", + } +) + +func AddPrinter(appID int, printers []*model.AddPrinterParam) (err error) { + var ( + db = dao.GetDB() + errs []error + ) + if len(printers) > 50 { + return fmt.Errorf("一次最多只能绑定50台!") + } + for _, v := range printers { + if printers2, _ := dao.GetPrinters(db, appID, v.PrintNo, 0, 0); len(printers2) > 0 { + // 代表打印机已经在小程序注册了,查询打印机授权门店 + bindStoreList, err := dao.QueryPrintBindStore(v.PrintNo) + if err != nil { + errs = append(errs, fmt.Errorf("QueryPrintBindStore err : %v ", err)) + continue + } + if len(bindStoreList) >= 5 { + errs = append(errs, fmt.Errorf("当前打印机绑定门店数据超过五个,无法继续绑定")) + continue + } + have := false + userId := "" + for _, bsl := range bindStoreList { + if bsl.StoreID == v.StoreId { + have = true + userId = bsl.UserId + } + } + if !have { + if err := dao.BindStoreList(printers[0], userId); err != nil { + errs = append(errs, fmt.Errorf("BindStoreList err : %v ", err)) + continue + } + } + + continue + } + //验证 + if err = checkPrinterInfo(v.PrintNo, v.Name, "", "", 0); err != nil { + errs = append(errs, err) + continue + } + // 检查心跳 + exits, err := dao.CheckHeard(v.PrintNo) + if err != nil { + errs = append(errs, fmt.Errorf("CheckHeard err : %v ", err)) + continue + } + if !exits { + errs = append(errs, fmt.Errorf("打印机未激活,请激活后在绑定")) + continue + } + + printer := &model.Printer{ + AppID: appID, + PrintNo: v.PrintNo, + Name: v.Name, + IccID: "", + Status: model.PrinterStatusOffline, + Sound: "sounda", + PrintKey: v.SIM, + IsOnline: 0, + Volume: 1, + FlowFlag: 0, + OfflineCount: 0, + UserId: "system_user", + } + + // 创建打印机 + if err := InitPrint(printer, v); err != nil { + return err + } + } + if len(errs) > 0 { + err = jxutils.BuildErr(errs) + } + return err +} + +func InitPrint(printer *model.Printer, printParam *model.AddPrinterParam) error { + txDb, _ := dao.Begin(dao.GetDB()) + // 创建打印机 + dao.WrapAddIDCULDEntity(printer, "") + if err := dao.CreateEntityTx(txDb, printer); err != nil { + txDb.Rollback() + return err + } + + // 赋予打印机默认配置 + day := time.Now() + param, err := MarshalJson2String(&model.PrintSetting{ + CreatedAt: day, + UpdatedAt: day, + DeletedAt: utils.DefaultTimeValue, + PrintNo: printer.PrintNo, + CallNameSetting: 64, // 老板 + BusinessOffLineVoice: 1, // 离线开关 + BalanceNotEnoughVoice: 1, // 余额不足 + EveryDayGreetVoice: 1, // 问好 + BusinessPrintNum: 1, // 商户侧打印次数 + CustomerPrintNum: 1, // 用户侧打印次数 + + }) + if err != nil { + return err + } + if err := dao.CreateEntityTx(txDb, param); err != nil { + txDb.Rollback() + return err + } + + // 初始化打印机账户 + if err := dao.CreateEntityTx(txDb, &model.PrintBill{ + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + PrintNo: param.PrintNo, + PrintBalance: 20000, + UserId: "system", + }); err != nil { + txDb.Rollback() + return err + } + + // 初始化绑定信息 + if err := dao.BindStoreList(printParam, ""); err != nil { + txDb.Rollback() + return err + } + + defer txDb.Commit() + return err +} + +// MarshalJson2String 工具类 +func MarshalJson2String(param *model.PrintSetting) (*model.PrintSetting, error) { + // 语音设置 + voiceSetting := &model.VoiceSettingDetail{ + WaitOrderVoice: model.SettingOpen, + RiderTakeOrderVoice: model.SettingOpen, + ApplyUserOrderCancelVoice: model.SettingOpen, + ApplyRefundOrderVoice: model.SettingOpen, + ApplyRefundGoodsVoice: model.SettingOpen, + RefundGoodsVoice: model.SettingOpen, + ConfirmGoodsVoice: model.SettingOpen, + SuccessGoodsVoice: model.SettingOpen, + ConsultingPrint: model.SettingOpen, + ReminderVoice: model.SettingOpen, + CustomerRejectionVoice: model.SettingOpen, + CusterRefundVoice: model.SettingOpen, + LoseAuthorization: model.SettingOpen, + } + customerVoiceSettingByte, err := json.Marshal(voiceSetting) + if err != nil { + return nil, err + } + param.VoiceSetting = string(customerVoiceSettingByte) + + // 打印设置 + printSetting := &model.PrintSettingDetail{ + UserOrderCancel: model.SettingOpen, + RefundOrder: model.SettingOpen, + BusinessOrderCancel: model.SettingOpen, + RiderTakeOrder: model.SettingOpen, + CusterRefundPrint: model.SettingOpen, + WaitOrderPrint: model.SettingOpen, + ApplyUserCancelOrder: model.SettingOpen, + ApplyUserRefund: model.SettingOpen, + OrderCancelSuccess: model.SettingOpen, + } + pickingSettingByte, err := json.Marshal(printSetting) + if err != nil { + return nil, err + } + param.PrintSetting = string(pickingSettingByte) + return param, nil +} + +func checkPrinterInfo(printNo, name, sound, sim string, volume int) (err error) { + if printNo != "" { + + } + if sim != "" { + //if regexpMobile.FindString(sim) == "" { + return fmt.Errorf("暂不支持修改sim卡号码!print_no : %v ", printNo) + //} + } + if volume != 0 { + if volume <= 0 || volume > 5 { + return fmt.Errorf("请输入正确的音量1-5!print_no : %v ", printNo) + } + } + if sound != "" { + if soundMap[sound] == "" { + return fmt.Errorf("请输入正确的提示音!print_no : %v ", printNo) + } + } + if name != "" { + if len(name) > 255 { + return fmt.Errorf("打印机备注不能超过255个字符!print_no : %v ", printNo) + } + } + return err +} + +func DelPrinter(appID int, printNos []string, storeId string) (err error) { + var ( + db = dao.GetDB() + errs []error + ) + for _, v := range printNos { + if printers, _ := dao.GetPrinters(db, appID, v, 0, 0); len(printers) == 0 { + errs = append(errs, fmt.Errorf("该应用下未找到该打印机!print_no : %v ", v)) + continue + } else { + if err := dao.DeleteStoreList(printers[0].PrintNo, storeId); err != nil { + errs = append(errs, err) + continue + } + } + } + if len(errs) > 0 { + err = jxutils.BuildErr(errs) + } + return err +} + +func UpdatePrinter(appID int, printNo string, name, sim, sound *string, volume *int) (err error) { + var ( + db = dao.GetDB() + fields []string + ) + //看有没有 + if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 { + return fmt.Errorf("该应用下未找到该打印机!print_no : %v", printNo) + } else { + if name != nil { + if *name != "" { + if len(*name) > 20 { + return fmt.Errorf("打印机备注不能超过20个字符!print_no : %v ", printNo) + } + } + if printers[0].Name != *name { + printers[0].Name = *name + fields = append(fields, "name") + } + } + if sim != nil { + if *sim != "" { + //if regexpMobile.FindString(*sim) == "" { + return fmt.Errorf("暂不支持修改sim卡号码!print_no : %v ", printNo) + //} + } + //if printers[0].SIM != *sim { + // printers[0].SIM = *sim + // fields = append(fields, "sim") + //} + } + if sound != nil { + if *sound != "" { + if soundMap[*sound] == "" { + return fmt.Errorf("请输入正确的提示音!print_no : %v ", printNo) + } + } + if printers[0].Sound != *sound { + printers[0].Sound = *sound + fields = append(fields, "sound") + } + } + if volume != nil { + if *volume <= 0 || *volume > 5 { + return fmt.Errorf("请输入正确的音量 1-5!print_no : %v ", printNo) + } + if printers[0].Volume != *volume { + printers[0].Volume = *volume + fields = append(fields, "volume") + } + } + if _, err = dao.UpdateEntity(db, printers[0], fields...); err != nil { + return err + } + } + return err +} + +func DelPrinterSeq(appID int, printNo string) (err error) { + var ( + db = dao.GetDB() + ) + //看有没有 + if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 { + return fmt.Errorf("该应用下未找到该打印机!print_no : %v", printNo) + } else { + printMsgs, _ := dao.GetPrintMsgs(db, printNo, "", model.PrintMsgAll, model.PrintMsgSuccess) + for _, v := range printMsgs { + v.DeletedAt = time.Now() + if _, err = dao.UpdateEntity(db, v, "DeletedAt"); err != nil { + return err + } + } + } + + // 简历连接 + conn, err := net.Dial("tcp", "www.jxcs.net:8000") + if err != nil { + return err + } + clearPrint := fmt.Sprintf(`{"print_no_clear":%s}`, printNo) + // 发送数据 + if _, err := conn.Write([]byte(clearPrint)); err != nil { + return err + } + // 等待数据 + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil { + return err + } + if string(buf[:n]) != "ok" { + return errors.New("缓存清理失败") + } + defer conn.Close() + return err +} + +func DoPrintMsg(appID int, msgID, printNo, content string, orderNo string) (err error) { + var ( + db = dao.GetDB() + ) + //打印机必须绑定在该应用下才能打印 + if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 { + return fmt.Errorf("未在该应用下获取到此打印机!print_no %v", printNo) + } + printMsg := &model.PrintMsg{ + PrintNo: printNo, + Content: content, + OrderNo: orderNo, + MsgID: msgID, + } + dao.WrapAddIDCULDEntity(printMsg, "") + if err = dao.CreateEntity(db, printMsg); err != nil { + return err + } + return err +} + +type GetPrintMsgResult struct { + MsgID string `json:"msg_id"` //消息ID + PrintNo string `json:"print_no"` //打印机编号 + OrderNo string `json:"order_no"` //订单序号 + Content string `json:"content"` //订单内容 + Status int `json:"status"` //打印状态 + Comment string `json:"comment"` //失败原因 +} + +func GetPrintMsg(appID int, msgID string) (printMsg *GetPrintMsgResult, err error) { + var ( + db = dao.GetDB() + ) + if printMsgs, _ := dao.GetPrintMsgs(db, "", msgID, model.PrintMsgAll, model.PrintMsgAll); len(printMsgs) > 0 { + result := printMsgs[0] + printMsg = &GetPrintMsgResult{ + MsgID: result.MsgID, + PrintNo: result.PrintNo, + OrderNo: result.OrderNo, + Content: result.Content, + Status: result.Status, + Comment: result.Comment, + } + return printMsg, err + } else { + return printMsg, fmt.Errorf("未找到该消息!msg_id :%v", msgID) + } +} + +func GetPrinterStatus(appID int, printNo string) (status int, err error) { + var ( + db = dao.GetDB() + ) + //看有没有 + if printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0); len(printers) == 0 { + return status, fmt.Errorf("该应用下未找到该打印机!print_no : %v", printNo) + } else { + return printers[0].Status + printers[0].IsOnline, nil // 当两个值都唯一时->在线正常 + server := "print.jxcs.net:8000" + tcpAddr, err := net.ResolveTCPAddr("tcp4", server) + if err != nil { + //os.Exit(1) + return status, err + } + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + return status, err + } + status = connHandler(conn, &PrintInfo{ + PrintNo: printNo, + AppID: appID, + }) + return status, nil + } +} + +func connHandler(c net.Conn, printInfo *PrintInfo) (status int) { + defer c.Close() + //缓冲 + buf := make([]byte, 1024) + data, _ := json.Marshal(printInfo) + //写入数据 + c.Write(data) + //服务器端返回的数据写入buf + n, _ := c.Read(buf) + status = utils.Str2Int(string(buf[:n])) + //服务器端回传的信息 + fmt.Println("server response:", string(buf[:n])) + return status +} + +//#region 打印机拼装模板 + +// QueryPrinterSetting 查询用户设置 +func QueryPrinterSetting() { + +} + +//#endregion 打印机