GS1(Globe standard 1) 码的解析

package drugcode

import (
	"github.com/pkg/errors"
	"math"
	"regexp"
	"strconv"
	"strings"
)

const minLen = 14

const Gs1TagStr = "%1D"
const Gs1Tag = "\u001D"

//BadDrugCode 不合法的drug_code
var BadDrugCode = errors.New("不合法的")



func GetDrugCode(code string) string {
	return strings.ReplaceAll(code, Gs1Tag, Gs1TagStr)
}

//_AI ai标识
type _AI struct {
	Ai        string
	Re        *regexp.Regexp
	Name      string
	transform func([]string) string
}

var (
	//AiSscc ai标识
	AiSscc = &_AI{Ai: "00", Re: regexp.MustCompile(`^00(\d{18})`), Name: "SSCC"}
	//AiGtin ai标识
	AiGtin = &_AI{Ai: "01", Re: regexp.MustCompile(`^01(\d{14})`), Name: "GTIN"}
	//AiEan ai标识
	AiEan = &_AI{Ai: "02", Re: regexp.MustCompile(`^02(\d{14})`), Name: "GTIN"}
	//AiLote ai标识
	AiLote = &_AI{Ai: "10", Re: regexp.MustCompile("^10([^\u001D]{1,20})"), Name: "LOTE"}
	//Ai13 ai标识
	Ai13 = &_AI{Ai: "13", Re: regexp.MustCompile(`^13(\d{6})`), Name: ""}
	//AiFCons15 ai标识
	AiFCons15 = &_AI{Ai: "15", Re: regexp.MustCompile(`^15(\d{6})`), Name: "F_CONS", transform: trans2}
	//AiFCons17 ai标识
	AiFCons17 = &_AI{Ai: "17", Re: regexp.MustCompile(`^17(\d{6})`), Name: "F_CONS", transform: trans2}
	//AiFCons19 ai标识
	AiFCons19 = &_AI{Ai: "19", Re: regexp.MustCompile(`^19(\d{6})`), Name: "F_CONS", transform: trans2}
	//AiSn ai标识
	AiSn = &_AI{Ai: "21", Re: regexp.MustCompile(`^21([\d\w]{1,20})`), Name: "SN"}
	//Ai30 ai标识
	Ai30 = &_AI{Ai: "30", Re: regexp.MustCompile(`^30(\d{1,8})`), Name: ""}
	//AiNtgew310 ai标识
	AiNtgew310 = &_AI{Ai: "310", Re: regexp.MustCompile(`^310(\d)(\d{6})`), Name: "NTGEW", transform: trans1}
	//AiNtgew320 ai标识
	AiNtgew320 = &_AI{Ai: "320", Re: regexp.MustCompile(`^320(\d)(\d{6})`), Name: "NTGEW", transform: trans1}
	//Ai330 ai标识
	Ai330 = &_AI{Ai: "330", Re: regexp.MustCompile(`^330(\d)(\d{6})`), Name: ""}
	//AiCant  ai标识
	AiCant = &_AI{Ai: "37", Re: regexp.MustCompile(`^37(\d{1,8})`), Name: "CANT"}
	aiMap  = map[string]*_AI{
		AiSscc.Ai: AiSscc, AiGtin.Ai: AiGtin, AiEan.Ai: AiEan, AiLote.Ai: AiLote, Ai13.Ai: Ai13, AiFCons15.Ai: AiFCons15, AiFCons17.Ai: AiFCons17, AiFCons19.Ai: AiFCons19, AiSn.Ai: AiSn, Ai30.Ai: Ai30, AiNtgew310.Ai: AiNtgew310, AiNtgew320.Ai: AiNtgew320, Ai330.Ai: Ai330, AiCant.Ai: AiCant,
	}
)

func trans1(match []string) string {
	m2, _ := strconv.Atoi(match[2])
	m1, _ := strconv.Atoi(match[1])
	return strconv.Itoa(m2 / int(math.Pow10(m1)))
}

func trans2(match []string) string {
	s := match[1]
	return "20" + s[0:2] + "-" + s[2:4] + "-" + s[4:6]
}

//Ais ai标识列表
type Ais struct {
	AiMap     map[string]string
	AiNameMap map[string]string
	NtgewAi   *_AI
}

//Get 从AI获取
func (a *Ais) Get(ai *_AI) string {
	return a.AiMap[ai.Ai]
}

//GetFromName 从名称获取
func (a *Ais) GetFromName(ai string) string {
	return a.AiNameMap[ai]
}

func (a *Ais) setAi(ai *_AI, match []string) {
	s := match[1]
	if ai.transform != nil {
		s = ai.transform(match)
	}
	if len(ai.Name) > 1 {
		a.AiNameMap[ai.Name] = s
	}
	a.AiMap[ai.Ai] = s
	if ai.Name == AiNtgew310.Name {
		a.NtgewAi = ai
	}
}

//AiParse 获取标识列表
func AiParse(code string) (*Ais, error) {
	code = strings.ReplaceAll(code, Gs1TagStr, Gs1Tag)
	if strings.Index(code, Gs1Tag) < 0 {
		return nil, BadDrugCode
	}

	ais := &Ais{
		AiMap:     make(map[string]string),
		AiNameMap: make(map[string]string),
		NtgewAi:   nil,
	}

	for {
		code = strings.TrimPrefix(code, Gs1Tag)
		code = strings.TrimPrefix(code, " ")
		if len(code) < 3 {
			break
		}
		ai, ok := aiMap[code[:2]]
		if !ok {
			ai, ok = aiMap[code[:3]]
			if !ok {
				break
			}
		}
		if strings.HasPrefix(code, ai.Ai) && ai.Re.MatchString(code) {
			match := ai.Re.FindStringSubmatch(code)
			ais.setAi(ai, match)
			code = strings.TrimPrefix(code, match[0])
		}
	}
	return ais, nil
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值