package calloff import ( "errors" "fmt" "leit.com/leit_seat_aps/common" "strconv" "strings" "time" ) // SEQ 数据交换头 type UNB struct { Sender string // 发送方 Reciever string // 接收方 MsgTime time.Time // 消息时间 MsgCtrlPara string // 消息交互控制参数 ParseString string // 原始消息数据串 } // CALLOFF 数据消息头 type UNH struct { MsgId string // 消息标识ID MsgType string // 消息类型 DELJIT MsgTypeVersion string // 消息类型版本号 MsgTypeRelNo string // 消息类型版本释放号 ParseString string // 原始数据串 } // CALLOFF 数据消息开始 type BGM struct { MessageType int // 消息类型 30 = TOD / 221 = SEQ / 36 = CALLOFF DeliveryPlant int // 发运目标工厂 92 = BBA CheckSequence string // 检查排序号 ParseString string // 原始数据串 } // CALLOFF 数据消息日期时间信息 type DTM struct { DateTimeType int // 137 = 消息日期 / 42 = 计划开始装配时间 / 2 = SWET 客户要求的来料时间 DateTimeFormat int // 日期时间格式:203 = CCYYMMDDHHMM / 204 = CCYYMMDDHHMMSS MsgTime time.Time // 消息时间 MsgTimeFormat string // 消息时间格式 ParseString string // 原始数据串 } // CALLOFF 参考信息 type RFF struct { RefType string // CALLOFF = AAN / PARTFAMILY = ZZZ CallOffNum string // 发运排序号 PartFamily string // 零件族 ParseString string // 原始数据串 } // CALLOFF 数据消息名称地址信息 type NAD struct { Consignee string // 收货人 ConsigneePlant int // 收货厂编号 10 = Dadong / 66 = Shengbei / 88 = Tiexi ConsigneeCompany int // 收货公司编号 92 = BBA ParseString string // 原始数据串 } // CALLOFF 地点信息 // LOC+4+PD::92:00+PC::92:10’ // Location + 4=goods receipt place + PD=place of unloading :: 92 = BBA: Place of unloading // + PC=place of consumption :: 92 = BBA : Place of consumption type LOC struct { LocType int // 44 = 文档发出地 / 83 = 货物发运地 / 4 = 收货地 UnloadingPlace string // 卸货地点 ConsumeCompany int // 使用公司 ConsumePlant int // 使用工厂 ParseString string // 原始数据串 } // CALLOFF 排序号 type SEQ struct { SeqType int // 3=新建;1=变更;2=取消 Gir GIR ParseString string // 原始数据串 } // CALLOFF 排序订单相关信息 // 示例:GIR+4+43738111:AN+4173’ // Related Identification Numbers + 4=vehicle identification set // + EINSTEIN order number : AN=Manufacturing reference number // + Data string with free format vehicle identification = last 4 digits of check sequence number // out of BGM segment (BGM+36::92+00014173’) It can be used as vehicle identification like VIN in production release message type GIR struct { VehicleIdSet string // 车辆识别集 CustOrderNr string // 客户订单号 VehicleId string // 车辆识别号 ParseString string // 原始数据串 } // CALLOFF 数据消息尾 type UNT struct { DataRows int // 数据行数,从UNH到UNT总数 MsgId string // 消息标识 ParseString string // 原始数据串 } // CALLOFF 数据交换结束符 type UNZ struct { MsgCount int // 消息数 MsgRefId string // 消息参考号 ParseString string // 原始数据串 } // CALLOFF 消息对象 type CALLOFF struct { FileName string // TOD文件名 DataRows int // 包含数据行 UNH->UNT Unb UNB // 数据交换头 Unh UNH // 数据消息头 Bgm BGM // 数据消息开始 DtmMsg DTM // 数据消息日期时间信息 DtmDelivery DTM // 发运时间信息 RffCF RFF // 参考信息: 发运Calloff号 RffPF RFF // 参考信息:发运的PartFamily号 Nad NAD // 数据消息名称地址信息 Loc LOC // 地址信息 SeqList []SEQ // 数据消息的零件族信息:零件、零件族、供应组、数量等信息 Unt UNT // 数据消息尾 Unz UNZ // 数据消息交换结束 } func (unb *UNB) Parse(parseString string) (err error) { var ( kvlist []string kv4 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("UNB: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") if len(kvlist) < 5 { return errors.New("UNB: Key value length less than 5, failed to parse!") } kv4 = strings.Split(kvlist[4], ":") if len(kv4) < 2 { return errors.New("UNB: Key4 value length less than 2, failed to parse!") } // 填充值 unb.Sender = kvlist[2] // 发送方 unb.Reciever = kvlist[3] // 接收方 if unb.MsgTime, err = common.DateParse(kv4[0]+kv4[1], "ymdHi"); err != nil { return errors.New("UNB: Failed to get the MsgTime!") } unb.MsgCtrlPara = kvlist[5] // 消息控制参数 unb.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(unb.Sender) == "" { return errors.New("UNB: Sender is empty!") } if strings.TrimSpace(unb.Reciever) == "" { return errors.New("UNB: Reciever is empty!") } return } func (unb *UNB) Print() { fmt.Println("UNB | Sender:", unb.Sender, " | Reciever:", unb.Reciever, " | MsgTime:", unb.MsgTime, " | MsgCtrlPara:", unb.MsgCtrlPara) } func (unh *UNH) Parse(parseString string) (err error) { var ( kvlist []string kv2 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("UNH: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") kv2 = strings.Split(kvlist[2], ":") if len(kv2) < 3 { return errors.New("UNH: kv2 value length less than 3, failed to parse!") } // 填充值 unh.MsgId = kvlist[1] // 消息ID unh.MsgType = kv2[0] // 消息类型 unh.MsgTypeVersion = kv2[1] unh.MsgTypeRelNo = kv2[2] unh.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(unh.MsgId) == "" { return errors.New("UNH: MsgId is empty!") } if strings.TrimSpace(unh.MsgType) == "" { return errors.New("UNH: MsgType is empty!") } if strings.ToUpper(strings.TrimSpace(unh.MsgType)) != "DELJIT" { return errors.New("UNH: MsgType is not DELJIT!") } return } func (unh *UNH) Print() { fmt.Println("UNH | MsgId:", unh.MsgId, " | MsgType:", unh.MsgType) } // 示例:BGM+36::92+00200557' // 解析:+37生产下达36发运CallOff::92BBA+检查排序号(允许供应商检查所有请求已接收) func (bgm *BGM) Parse(parseString string) (err error) { var ( kvlist []string kv1 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("BGM: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") kv1 = strings.Split(kvlist[1], ":") if len(kv1) < 3 { return errors.New("BGM: kv1 value length less than 3, failed to parse!") } // 填充值 bgm.MessageType, _ = strconv.Atoi(kv1[0]) // 30=TOD;37生产下达 36发运 242=SEQ bgm.DeliveryPlant, _ = strconv.Atoi(kv1[2]) // 92 = BBA bgm.CheckSequence = kvlist[2] // 检查排序号 bgm.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(bgm.CheckSequence) == "" { return errors.New("BGM: CheckSequence is empty!") } return } func (bgm *BGM) Print() { fmt.Println("BGM | CheckSequence:", bgm.CheckSequence) } // 消息文档时间:DTM+137:200902201510:203' // 发运时间信息:DTM+2:200902231011:203' OR DTM+2:20090223101159:204' func (dtm *DTM) Parse(parseString string) (err error) { var ( kvlist []string kv1 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("DTM: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") kv1 = strings.Split(kvlist[1], ":") if len(kv1) < 3 { return errors.New("DTM: kv1 value length less than 3, failed to parse!") } // 填充值 dtm.DateTimeType, _ = strconv.Atoi(kv1[0]) // 时间格式 dtm.DateTimeFormat, _ = strconv.Atoi(kv1[2]) dtm.MsgTimeFormat = common.GetTimeFormatByType(dtm.DateTimeFormat) if dtm.MsgTime, err = common.DateParse(kv1[1], dtm.MsgTimeFormat); err != nil { return errors.New("DTM: Failed to get the MsgTime!") } dtm.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(dtm.MsgTimeFormat) == "" { return errors.New("DTM: MsgTimeFormat is empty!") } return } func (dtm *DTM) Print() { fmt.Println("DTM | DateTimeType:", dtm.DateTimeType, " | DateTimeFormat:", dtm.DateTimeFormat, " | MsgTime:", dtm.MsgTime) } // RFF+AAN:131642' => +AAN(Delivery CallOff号):131553 // RFF+ZZZ:STFKBR3 ' =>+ZZZ:零件族号(<8位) func (rff *RFF) Parse(parseString string) (err error) { var ( kvlist []string kv1 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("RFF: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") kv1 = strings.Split(kvlist[1], ":") if len(kv1) < 2 { return errors.New("RFF: kv1 value length less than 2, failed to parse!") } // 填充值 rff.ParseString = parseString switch strings.TrimSpace(kv1[0]) { case "AAN": rff.RefType = "CALLOFF" rff.CallOffNum = kv1[1] if strings.TrimSpace(rff.CallOffNum) == "" { return errors.New("RFF: CallOffNum is empty!") } case "ZZZ": rff.RefType = "PARTFAMILY" rff.PartFamily = kv1[1] // 零件族 if strings.TrimSpace(rff.PartFamily) == "" { return errors.New("RFF: Partfamily is empty!") } default: } return } func (rff *RFF) Print() { fmt.Println("RFF | CallOffNum:", rff.CallOffNum, "| Partfamily:", rff.PartFamily) } // 示例:NAD+CN+88::92 func (nad *NAD) Parse(parseString string) (err error) { var ( kvlist []string kv2 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("NAD: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") kv2 = strings.Split(kvlist[2], ":") if len(kv2) < 1 { return errors.New("NAD: kv2 value length less than 1, failed to parse!") } // 填充值 nad.Consignee = kvlist[1] // 收货人 nad.ConsigneePlant, _ = strconv.Atoi(kv2[0]) // 收货厂编号 10=Dadong,66=Shengbei;88=Tiexi nad.ConsigneeCompany, _ = strconv.Atoi(kv2[2]) // 收货公司编号 92 = BBA nad.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(nad.Consignee) == "" { return errors.New("NAD: Consignee is empty!") } if nad.ConsigneePlant <= 0 { return errors.New("NAD: ConsigneePlant is not existing!") } if nad.ConsigneeCompany <= 0 { return errors.New("NAD: ConsigneeCompany is not existing!") } return } func (nad *NAD) Print() { fmt.Println("NAD | Consignee:", nad.Consignee, " | ConsigneePlant:", nad.ConsigneePlant, " | ConsigneeCompany:", nad.ConsigneeCompany) } // 示例1:LOC+4+PD::92:00+PC::92:88' // +4收货地点标识+PD卸货地点::92BBA:00+PC消耗地点::92BBA:88Tiexi func (loc *LOC) Parse(parseString string) (err error) { var ( kvlist []string kv2 []string kv3 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("LOC: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") kv2 = strings.Split(kvlist[2], ":") if len(kv2) < 4 { return errors.New("LOC: kv2 value length less than 4, failed to parse!") } kv3 = strings.Split(kvlist[3], ":") if len(kv3) < 4 { return errors.New("LOC: kv3 value length less than 4, failed to parse!") } // 填充值 loc.LocType, _ = strconv.Atoi(kvlist[1]) // 44 = 文档发出地 / 83 = 货物发运地 / 4 = 收货地 loc.UnloadingPlace = kv2[2] loc.ConsumeCompany, _ = strconv.Atoi(kv3[2]) loc.ConsumePlant, _ = strconv.Atoi(kv3[3]) loc.ParseString = parseString // 校验关键字段是否为空 if loc.LocType <= 0 { return errors.New("LOC: LocType is empty!") } return } func (loc *LOC) Print() { fmt.Println("LOC | LocType:", loc.LocType, " | UnloadingPlace:", loc.UnloadingPlace, " | ConsumeCompany:", loc.ConsumeCompany, " | ConsumePlantSite:", loc.ConsumePlant) } // 示例:SEQ+3’ func (seq *SEQ) Parse(parseString string) (err error) { var ( kvlist []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("SEQ: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") // 填充值 seq.SeqType, _ = strconv.Atoi(kvlist[1]) // 3=新建;1=更新;2=取消 seq.ParseString = parseString // 校验关键字段是否为空 if seq.SeqType < 1 || seq.SeqType > 3 { return errors.New("SEQ: Unvalid seq type!") } return } func (seq *SEQ) Print() { fmt.Println("SEQ | SEQ + ", seq.SeqType) } // 示例:GIR+4+69472141:AN+0557' // +4车辆识别集+订单号订单类型(最后一位是订单类型):AN+车辆识别的自由文本 func (gir *GIR) Parse(parseString string) (err error) { var ( kvlist []string kv2 []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("GIR: parse string is empty!") } // 基于+分隔符来解析字符串 // GIR+1+00024391:AQ+00000966:ML+12373531:AN + GX38594 : VN kvlist = strings.Split(parseString, "+") kv2 = strings.Split(kvlist[2], ":") if len(kv2) < 2 { return errors.New("GIR: kv2 value length less than 2, failed to parse!") } // 填充值 gir.VehicleIdSet = kvlist[1] // 车辆识别集 gir.CustOrderNr = kv2[0] // 客户订单号 gir.VehicleId = kvlist[3] // 车辆识别号 gir.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(gir.CustOrderNr) == "" { return errors.New("GIR: CustOrderNr is empty!") } if strings.TrimSpace(gir.VehicleId) == "" { return errors.New("GIR: VehicleId is empty!") } return } func (gir *GIR) Print() { fmt.Println("GIR | CustOrderNr:", gir.CustOrderNr, " | VehicleId:", gir.VehicleId) } func (unt *UNT) Parse(parseString string) (err error) { var ( kvlist []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("UNT: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") // 填充值 if unt.DataRows, err = strconv.Atoi(kvlist[1]); err != nil { return errors.New("UNT: Failed to get data rows!") } unt.MsgId = kvlist[2] unt.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(unt.MsgId) == "" { return errors.New("UNT: MsgId is empty!") } return } func (unt *UNT) Print() { fmt.Println("UNT | MsgId:", unt.MsgId, " | DataRows:", unt.DataRows) } func (unz *UNZ) Parse(parseString string) (err error) { var ( kvlist []string ) // 输入为空,返回错误 if strings.TrimSpace(parseString) == "" { return errors.New("UNZ: parse string is empty!") } // 基于+分隔符来解析字符串 kvlist = strings.Split(parseString, "+") // 填充值 if unz.MsgCount, err = strconv.Atoi(kvlist[1]); err != nil { return errors.New("UNZ: Failed to get message count!") } unz.MsgRefId = kvlist[2] unz.ParseString = parseString // 校验关键字段是否为空 if strings.TrimSpace(unz.MsgRefId) == "" { return errors.New("UNZ: MsgRefId is empty!") } return } func (unz *UNZ) Print() { fmt.Println("UNZ | MsgRefId:", unz.MsgRefId, " | MsgCount:", unz.MsgCount) }