修改打印模板
This commit is contained in:
207
services/print_server/app_server/temp.go
Normal file
207
services/print_server/app_server/temp.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package app_server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-print/dao"
|
||||
tempModel "git.rosy.net.cn/jx-print/model/app_model"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TempServer struct {
|
||||
}
|
||||
|
||||
// MakeSystemTempFontSmall 制作系统模板小字体
|
||||
func (t *TempServer) MakeSystemTempFontSmall(param map[string]interface{}) (string, error) {
|
||||
if len(param) <= 0 {
|
||||
return "", errors.New("参数不能为空")
|
||||
}
|
||||
orderPrint := &JXPrintData{}
|
||||
if err := utils.Map2StructByJson(param, orderPrint, false); err != nil {
|
||||
return "", errors.New("参数不能为空")
|
||||
}
|
||||
// 头部模板,订单
|
||||
var orderParams []interface{}
|
||||
headTemp := tempBegin
|
||||
orderParams = append(orderParams, orderPrint.EBailOrderNo, orderPrint.PayOrderTime, orderPrint.TrySendTime, orderPrint.OrderNo)
|
||||
// 是否为预订单
|
||||
if orderPrint.BusinessType == "2" {
|
||||
headTemp += tempBusiness
|
||||
}
|
||||
|
||||
// 订单来源信息
|
||||
pickupTemp := tempBegin2
|
||||
orderParams = append(orderParams, orderPrint.VendorName, orderPrint.VendorOrderNo, orderPrint.QRCOrder)
|
||||
if orderPrint.VendorID == utils.Int2Str(model.VendorIDEBAI) {
|
||||
getCode := fmt.Sprintf(tempEBail, orderPrint.VendorName, orderPrint.EBaiCode)
|
||||
pickupTemp += getCode
|
||||
}
|
||||
|
||||
// 客户信息
|
||||
userInfo := tempBegin3
|
||||
orderParams = append(orderParams, orderPrint.ConsigneeName, orderPrint.ConsigneeMobile, orderPrint.ConsigneeAddress, orderPrint.BuyerComment)
|
||||
|
||||
// 商品信息
|
||||
skuList := ""
|
||||
for _, v := range orderPrint.SkuList {
|
||||
sku := fmt.Sprintf(skuListTemp, v.SkuName, v.SkuCount, v.SalePrice, v.TotalCountPrice)
|
||||
if v.Upc != "" {
|
||||
sku += fmt.Sprintf(`<center>upc码:%s</center><br>`, v.Upc)
|
||||
}
|
||||
skuList += sku
|
||||
}
|
||||
|
||||
// 统计信息
|
||||
statInfo := tempEnd
|
||||
orderParams = append(orderParams, orderPrint.AllSkuTypeCount, orderPrint.AllSkuCount, orderPrint.StoreName, orderPrint.StoreTel, orderPrint.OfficialName)
|
||||
// 语音模板
|
||||
soundTemp := fmt.Sprintf(soundTemp, "老板,你有新订单了")
|
||||
orderFmt := soundTemp + pickupTemp + userInfo + skuList + statInfo
|
||||
return fmt.Sprintf(orderFmt, orderParams), nil
|
||||
}
|
||||
|
||||
// MakeSystemTempFontBig 制作系统模板大字体
|
||||
func (t *TempServer) MakeSystemTempFontBig(param map[string]interface{}) (string, error) {
|
||||
if len(param) <= 0 {
|
||||
return "", errors.New("参数不能为空")
|
||||
}
|
||||
orderPrint := &JXPrintData{}
|
||||
if err := utils.Map2StructByJson(param, orderPrint, false); err != nil {
|
||||
return "", errors.New("参数不能为空")
|
||||
}
|
||||
// 头部模板,订单
|
||||
var orderParams []interface{}
|
||||
headTemp := tempBeginBig
|
||||
orderParams = append(orderParams, orderPrint.EBailOrderNo, orderPrint.PayOrderTime, orderPrint.TrySendTime, orderPrint.OrderNo)
|
||||
// 是否为预订单
|
||||
if orderPrint.BusinessType == "2" {
|
||||
headTemp += tempBusinessBig
|
||||
}
|
||||
|
||||
// 订单来源信息
|
||||
pickupTemp := tempBegin2Big
|
||||
orderParams = append(orderParams, orderPrint.VendorName, orderPrint.VendorOrderNo, orderPrint.QRCOrder)
|
||||
if orderPrint.VendorID == utils.Int2Str(model.VendorIDEBAI) {
|
||||
getCode := fmt.Sprintf(tempEBailBig, orderPrint.VendorName, orderPrint.EBaiCode)
|
||||
pickupTemp += getCode
|
||||
}
|
||||
|
||||
// 客户信息
|
||||
userInfo := tempBegin3Big
|
||||
orderParams = append(orderParams, orderPrint.ConsigneeName, orderPrint.ConsigneeMobile, orderPrint.ConsigneeAddress, orderPrint.BuyerComment)
|
||||
|
||||
// 商品信息
|
||||
skuList := ""
|
||||
for _, v := range orderPrint.SkuList {
|
||||
sku := fmt.Sprintf(skuListTempBig, v.SkuName, v.SkuCount, v.SalePrice, v.TotalCountPrice)
|
||||
if v.Upc != "" {
|
||||
sku += fmt.Sprintf(`<center>upc码:%s</center><br>`, v.Upc)
|
||||
}
|
||||
skuList += sku
|
||||
}
|
||||
|
||||
// 统计信息
|
||||
statInfo := tempEndBig
|
||||
orderParams = append(orderParams, orderPrint.AllSkuTypeCount, orderPrint.AllSkuCount, orderPrint.StoreName, orderPrint.StoreTel, orderPrint.OfficialName)
|
||||
// 语音模板
|
||||
soundTemp := fmt.Sprintf(soundTemp, "老板,你有新订单了")
|
||||
orderFmt := soundTemp + pickupTemp + userInfo + skuList + statInfo
|
||||
return fmt.Sprintf(orderFmt, orderParams), nil
|
||||
}
|
||||
|
||||
// AddOrUpdateTemp 添加或者修改模板
|
||||
func (t *TempServer) AddOrUpdateTemp(param *tempModel.AddTemp) error {
|
||||
temp, err := dao.GetTempByName(param.UserId, param.TempName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(temp) > 0 {
|
||||
return errors.New("模板名称重复")
|
||||
}
|
||||
|
||||
// 解析模板
|
||||
var tempTagList []*tempModel.TempContext
|
||||
if err := json.Unmarshal([]byte(param.Temp), tempTagList); err != nil {
|
||||
return err
|
||||
}
|
||||
sort.Slice(tempTagList, func(i, j int) bool {
|
||||
if tempTagList[i].Rank > tempTagList[j].Rank {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
rankKey := ""
|
||||
contextStr := "{"
|
||||
for i := 0; i < len(tempTagList); i++ {
|
||||
if i != len(tempTagList)-1 {
|
||||
key := tempTagList[i].MatchContext + ","
|
||||
rankKey += key
|
||||
} else {
|
||||
rankKey += tempTagList[i].MatchContext
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(tempTagList); i++ {
|
||||
if i != len(tempTagList)-1 {
|
||||
contextStr += tempTagList[i].MatchContext + ":" + tempTagList[i].MatchContext + ","
|
||||
} else {
|
||||
contextStr += tempTagList[i].MatchContext + ":" + tempTagList[i].MatchContext + "}"
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
userTemp := &tempModel.SystemTemp{
|
||||
TempName: param.TempName,
|
||||
TempRank: rankKey,
|
||||
Temp: contextStr,
|
||||
UserId: param.UserId,
|
||||
TempType: param.TempType,
|
||||
TempSize: param.TempSize,
|
||||
LastOperator: param.UserId,
|
||||
DeletedAt: &utils.DefaultTimeValue,
|
||||
PrintSn: param.PrintSn,
|
||||
IsUse: param.IsUse,
|
||||
}
|
||||
|
||||
// 如果默认打印改模板,其他打印模板则改成不使用
|
||||
if param.IsUse == 1 {
|
||||
if err := dao.UpdateOtherTempStatus(param.UserId); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 新增
|
||||
if param.ID == 0 {
|
||||
userTemp.CreatedAt = &now
|
||||
userTemp.UpdatedAt = &now
|
||||
return dao.AddTemp(userTemp)
|
||||
}
|
||||
|
||||
// 修改
|
||||
userTemp.UpdatedAt = &now
|
||||
userTemp.ID = param.ID
|
||||
return dao.UpdateTemp(userTemp, []string{"id"})
|
||||
}
|
||||
|
||||
// DeleteTemp 删除模板
|
||||
func (t *TempServer) DeleteTemp(id int, userId string) error {
|
||||
return dao.DeleteTemp(id, userId)
|
||||
}
|
||||
|
||||
// QueryTempList 查询用户模板
|
||||
func (t *TempServer) QueryTempList(userId string) ([]*tempModel.SystemTemp, error) {
|
||||
return dao.SelectUserTemp(userId)
|
||||
}
|
||||
|
||||
// QuerySystemTemp 查询系统模板
|
||||
func (t *TempServer) QuerySystemTemp() ([]*tempModel.SystemTemp, error) {
|
||||
return dao.QuerySystemTemp()
|
||||
}
|
||||
|
||||
// SwitchTemp 切换使用模板
|
||||
func (t *TempServer) SwitchTemp(userId string, tempId int) error {
|
||||
return dao.SwitchTemp2User(tempId, userId)
|
||||
}
|
||||
440
services/print_server/app_server/temp_config.go
Normal file
440
services/print_server/app_server/temp_config.go
Normal file
@@ -0,0 +1,440 @@
|
||||
package app_server
|
||||
|
||||
import (
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-print/dao"
|
||||
"git.rosy.net.cn/jx-print/globals"
|
||||
tempModel "git.rosy.net.cn/jx-print/model/app_model"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var SystemTemp map[string]*tempModel.SystemTemp
|
||||
|
||||
func init() {
|
||||
var sysTemp = TempServer{}
|
||||
sysTempList, err := sysTemp.QuerySystemTemp()
|
||||
if err != nil {
|
||||
globals.SugarLogger.Debug("query system temp err :", err)
|
||||
return
|
||||
}
|
||||
temp := make(map[string]*tempModel.SystemTemp, 0)
|
||||
for _, v := range sysTempList {
|
||||
temp[v.TempSize] = v
|
||||
SystemTemp[v.TempSize] = v
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
param := &tempModel.SystemTemp{
|
||||
CreatedAt: &now,
|
||||
UpdatedAt: &now,
|
||||
LastOperator: "system",
|
||||
DeletedAt: &utils.DefaultTimeValue,
|
||||
TempName: "system",
|
||||
TempRank: SystemTempKey,
|
||||
Temp: "",
|
||||
UserId: "system_user",
|
||||
TempType: tempModel.TempTypeMerchant,
|
||||
TempSize: tempModel.SystemTempSizeBig,
|
||||
PrintSn: "system",
|
||||
IsUse: 1,
|
||||
}
|
||||
|
||||
// 初始化大字体模板
|
||||
if _, v := temp[tempModel.SystemTempSizeBig]; !v {
|
||||
param.TempName += tempModel.SystemTempSizeBig
|
||||
param.Temp = SystemTempValue
|
||||
if err := dao.AddTemp(param); err != nil {
|
||||
globals.SugarLogger.Debug("init system temp err :", err)
|
||||
}
|
||||
SystemTemp[tempModel.SystemTempSizeBig] = param
|
||||
}
|
||||
|
||||
// 初始化中字体模板
|
||||
if _, v := temp[tempModel.SystemTempSizeMedium]; !v {
|
||||
param.TempName += tempModel.SystemTempSizeMedium
|
||||
medium := strings.Replace(SystemTempValue, "<b>", "<hb>", -1)
|
||||
medium2 := strings.Replace(medium, "</b>", "</hb>", -1)
|
||||
param.Temp = medium2
|
||||
if err := dao.AddTemp(param); err != nil {
|
||||
globals.SugarLogger.Debug("init system temp err :", err)
|
||||
}
|
||||
if err := dao.AddTemp(param); err != nil {
|
||||
globals.SugarLogger.Debug("init system temp err :", err)
|
||||
}
|
||||
SystemTemp[tempModel.SystemTempSizeMedium] = param
|
||||
}
|
||||
|
||||
// 初始化小字体模板
|
||||
if _, v := temp[tempModel.SystemTempSizeSmall]; !v {
|
||||
param.TempName += tempModel.SystemTempSizeSmall
|
||||
medium := strings.Replace(SystemTempValue, "<b>", " ", -1)
|
||||
medium2 := strings.Replace(medium, "</b>", " ", -1)
|
||||
param.Temp = medium2
|
||||
if err := dao.AddTemp(param); err != nil {
|
||||
globals.SugarLogger.Debug("init system temp err :", err)
|
||||
}
|
||||
if err := dao.AddTemp(param); err != nil {
|
||||
globals.SugarLogger.Debug("init system temp err :", err)
|
||||
}
|
||||
SystemTemp[tempModel.SystemTempSizeSmall] = param
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SystemTempKey 系统数据库模板排序
|
||||
const (
|
||||
//SystemTempKey 公共参数 EBaiOrderNo= vendorName EBaiVendorName = vendorOrderNo
|
||||
SystemTempKey = "sound,eBailOrderNo,payOrderTime,trySendTime,orderNo,businessType,vendorName,eBaiCode,qRCOrder,eBaiVendorName,eBaiOrderNo,consigneeName," +
|
||||
"consigneeMobile,consigneeAddress,buyerComment,skuName,skuNumber,skuPrice,skuAllPrice,allSkuTypeCount,allSkuCount,storeName,storeTel,officialName"
|
||||
SystemTempValue = "{" +
|
||||
"sound:" + Sound + "," +
|
||||
"eBailOrderNo:" + EBailOrderNo + "," +
|
||||
"payOrderTime:" + PayOrderTime + "," +
|
||||
"trySendTime:" + TrySendTime + "," +
|
||||
"orderNo:" + OrderNo + "," +
|
||||
"businessType:" + BusinessType + "," +
|
||||
"vendorName:" + VendorName + "," +
|
||||
"eBaiCode:" + EBaiCode + "," +
|
||||
"qRCOrder:" + QRCOrder + "," +
|
||||
"eBaiVendorName:" + EBaiVendorName + "," +
|
||||
"eBaiOrderNo:" + EBaiOrderNo + "," +
|
||||
"consigneeName:" + ConsigneeName + "," +
|
||||
"consigneeMobile:" + ConsigneeMobile + "," +
|
||||
"consigneeAddress:" + ConsigneeAddress + "," +
|
||||
"buyerComment:" + BuyerComment + "," +
|
||||
"skuName:" + SkuName + "," +
|
||||
"skuNumber:" + SkuNumber + "," +
|
||||
"skuPrice:" + SkuPrice + "," +
|
||||
"skuAllPrice:" + SkuAllPrice + "," +
|
||||
"allSkuTypeCount:" + AllSkuTypeCount + "," +
|
||||
"allSkuCount:" + AllSkuCount + "," +
|
||||
"storeName:" + StoreName + "," +
|
||||
"storeTel:" + StoreTel + "," +
|
||||
"officialName:" + OfficialName +
|
||||
"}"
|
||||
|
||||
Sound = `<br><sound>%s</sound><br>`
|
||||
|
||||
EBailOrderNo = `<center><b>%s</b></center><br><br>
|
||||
<center>手机买菜上京西</center><br>
|
||||
<center>极速到家送惊喜</center><br>
|
||||
--------------------------------<br>`
|
||||
PayOrderTime = ` <b>下单时间: %s</b><br>`
|
||||
TrySendTime = ` <b>预计送达: %s</b><br>`
|
||||
OrderNo = ` <b>订单编号: %s</b><br>`
|
||||
BusinessType = `<center><b>预订单</b></center><br>`
|
||||
|
||||
VendorName = `<br><b>%s`
|
||||
EBaiCode = `#%s</b><br>`
|
||||
|
||||
QRCOrder = `<qrc>%s</qrc><br>`
|
||||
EBaiVendorName = `<b>%s:`
|
||||
EBaiOrderNo = `%s</b><br><br>`
|
||||
ConsigneeName = ` <b>客户: %s<br>`
|
||||
ConsigneeMobile = ` <b>电话: %s<br>`
|
||||
ConsigneeAddress = ` <b>地址: %s<br><br>`
|
||||
|
||||
BuyerComment = ` <b>客户备注:</b><br><b>%s</b><br><br>
|
||||
商品明细:<br>
|
||||
品名 数量 单价 小计<br>
|
||||
--------------------------------<br>`
|
||||
SkuName = `<b>%s</b><br>`
|
||||
SkuNumber = `<b>x%s</b>`
|
||||
SkuPrice = ` <b>¥%s</b>`
|
||||
SkuAllPrice = ` <b>¥%s</b><br>`
|
||||
|
||||
AllSkuTypeCount = `<br><br><b>共%s种,`
|
||||
AllSkuCount = `%s件商品</b><br>--------------------------------<br>`
|
||||
|
||||
StoreName = `<center><b>商品质量问题请联系:</b></center><br>
|
||||
<center><b>%s:`
|
||||
StoreTel = `%s</b></center><br><br>
|
||||
更多信息请关注官方微信: `
|
||||
|
||||
OfficialName = `<b>%s</b><br><br><br>
|
||||
--------------------------------<br>
|
||||
--------------------------------<br><br>`
|
||||
)
|
||||
|
||||
// 小字体系统模板
|
||||
const (
|
||||
// 模板开始
|
||||
tempBegin = `
|
||||
<center><b>%s</b></center>
|
||||
<br>
|
||||
<br>
|
||||
<center>手机买菜上京西</center>
|
||||
<br>
|
||||
<center>极速到家送惊喜</center>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
下单时间: %s
|
||||
<br>
|
||||
预计送达: %s
|
||||
<br>
|
||||
订单编号: %s
|
||||
<br>`
|
||||
// 是否为预订单
|
||||
tempBusiness = `<center><b>预订单</b></center><br>`
|
||||
tempBegin2 = `
|
||||
<br>
|
||||
<b>%s#%s</b>
|
||||
<br>
|
||||
<qrc>%s</qrc>
|
||||
<br>`
|
||||
tempEBail = `<b>饿百取货码%s:%s</b><br><br>`
|
||||
tempBegin3 = `
|
||||
<br>
|
||||
<br>
|
||||
客户: %s
|
||||
<br>
|
||||
电话: %s
|
||||
<br>
|
||||
地址: %s
|
||||
<br>
|
||||
<br>
|
||||
客户备注:
|
||||
<br>
|
||||
<b>%s</b>
|
||||
<br>
|
||||
<br>
|
||||
商品明细:
|
||||
<br>
|
||||
品名 数量 单价 小计
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
`
|
||||
// 模板结束
|
||||
tempEnd = `<br>
|
||||
<br>
|
||||
共%s种,%s件商品
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<center><hb>商品质量问题请联系:</hb></center>
|
||||
<br>
|
||||
<center><hb>%s:%s</hb></center>
|
||||
<br>
|
||||
<br>
|
||||
更多信息请关注官方微信: %s
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<br>
|
||||
`
|
||||
|
||||
// 模板商品
|
||||
skuListTemp = `%s
|
||||
<br>
|
||||
x%s ¥%s ¥%s
|
||||
<br>
|
||||
`
|
||||
soundTemp = `<br><sound>%s</sound>`
|
||||
)
|
||||
|
||||
// 中字体系统模板
|
||||
const (
|
||||
// 模板开始
|
||||
tempBeginMiddle = `
|
||||
<center><b>%s</b></center>
|
||||
<br>
|
||||
<br>
|
||||
<center>手机买菜上京西</center>
|
||||
<br>
|
||||
<center>极速到家送惊喜</center>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<wb>下单时间: %s</wb>
|
||||
<br>
|
||||
<wb>预计送达: %s</wb>
|
||||
<br>
|
||||
<wb>订单编号: %s</wb>
|
||||
<br>`
|
||||
// 是否为预订单
|
||||
tempBusinessMiddle = `<center><b>预订单</b></center><br>`
|
||||
tempBegin2Middle = `
|
||||
<br>
|
||||
<b>%s#%s</b>
|
||||
<br>
|
||||
<qrc>%s</qrc>
|
||||
<br>`
|
||||
tempEBailMiddle = `<b>%s:%s</b><br><br>`
|
||||
tempBegin3Middle = `
|
||||
<br>
|
||||
<br>
|
||||
<wb>客户: %s</wb>
|
||||
<br>
|
||||
<wb>电话: %s</wb>
|
||||
<br>
|
||||
<wb>地址: %s</wb>
|
||||
<br>
|
||||
<br>
|
||||
<wb>客户备注:</wb>
|
||||
<br>
|
||||
<b>%s</b>
|
||||
<br>
|
||||
<br>
|
||||
<wb>商品明细:</wb>
|
||||
<br>
|
||||
品名 数量 单价 小计
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
`
|
||||
// 模板结束
|
||||
tempEndMiddle = `<br>
|
||||
<br>
|
||||
<wb>共%s种,%s件商品</wb>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<center><hb>商品质量问题请联系:</hb></center>
|
||||
<br>
|
||||
<center><hb>%s:%s</hb></center>
|
||||
<br>
|
||||
<br>
|
||||
更多信息请关注官方微信: %s
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<br>
|
||||
`
|
||||
|
||||
// 模板商品
|
||||
skuListTempMiddle = `<wb>%s</wb>
|
||||
<br>
|
||||
<wb>x%s</wb> <wb>¥%s</wb> <wb>¥%s</wb>
|
||||
<br>
|
||||
`
|
||||
)
|
||||
|
||||
// 大字体系统模板
|
||||
const (
|
||||
// 模板开始
|
||||
tempBeginBig = `
|
||||
<center><b>%s</b></center>
|
||||
<br>
|
||||
<br>
|
||||
<center>手机买菜上京西</center>
|
||||
<br>
|
||||
<center>极速到家送惊喜</center>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<b>下单时间: %s</b>
|
||||
<br>
|
||||
<b>预计送达: %s</b>
|
||||
<br>
|
||||
<b>订单编号: %s</b>
|
||||
<br>`
|
||||
// 是否为预订单
|
||||
tempBusinessBig = `<center><b>预订单</b></center><br>`
|
||||
tempBegin2Big = `
|
||||
<br>
|
||||
<b>%s#%s</b>
|
||||
<br>
|
||||
<qrc>%s</qrc>
|
||||
<br>`
|
||||
tempEBailBig = `<b>%s:%s</b><br><br>`
|
||||
tempBegin3Big = `
|
||||
<br>
|
||||
<br>
|
||||
<b>客户: %s</b>
|
||||
<br>
|
||||
<b>电话: %s</b>
|
||||
<br>
|
||||
<b>地址: %s</b>
|
||||
<br>
|
||||
<br>
|
||||
<b>客户备注:</b>
|
||||
<br>
|
||||
<b>%s</b>
|
||||
<br>
|
||||
<br>
|
||||
<b>商品明细:</b>
|
||||
<br>
|
||||
品名 数量 单价 小计
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
`
|
||||
// 模板结束
|
||||
tempEndBig = `<br>
|
||||
<br>
|
||||
<b>共%s种,%s件商品</b>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<center><b>商品质量问题请联系:</b></center>
|
||||
<br>
|
||||
<center><b>%s:%s</b></center>
|
||||
<br>
|
||||
<br>
|
||||
更多信息请关注官方微信: %s
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
--------------------------------
|
||||
<br>
|
||||
<br>
|
||||
`
|
||||
|
||||
// 模板商品
|
||||
skuListTempBig = `<b>%s</b>
|
||||
<br>
|
||||
<b>x%s</b> <b>¥%s</b> <b>¥%s</b>
|
||||
<br>
|
||||
`
|
||||
)
|
||||
|
||||
type SkuListPrintOrder struct {
|
||||
SkuName string `json:"skuName"` // 商品名称
|
||||
SkuCount string `json:"skuCount"` // 商品数量
|
||||
SalePrice string `json:"salePrice"` // 单价
|
||||
TotalCountPrice string `json:"totalCountPrice"` // 总价
|
||||
Upc string `json:"upc"` // 条形码
|
||||
}
|
||||
|
||||
type JXPrintData struct {
|
||||
EBailOrderNo string `json:"e_bail_order_no"` // 饿百取货码(品牌名称)
|
||||
BusinessType string `json:"business_type"` // 是否为预定单 2-是/1-否
|
||||
PayOrderTime string `json:"pay_order_time"` // 下单时间
|
||||
TrySendTime string `json:"try_send_time"` // 预计送达时间
|
||||
OrderNo string `json:"order_no"` // 订单编号
|
||||
VendorName string `json:"vendor_name"` // 订单来源平台名称
|
||||
VendorID string `json:"vendor_id"` // 订单来源平台Id
|
||||
VendorOrderNo string `json:"vendor_order_no"` // 订单序号
|
||||
EBaiCode string `json:"e_bai_code"` // 饿百取货码
|
||||
QRCOrder string `json:"qrc_order"` // 订单二维码单号,还是订单Id
|
||||
ConsigneeName string `json:"consignee_name"` // 客户名称
|
||||
ConsigneeMobile string `json:"consignee_mobile"` // 客户电话
|
||||
ConsigneeAddress string `json:"consignee_address"` // 客户地址
|
||||
BuyerComment string `json:"buyer_comment"` // 客户备注
|
||||
SkuList []*SkuListPrintOrder `json:"sku_list"` // 商品列表
|
||||
SkuName string `json:"sku_name"` // 商品名称
|
||||
SkuCount string `json:"sku_count"` // 商品件数
|
||||
SkuOnePrice string `json:"sku_one_price"` // 商品单价
|
||||
SkuAllPrice string `json:"sku_all_price"` // 商品总价 = 商品件数 x 商品件数
|
||||
AllSkuTypeCount string `json:"all_sku_type_count"` // 商品种类
|
||||
AllSkuCount string `json:"all_sku_count"` // 商品总数量
|
||||
UserPayMoney string `json:"user_pay_money"` // 用户支付
|
||||
StoreName string `json:"store_name"` // 门店名称
|
||||
StoreTel string `json:"store_tel"` // 门店电话
|
||||
OfficialName string `json:"official_name"` // 官方名称
|
||||
BigFont string `json:"big_font"` // 是否为大字体
|
||||
PrintNumber string `json:"print_number"` // 打印次数
|
||||
}
|
||||
163
services/print_server/app_server/wx_login.go
Normal file
163
services/print_server/app_server/wx_login.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package app_server
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-print/dao"
|
||||
"git.rosy.net.cn/jx-print/globals"
|
||||
"git.rosy.net.cn/jx-print/model"
|
||||
wxLogin "git.rosy.net.cn/jx-print/model/app_model"
|
||||
"git.rosy.net.cn/jx-print/services/api"
|
||||
"github.com/gin-gonic/gin"
|
||||
xaes "github.com/go-pay/gopay/pkg/aes"
|
||||
"github.com/go-pay/gopay/wechat"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserLogin struct {
|
||||
}
|
||||
|
||||
// WxLogin 授权登录
|
||||
func (u *UserLogin) WxLogin(ctx *gin.Context, code, phone string) (*model.User, error) {
|
||||
// 生成openId
|
||||
openObj, err := wechat.GetOauth2AccessToken(ctx, wxLogin.WeChatAPPID, wxLogin.WeChatAPPSecret, code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if openObj.Errcode != 0 {
|
||||
return nil, errors.New(openObj.Errmsg)
|
||||
}
|
||||
|
||||
// 检查用户是否存在
|
||||
users, err := dao.GetUsers(globals.GetDB(), "", "", phone, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(users) > 1 {
|
||||
return nil, errors.New("数据异常,用户电话不唯一,联系管理员")
|
||||
}
|
||||
|
||||
// 获取用户信息,是否注册
|
||||
userInfo, err := wechat.GetOauth2UserInfo(ctx, openObj.AccessToken, openObj.Openid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var userObj *model.User
|
||||
timeNow := time.Now()
|
||||
switch len(users) {
|
||||
case 0:
|
||||
// 用户不存在,创建并返回用户
|
||||
userBase := &model.User{
|
||||
CreatedAt: &timeNow,
|
||||
UpdatedAt: &timeNow,
|
||||
LastOperator: "系统新增",
|
||||
DeletedAt: &utils.DefaultTimeValue,
|
||||
UserID: utils.GetUUID(),
|
||||
Password: "",
|
||||
Name: userInfo.Nickname,
|
||||
Mobile: phone,
|
||||
Email: "",
|
||||
Avatar: userInfo.Headimgurl,
|
||||
Status: 1,
|
||||
Type: 1,
|
||||
Company: "",
|
||||
CityCode: 0,
|
||||
DistrictCode: 0,
|
||||
Address: "",
|
||||
IDCardNo: "",
|
||||
Remark: "",
|
||||
LastLoginAt: &timeNow,
|
||||
LastLoginIP: ctx.ClientIP(),
|
||||
LastLoginType: model.OrderOriginWxMini,
|
||||
OpenId: userInfo.Openid,
|
||||
UnionId: userInfo.Unionid,
|
||||
}
|
||||
if err := dao.CreateUserWx(userBase); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userObj = userBase
|
||||
case 1:
|
||||
// 用户使用电话号码登录,未使用微信登录
|
||||
if users[0].OpenId == "" {
|
||||
users[0].Name = userInfo.Nickname
|
||||
users[0].Avatar = userInfo.Headimgurl
|
||||
users[0].OpenId = userInfo.Openid
|
||||
users[0].UnionId = userInfo.Unionid
|
||||
}
|
||||
// 用户存在,判断用户
|
||||
users[0].UpdatedAt = &timeNow
|
||||
users[0].LastOperator = users[0].Name
|
||||
users[0].LastLoginIP = ctx.ClientIP()
|
||||
if err := dao.UpdateUserWx(users[0], []string{"updated_at", "last_operator", "last_login_ip", "name", "avatar", "open_id", "union_id"}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userObj = users[0]
|
||||
}
|
||||
|
||||
return userObj, err
|
||||
}
|
||||
|
||||
// GetUserPhoneNum 解密用户手机号
|
||||
func (u *UserLogin) GetUserPhoneNum(param *wxLogin.WeChatPhoneNumberParam) (string, error) {
|
||||
sessionInfo, err := api.WeixinMiniAPI.SNSCode2Session(param.Code)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
weChatLogin := new(wechat.UserPhone)
|
||||
if err := DecryptOpenDataToStruct(param.EncryptedData, param.IV, sessionInfo.SessionKey, weChatLogin); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return weChatLogin.PhoneNumber, nil
|
||||
}
|
||||
|
||||
// DecryptOpenDataToStruct 解密开放数据到结构体
|
||||
// encryptedData:包括敏感数据在内的完整用户信息的加密数据,小程序获取到
|
||||
// iv:加密算法的初始向量,小程序获取到
|
||||
// sessionKey:会话密钥,通过 gopay.Code2Session() 方法获取到
|
||||
// beanPtr:需要解析到的结构体指针,操作完后,声明的结构体会被赋值
|
||||
// 文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
|
||||
func DecryptOpenDataToStruct(encryptedData, iv, sessionKey string, beanPtr interface{}) (err error) {
|
||||
if encryptedData == "" || iv == "" || sessionKey == "" {
|
||||
return errors.New("input params can not null")
|
||||
}
|
||||
var (
|
||||
cipherText, aesKey, ivKey, plainText []byte
|
||||
block cipher.Block
|
||||
blockMode cipher.BlockMode
|
||||
)
|
||||
beanValue := reflect.ValueOf(beanPtr)
|
||||
if beanValue.Kind() != reflect.Ptr {
|
||||
return errors.New("传入beanPtr类型必须是以指针形式")
|
||||
}
|
||||
if beanValue.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("传入interface{}必须是结构体")
|
||||
}
|
||||
cipherText, _ = base64.StdEncoding.DecodeString(encryptedData)
|
||||
aesKey, _ = base64.StdEncoding.DecodeString(sessionKey)
|
||||
ivKey, _ = base64.StdEncoding.DecodeString(iv)
|
||||
if len(cipherText)%len(aesKey) != 0 {
|
||||
return errors.New("encryptedData is error")
|
||||
}
|
||||
if block, err = aes.NewCipher(aesKey); err != nil {
|
||||
return fmt.Errorf("aes.NewCipher:%w", err)
|
||||
}
|
||||
blockMode = cipher.NewCBCDecrypter(block, ivKey)
|
||||
plainText = make([]byte, len(cipherText))
|
||||
blockMode.CryptBlocks(plainText, cipherText)
|
||||
if len(plainText) > 0 {
|
||||
plainText = xaes.PKCS7UnPadding(plainText)
|
||||
}
|
||||
if err = json.Unmarshal(plainText, beanPtr); err != nil {
|
||||
return fmt.Errorf("json.Marshal(%s):%w", string(plainText), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
240
services/print_server/app_server/wx_print.go
Normal file
240
services/print_server/app_server/wx_print.go
Normal file
@@ -0,0 +1,240 @@
|
||||
package app_server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-print/dao"
|
||||
"git.rosy.net.cn/jx-print/globals"
|
||||
"git.rosy.net.cn/jx-print/model"
|
||||
"git.rosy.net.cn/jx-print/putils"
|
||||
"time"
|
||||
)
|
||||
|
||||
func AddPrinters(tokenInfo *model.TokenInfo, appID int, printInfo []*model.PrintInfo) (err error) {
|
||||
var (
|
||||
db = globals.GetDB()
|
||||
errs []error
|
||||
now = time.Now()
|
||||
)
|
||||
if len(printInfo) > 50 {
|
||||
return fmt.Errorf("每次最多添加50台!")
|
||||
}
|
||||
if apps, _ := dao.GetApps(db, appID, tokenInfo.User.UserID, ""); len(apps) == 0 {
|
||||
return fmt.Errorf("未查询到此应用!app_id:%d", appID)
|
||||
}
|
||||
for _, v := range printInfo {
|
||||
if v.PrintNo == "" {
|
||||
errs = append(errs, fmt.Errorf("请输入正确的打印机编号!print_no :%s 。", v.PrintNo))
|
||||
continue
|
||||
}
|
||||
printers, _ := dao.GetPrinters(db, appID, v.PrintNo, 0, 0, 0)
|
||||
if len(printers) > 0 {
|
||||
errs = append(errs, fmt.Errorf("此打印机已被其他应用绑定!print_no :%s 。", v.PrintNo))
|
||||
continue
|
||||
}
|
||||
printer := &model.Printer{
|
||||
CreatedAt: &now,
|
||||
UpdatedAt: &now,
|
||||
DeletedAt: &utils.DefaultTimeValue,
|
||||
LastOperator: tokenInfo.User.Name,
|
||||
AppID: appID,
|
||||
PrintNo: v.PrintNo,
|
||||
Name: v.Name,
|
||||
PrintKey: v.PrintKey,
|
||||
Status: model.PrinterStatusNormal,
|
||||
IsOnline: model.PrinterOffline,
|
||||
Sound: "sounda",
|
||||
Volume: 4,
|
||||
UserId: tokenInfo.User.UserID,
|
||||
}
|
||||
if err = dao.Insert(db, printer); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
err = putils.BuildErr(errs)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func GetPrinters(appID int, printNo, name string, status, isOnline, offset, pageSize int, userId string) (page *model.PagedInfo, err error) {
|
||||
return dao.GetPrintersPage(globals.GetDB(), appID, printNo, name, status, isOnline, offset, pageSize, userId)
|
||||
}
|
||||
|
||||
func DelPrinters(appID int, tokenInfo *model.TokenInfo, printNos []string) (err error) {
|
||||
var (
|
||||
db = globals.GetDB()
|
||||
errs []error
|
||||
now = time.Now()
|
||||
)
|
||||
if len(printNos) > 50 {
|
||||
return fmt.Errorf("每次最多删除50台!")
|
||||
}
|
||||
if apps, _ := dao.GetApps(db, appID, tokenInfo.User.UserID, ""); len(apps) == 0 {
|
||||
return fmt.Errorf("未查询到此应用!app_id:%d", appID)
|
||||
}
|
||||
for _, v := range printNos {
|
||||
if v == "" {
|
||||
errs = append(errs, fmt.Errorf("请输入正确的打印机编号!print_no :%s 。", v))
|
||||
continue
|
||||
}
|
||||
printers, _ := dao.GetPrinters(db, appID, v, 0, 0, 0)
|
||||
if len(printers) == 0 {
|
||||
errs = append(errs, fmt.Errorf("未在该应用下查到此打印机!app_id: %d, print_no: %s", appID, v))
|
||||
continue
|
||||
}
|
||||
|
||||
if printers[0].UserId != tokenInfo.User.UserID {
|
||||
errs = append(errs, fmt.Errorf("该appId不在用户账号下!app_id: %d, print_no: %s", appID, v))
|
||||
continue
|
||||
}
|
||||
|
||||
printer := printers[0]
|
||||
printer.DeletedAt = &now
|
||||
printer.LastOperator = tokenInfo.User.Name
|
||||
if err = dao.Update(db, printer, model.FieldLastOperator, model.FieldDeletedAt); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
err = putils.BuildErr(errs)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func UpdatePrinter(appID int, tokenInfo *model.TokenInfo, printNo, name, sound string, volume int) (err error) {
|
||||
var (
|
||||
db = globals.GetDB()
|
||||
now = time.Now()
|
||||
fields []string
|
||||
)
|
||||
if apps, _ := dao.GetApps(db, appID, tokenInfo.User.UserID, ""); len(apps) == 0 {
|
||||
return fmt.Errorf("未查询到此应用!app_id:%d", appID)
|
||||
}
|
||||
|
||||
printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0, 0)
|
||||
if len(printers) == 0 {
|
||||
return fmt.Errorf("未在该应用下查到此打印机!app_id: %d, print_no: %s", appID, printNo)
|
||||
}
|
||||
if printers[0].UserId != tokenInfo.User.UserID {
|
||||
return fmt.Errorf("该appId不在用户账号下!app_id: %d, print_no: %s", appID, printers[0].PrintNo)
|
||||
}
|
||||
|
||||
printer := printers[0]
|
||||
printer.UpdatedAt = &now
|
||||
printer.LastOperator = tokenInfo.User.Name
|
||||
fields = append(fields, model.FieldUpdatedAt, model.FieldLastOperator)
|
||||
if name != printer.Name {
|
||||
printer.Name = name
|
||||
fields = append(fields, "name")
|
||||
}
|
||||
|
||||
if sound != printer.Sound {
|
||||
printer.Sound = sound
|
||||
fields = append(fields, "sound")
|
||||
}
|
||||
if volume != printer.Volume {
|
||||
printer.Volume = volume
|
||||
fields = append(fields, "volume")
|
||||
}
|
||||
if err = dao.Update(db, printer, fields...); err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// TestPrint 测试打印
|
||||
func TestPrint(appID int, tokenInfo *model.TokenInfo, printNo string, orderNo string, content string) (msgID string, err error) {
|
||||
var (
|
||||
db = globals.GetDB()
|
||||
now = time.Now()
|
||||
)
|
||||
msgID = now.Format("20060102150405") + "_" + putils.RandStringBytesWithNumber(8)
|
||||
if apps, _ := dao.GetApps(db, appID, tokenInfo.User.UserID, ""); len(apps) == 0 {
|
||||
return "", fmt.Errorf("未查询到此应用!app_id:%d", appID)
|
||||
}
|
||||
printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0, 0)
|
||||
if len(printers) == 0 {
|
||||
return "", fmt.Errorf("未在该应用下查到此打印机!app_id: %d, print_no: %s", appID, printNo)
|
||||
}
|
||||
if printers[0].UserId != tokenInfo.User.UserID {
|
||||
return "", fmt.Errorf("该appId不在用户账号下!app_id: %d, print_no: %s", appID, printers[0].PrintNo)
|
||||
}
|
||||
|
||||
printMsg := &model.PrintMsg{
|
||||
CreatedAt: &now,
|
||||
UpdatedAt: &now,
|
||||
LastOperator: tokenInfo.User.Name,
|
||||
DeletedAt: &utils.DefaultTimeValue,
|
||||
PrintNo: printNo,
|
||||
OrderNo: orderNo,
|
||||
Content: content,
|
||||
MsgID: msgID,
|
||||
}
|
||||
err = dao.Insert(db, printMsg)
|
||||
return msgID, err
|
||||
}
|
||||
|
||||
func GetPrintMessages(appID int, tokenInfo *model.TokenInfo, printNo, msgID string, beginAt, endAt string, offset, pageSize int) (page *model.PagedInfo, err error) {
|
||||
var (
|
||||
db = globals.GetDB()
|
||||
)
|
||||
if apps, _ := dao.GetApps(db, appID, tokenInfo.User.UserID, ""); len(apps) == 0 {
|
||||
return nil, fmt.Errorf("未查询到此应用!app_id:%d", appID)
|
||||
}
|
||||
printers, _ := dao.GetPrinters(db, appID, printNo, 0, 0, 0)
|
||||
if len(printers) == 0 {
|
||||
return nil, fmt.Errorf("未在该应用下查到此打印机!app_id: %d, print_no: %s", appID, printNo)
|
||||
}
|
||||
return dao.GetPrintMessagesPage(db, printNo, msgID, beginAt, endAt, offset, pageSize)
|
||||
}
|
||||
|
||||
type GetPrinterReportResult struct {
|
||||
WeekPrintCount int `json:"week_print_count"`
|
||||
DayPrintCount int `json:"day_print_count"`
|
||||
DayUnPrintCount int `json:"day_un_print_count"`
|
||||
OnlinePrinterCount int `json:"online_printer_count"`
|
||||
OfflinePrinterCount int `json:"offline_printer_count"`
|
||||
FlowPrinterCount int `json:"flow_printer_count"`
|
||||
PaperPrinterCount int `json:"paper_printer_count"`
|
||||
}
|
||||
|
||||
func GetPrinterReport(tokenInfo *model.TokenInfo) (getPrinterReportResult *GetPrinterReportResult, err error) {
|
||||
var (
|
||||
db = globals.GetDB()
|
||||
weekCount, DayCount, DayUnCount = 0, 0, 0
|
||||
onlineC, offlineC, flowC, paperC = 0, 0, 0, 0
|
||||
)
|
||||
getPrinterReportResult = &GetPrinterReportResult{}
|
||||
apps, _ := dao.GetApps(db, 0, tokenInfo.User.UserID, "")
|
||||
if len(apps) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
for _, app := range apps {
|
||||
printers, _ := dao.GetPrinters(db, app.ID, "", 0, 0, 0)
|
||||
for _, printer := range printers {
|
||||
weeks, _ := dao.GetPrintMessages(db, printer.PrintNo, "", utils.Time2Str(time.Now().AddDate(0, 0, -7)), utils.Time2Str(time.Now()), 0)
|
||||
weekCount += len(weeks)
|
||||
days, _ := dao.GetPrintMessages(db, printer.PrintNo, "", utils.Time2Str(time.Now().AddDate(0, 0, -1)), utils.Time2Str(time.Now()), 0)
|
||||
DayCount += len(days)
|
||||
dayUns, _ := dao.GetPrintMessages(db, printer.PrintNo, "", utils.Time2Str(time.Now().AddDate(0, 0, -1)), utils.Time2Str(time.Now()), 1)
|
||||
DayUnCount += len(dayUns)
|
||||
}
|
||||
onlines, _ := dao.GetPrinters(db, app.ID, "", model.PrinterOnline, 0, 0)
|
||||
onlineC += len(onlines)
|
||||
offlines, _ := dao.GetPrinters(db, app.ID, "", model.PrinterOffline, 0, 0)
|
||||
offlineC += len(offlines)
|
||||
flows, _ := dao.GetPrinters(db, app.ID, "", 0, 0, 1)
|
||||
flowC += len(flows)
|
||||
papers, _ := dao.GetPrinters(db, app.ID, "", model.PrinterStatusWithouPaper, 0, 0)
|
||||
paperC += len(papers)
|
||||
}
|
||||
getPrinterReportResult.WeekPrintCount = weekCount
|
||||
getPrinterReportResult.DayPrintCount = DayCount
|
||||
getPrinterReportResult.DayUnPrintCount = DayUnCount
|
||||
getPrinterReportResult.OnlinePrinterCount = onlineC
|
||||
getPrinterReportResult.OfflinePrinterCount = offlineC
|
||||
getPrinterReportResult.FlowPrinterCount = flowC
|
||||
getPrinterReportResult.PaperPrinterCount = paperC
|
||||
return getPrinterReportResult, err
|
||||
}
|
||||
Reference in New Issue
Block a user