feat(电子发票): 兼容飞猪OFD机票

This commit is contained in:
2026-06-25 13:54:14 +08:00
parent 9f1b631a58
commit 1ac0fe6ca4
2 changed files with 83 additions and 18 deletions
+48
View File
@@ -77,12 +77,36 @@ func (l *Layer) decodeObject(d *xml.Decoder, start xml.StartElement) error {
}
l.CompositeGraphicUnit = append(l.CompositeGraphicUnit, obj)
l.Objects = append(l.Objects, GraphicObject{Type: start.Name.Local, CompositeGraphicUnit: obj})
case "PageBlock":
return l.decodePageBlock(d, start)
default:
return d.Skip()
}
return nil
}
// decodePageBlock 解析页块子对象
// 入参: d XML解码器, start 起始节点
// 返回: error 错误信息
func (l *Layer) decodePageBlock(d *xml.Decoder, start xml.StartElement) error {
for {
tok, err := d.Token()
if err != nil {
return err
}
switch node := tok.(type) {
case xml.StartElement:
if err := l.decodeObject(d, node); err != nil {
return err
}
case xml.EndElement:
if node.Name.Local == start.Name.Local {
return nil
}
}
}
}
// UnmarshalXML 解析复合图元并保留对象顺序
// 入参: d XML解码器, start 起始节点
// 返回: error 错误信息
@@ -156,12 +180,36 @@ func (c *CompositeGraphicUnit) decodeObject(d *xml.Decoder, start xml.StartEleme
return err
}
c.Clips = &clips
case "PageBlock":
return c.decodePageBlock(d, start)
default:
return d.Skip()
}
return nil
}
// decodePageBlock 解析页块子对象
// 入参: d XML解码器, start 起始节点
// 返回: error 错误信息
func (c *CompositeGraphicUnit) decodePageBlock(d *xml.Decoder, start xml.StartElement) error {
for {
tok, err := d.Token()
if err != nil {
return err
}
switch node := tok.(type) {
case xml.StartElement:
if err := c.decodeObject(d, node); err != nil {
return err
}
case xml.EndElement:
if node.Name.Local == start.Name.Local {
return nil
}
}
}
}
// attrValue 获取XML属性值
// 入参: start 起始节点, name 属性名
// 返回: string 属性值
+35 -18
View File
@@ -157,30 +157,15 @@ func (r *Reader) loadRes(resPath string) {
baseLoc := res.BaseLoc
for _, mm := range res.MultiMedias.MultiMedia {
if mm.MediaFile != "" {
p := strings.TrimSpace(mm.MediaFile)
if p == "" {
continue
if finalPath := resolveResourcePath(resPath, baseLoc, mm.MediaFile); finalPath != "" {
r.ResMap[mm.ID] = finalPath
}
dir := path.Dir(resPath)
if baseLoc != "" {
if dir != baseLoc {
dir = path.Join(dir, baseLoc)
}
}
finalPath := path.Join(dir, p)
r.ResMap[mm.ID] = finalPath
}
}
for i := range res.Fonts.Font {
f := &res.Fonts.Font[i]
if f.FontFile != "" {
dir := path.Dir(resPath)
if baseLoc != "" {
if dir != baseLoc {
dir = path.Join(dir, baseLoc)
}
}
f.FontFile = path.Join(dir, f.FontFile)
f.FontFile = resolveResourcePath(resPath, baseLoc, f.FontFile)
}
r.fontCache[f.ID] = f
}
@@ -194,6 +179,27 @@ func (r *Reader) loadRes(resPath string) {
}
}
// resolveResourcePath 解析资源文件路径
// 入参: resPath 资源文件路径, baseLoc 资源基准路径, filePath 文件路径
// 返回: string 资源文件路径
func resolveResourcePath(resPath, baseLoc, filePath string) string {
p := strings.TrimSpace(filePath)
if p == "" {
return ""
}
p = strings.ReplaceAll(p, "\\", "/")
if strings.HasPrefix(p, "/") {
return strings.TrimPrefix(path.Clean(p), "/")
}
dir := path.Dir(resPath)
if baseLoc != "" {
if dir != baseLoc {
dir = path.Join(dir, baseLoc)
}
}
return path.Join(dir, p)
}
// PageContent 获取页面内容
// 入参: page 页面对象
// 返回: *PageContent 页面内容, error 错误信息
@@ -218,6 +224,17 @@ func (r *Reader) ResPath(resLink string) string {
if resLink == "" {
return ""
}
resLink = strings.ReplaceAll(resLink, "\\", "/")
resLink = strings.TrimSpace(resLink)
if resLink == "" {
return ""
}
resLink = strings.TrimPrefix(resLink, "/")
resLink = path.Clean(resLink)
rootDir := strings.TrimPrefix(strings.ReplaceAll(r.RootDir, "\\", "/"), "/")
if rootDir != "" && (resLink == rootDir || strings.HasPrefix(resLink, rootDir+"/")) {
return resLink
}
return path.Join(r.RootDir, resLink)
}