/** * @Author: sun * @Company: 苏州泰丰文化 * @Description: * @File: print_manage * @Version: 1.0.0 * @Date: 2024/10/12 15:43 */ package service import ( "bytes" "context" "errors" "fmt" "io" "mime/multipart" "net/http" "os" "time" "dubbo.apache.org/dubbo-go/v3/common/logger" artShow "github.com/fonchain_enterprise/fonchain-main/api/artShow" "github.com/fonchain_enterprise/fonchain-main/api/artist" "github.com/fonchain_enterprise/fonchain-main/api/artwork_third_party" "github.com/fonchain_enterprise/fonchain-main/pkg/config" "github.com/fonchain_enterprise/fonchain-main/pkg/e" "github.com/fonchain_enterprise/fonchain-main/pkg/model" "github.com/fonchain_enterprise/fonchain-main/pkg/model/login" "github.com/fonchain_enterprise/fonchain-main/pkg/serializer" "github.com/gin-gonic/gin" "github.com/lukasjarosch/go-docx" "github.com/qifengzhang007/gooxml/document" "github.com/qifengzhang007/gooxml/schema/soo/wml" ) func ArtShowListForPrint(c *gin.Context) { var showListReq artShow.ArtShowListForPrintReq if err := c.ShouldBindJSON(&showListReq); err != nil { logger.Errorf("ShowList ShouldBindJSON err", err) ResponseMsg(c, e.InvalidParams, serializer.Response{ Data: nil, Msg: err.Error(), Status: e.Failed, }) return } showListRes, err := GrpcArtShowImpl.ArtShowListForPrint(context.Background(), &showListReq) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Failed, }) return } ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: showListRes.Msg, Data: showListRes, Status: e.Ok, }) } // 我仅仅是加了三个分支逻辑 func PrintPreviewFile(c *gin.Context) { var req artShow.PrintPreviewFileReq if err := c.ShouldBindJSON(&req); err != nil { logger.Errorf("Print Preview File err: %v", err) ResponseMsg(c, e.InvalidParams, serializer.Response{ Data: nil, Msg: err.Error(), Status: e.Failed, }) return } // 组装 获取 画作 基础信息参数 artworkDataReq := artwork_third_party.AwDataByShowIdRequest{} artworkDataReq.ArtShowIds = append(artworkDataReq.ArtShowIds, req.ShowUid) // 获取 画作 基础信息 resp, err := GrpcArtworkThirdPartyImpl.AwDataByShowId(context.Background(), &artworkDataReq) if err != nil { logger.Errorf("Print Preview File query err: %v", err) ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Failed, }) return } if resp.Data == nil { logger.Errorf("Print Preview File query err: %v", err) ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: "画作信息为空", Status: e.Failed, }) return } if len(resp.Data) <= 0 { logger.Errorf("Print Preview File query err: %v", "画作信息为空") ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: nil, Msg: "画作信息为空", Status: e.Failed, }) return } // 组装 画作 基础信息 artworkData := make(map[string]*artwork_third_party.AwDataByShowIdResponse_Info, 0) for i := 0; i < len(resp.Data); i++ { artworkData[resp.Data[i].ArtworkUuid] = resp.Data[i] } // 获取 画作价格信息 artworkPriceList := new(artShow.ArtworkPriceListRes) // 获取 画作价格信息 artworkPriceReq := artShow.ShowDetailReq{} artworkPriceReq.ShowUID = append(artworkPriceReq.ShowUID, req.ShowUid) artworkPriceList, err = GrpcArtShowImpl.ArtworkPriceList(context.Background(), &artworkPriceReq) if err != nil { logger.Errorf("ArtworkPriceList query err", err) ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Failed, }) return } // 获取 画展包信息 showDetailReq := new(artShow.ShowDetailReq) showDetailReq.ShowUID = append(showDetailReq.ShowUID, req.ShowUid) artShowInfo, err := GrpcArtShowImpl.ShowDetail(context.Background(), showDetailReq) if err != nil { logger.Errorf("Print Preview File query err: %v", err) ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Failed, }) return } // 组装 画作 基础信息 artShowMap := make(map[string]*artShow.ShowDetail, 0) for i := 0; i < len(artShowInfo.Data); i++ { if artShowInfo.Data[i].Price == 0 { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: e.ErrorNoPrice, Status: e.Failed, }) return } artShowMap[artShowInfo.Data[i].ShowUID] = artShowInfo.Data[i] } // 获取画家 信息 artistInfoReq := new(artist.ArtistDetailDataReq) artistInfoReq.Uids = append(artistInfoReq.Uids, artShowInfo.Data[0].ArtistUID) artistInfo, err := GrpcArtistImpl.ArtistDetailData(context.Background(), artistInfoReq) if err != nil { logger.Errorf("Print Preview File query artiest info err: %v", err) ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Failed, }) return } artistMap := make(map[string]*artist.ArtistDetailDataResp_Info, 0) for i := 0; i < len(artistInfo.Data); i++ { if artistMap[artistInfo.Data[i].ProfileInfo.Name] == nil { artistMap[artistInfo.Data[i].ProfileInfo.Name] = artistInfo.Data[i] } } if len(artworkPriceList.Data) == 0 || len(artworkData) == 0 { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: e.ErrorNoPrice, Status: e.Failed, }) } priceInfo := serializer.BuildInvoiceInfo(artworkPriceList.Data, artworkData, artistMap) priceInfo.Address = artShowMap[req.ShowUid].Address priceInfo.ShowTime = artShowMap[req.ShowUid].ShowTime if artistMap[artShowInfo.Data[0].ArtistName] != nil { priceInfo.BankNo = artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.BankNum priceInfo.Bank = artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.BankName priceInfo.BankCode = artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.BankCode } var urlMap = make(map[string]string) switch req.PrintType { // 1-代销合同 2-销售清单 3-委托书 4-转让合同 case 1: saleContractPath := "./data/代销合同_模版.docx" doc, err := docx.Open(saleContractPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } replaceMap := docx.PlaceholderMap{ "art_name": artShowInfo.Data[0].ArtistName, "address": artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.Address, "id_no": artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.CardId, "telephone": artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.Phone, } if err = doc.ReplaceAll(replaceMap); err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } now := time.Now().UnixMilli() tmpPath := fmt.Sprintf("./data/%d.docx", now) err = doc.WriteToFile(tmpPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } pdfPath, err := docxToPdf(now) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } url, err := PutBos(pdfPath, "pdf", true) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } _ = os.Remove(tmpPath) //if _, err = GrpcArtShowImpl.CreateContractPath(context.Background(), &artShow.CreateContractPathReq{ // ShowUid: req.ShowUid, // ContractType: 1, // ContractPath: url, //}); err != nil { // ResponseMsg(c, e.SUCCESS, serializer.Response{ // Msg: err.Error(), // Status: e.Ok, // }) //} urlMap["serviceContractPath"] = url ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: urlMap, Status: e.Ok, }) //} case 2: //priceInfo.AuthList = nil res := &model.PriceRightListRes{} for _, v := range priceInfo.ArtworkPriceList { for _, vv := range priceInfo.CopyrightPriceList { if v.Num == vv.Num { tmp := &model.PrintRightItem{ ArtworkName: v.ArtworkName, ArtistName: v.ArtistName, DoTime: v.DoTime, Num: v.Num, Ruler: v.Ruler, TfNum: v.TfNum, FloorPrice: v.ArtworkPrice + vv.CopyrightPrice, } res.List = append(res.List, tmp) } } } res.RuleTotal = priceInfo.TotalRuler res.PriceTotal = priceInfo.Price res.Principal = artShowInfo.Data[0].ArtistName ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: res, Status: e.Ok, }) case 3: ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: priceInfo.AuthList, Status: e.Ok, }) case 4: //resData, err := GrpcArtShowImpl.GetContractPath(context.Background(), &artShow.GetContractPathReq{ // ShowUid: req.ShowUid, // ContractType: 4, //}) //if err != nil { // ResponseMsg(c, e.SUCCESS, serializer.Response{ // Msg: err.Error(), // Status: e.Ok, // }) //} //if len(resData.ContractPath) > 0 { // urlMap["tranContractPath"] = resData.ContractPath // ResponseMsg(c, e.SUCCESS, serializer.Response{ // Data: urlMap, // Status: e.Ok, // }) //} else { tranContractPath := "./data/转让合同_模版.docx" doc, err := document.Open(tranContractPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } if len(doc.Tables()) != 2 { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: "模版格式不合格", Status: e.Ok, }) } //获取表格中的文本 for _, table := range doc.Tables()[1:] { // 所有表 if len(table.Rows()) < len(resp.Data) { firstRow := table.Rows()[0] lineNumber := len(resp.Data) - len(table.Rows()) + 2 for i := 0; i < lineNumber; i++ { newRow := table.InsertRowAfter(firstRow) for l := 0; l < 5; l++ { newCell := newRow.AddCell() newCell.AddParagraph().AddRun().AddText("") } } } for i, lines := range table.Rows() { // 所有行 if i < 1 || i == len(table.Rows())-1 || i > len(resp.Data) { continue } for ii, cell := range lines.Cells() { switch ii { case 0: p := cell.AddParagraph() p.Properties().SetAlignment(wml.ST_JcCenter) r := p.AddRun() r.Properties().SetBold(true) r.Properties().SetSize(6.5) r.AddText(fmt.Sprintf("%d", i)) case 1: p := cell.AddParagraph() p.Properties().SetAlignment(wml.ST_JcCenter) r := p.AddRun() r.Properties().SetBold(true) r.Properties().SetSize(6.5) r.AddText(fmt.Sprintf("{work_name_%d}", i)) case 2: p := cell.AddParagraph() p.Properties().SetAlignment(wml.ST_JcCenter) r := p.AddRun() r.Properties().SetBold(true) r.Properties().SetSize(6.5) r.AddText(fmt.Sprintf("{hash_%d}", i)) case 3: p := cell.AddParagraph() p.Properties().SetAlignment(wml.ST_JcCenter) r := p.AddRun() r.Properties().SetBold(true) r.Properties().SetSize(6.5) r.AddText(fmt.Sprintf("原始")) default: continue } } } } now := time.Now().UnixMilli() tmpPath := fmt.Sprintf("./data/%d.docx", now) if err = doc.SaveToFile(tmpPath); err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } doc3, err := docx.Open(tmpPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } replaceMap := docx.PlaceholderMap{ "art_name": artShowInfo.Data[0].ArtistName, "address": artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.Address, "id_no": artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.CardId, "telephone": artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.Phone, } for k, v := range resp.Data { replaceMap["work_name_"+fmt.Sprintf("%d", k+1)] = v.ArtworkName replaceMap["hash_"+fmt.Sprintf("%d", k+1)] = v.CopyrightHash } if err = doc3.ReplaceAll(replaceMap); err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } now2 := time.Now().UnixMilli() tmpPath1 := fmt.Sprintf("./data/%d.docx", now2) err = doc3.WriteToFile(tmpPath1) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } pdfPath, err := docxToPdf(now2) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } url, err := PutBos(pdfPath, "pdf", true) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } _ = os.Remove(tmpPath) _ = os.Remove(tmpPath1) urlMap["tranContractPath"] = url //if _, err = GrpcArtShowImpl.CreateContractPath(context.Background(), &artShow.CreateContractPathReq{ // ShowUid: req.ShowUid, // ContractPath: url, // ContractType: 4, //}); err != nil { // ResponseMsg(c, e.SUCCESS, serializer.Response{ // Msg: err.Error(), // Status: e.Ok, // }) //} ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: urlMap, Status: e.Ok, }) //} case 5: saleContractPath := "./data/print_model/版权代理登记委托合同.docx" doc, err := docx.Open(saleContractPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } defer doc.Close() replaceMap := docx.PlaceholderMap{ "art_name": artShowInfo.Data[0].ArtistName, "id_no": artistMap[artShowInfo.Data[0].ArtistName].ProfileInfo.CardId, } if err = doc.ReplaceAll(replaceMap); err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } now := time.Now().UnixMilli() tmpPath := fmt.Sprintf("./data/%d.docx", now) err = doc.WriteToFile(tmpPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } pdfPath, err := docxToPdf(now) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } url, err := PutBos(pdfPath, "pdf", true) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } _ = os.Remove(tmpPath) urlMap["path"] = url // urlMap["path"] = config.ApiHost + "/pdfst/print_model/版权代理登记委托合同.pdf" ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: urlMap, Status: e.Ok, }) return case 6: //excel res := &model.PriceRightListRes{} for _, v := range priceInfo.ArtworkPriceList { for _, vv := range priceInfo.CopyrightPriceList { if v.Num == vv.Num { tmp := &model.PrintRightItem{ ArtworkName: v.ArtworkName, ArtistName: v.ArtistName, DoTime: v.DoTime, Num: v.Num, Ruler: v.Ruler, TfNum: v.TfNum, FloorPrice: v.ArtworkPrice + vv.CopyrightPrice, } res.List = append(res.List, tmp) } } } res.RuleTotal = priceInfo.TotalRuler res.PriceTotal = priceInfo.Price res.Principal = artShowInfo.Data[0].ArtistName ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: res, Status: e.Ok, }) return case 7: //文档更新内容,然后pdf var talentAgency, address string if _, isExist := artShowMap[req.ShowUid]; isExist { talentAgency = artShowMap[req.ShowUid].TalentAgency var addressMap = map[string]string{ "上海泰初澹然文化传播有限公司": "上海市黄浦区西藏中路268号2201室", "浙江蓝丰文化科技有限公司": "浙江省宁波市鄞州区实怡中心7幢13号17-1-1", "常熟虞丰文化艺术交流有限公司": "江苏省苏州市常熟市虞山街道虞景文华31幢F2部分", "合肥常丰文化传播有限公司": "安徽省合肥市瑶海区明光路街道芜湖路2号坝上街环球中心7层商协会大厦 716-2062", } if _, isOk := addressMap[talentAgency]; isOk == true { address = addressMap[talentAgency] } } saleContractPath := "./data/print_model/居间服务协议-20241210.docx" doc, err := docx.Open(saleContractPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } replaceMap := docx.PlaceholderMap{ "company": talentAgency, "address": address, } if err = doc.ReplaceAll(replaceMap); err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } now := time.Now().UnixMilli() tmpPath := fmt.Sprintf("./data/%d.docx", now) err = doc.WriteToFile(tmpPath) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } pdfPath, err := docxToPdf(now) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } url, err := PutBos(pdfPath, "pdf", true) if err != nil { ResponseMsg(c, e.SUCCESS, serializer.Response{ Msg: err.Error(), Status: e.Ok, }) } _ = os.Remove(tmpPath) urlMap["path"] = url ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: urlMap, Status: e.Ok, }) return default: return } return } func GetPrintDetail(c *gin.Context) { var req artShow.PrintDetailReq if err := c.ShouldBindJSON(&req); err != nil { ResponseMsg(c, e.InvalidParams, serializer.Response{ Data: nil, Msg: err.Error(), Status: e.Failed, }) return } res, err := GrpcArtShowImpl.GetPrintDetail(context.Background(), &req) if err != nil { logger.Errorf("Print Preview File err: %v", err) ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: nil, Msg: err.Error(), Status: e.Failed, }) } ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: res, Status: e.Ok, }) return } func CreatePrintDetail(c *gin.Context) { var req artShow.CreatePrintDetailReq if err := c.ShouldBindJSON(&req); err != nil { ResponseMsg(c, e.InvalidParams, serializer.Response{ Data: nil, Msg: err.Error(), Status: e.Failed, }) return } userInfo := login.GetUserInfoFromC(c) req.PrintOperator = userInfo.NickName _, err := GrpcArtShowImpl.CreatePrintDetail(context.Background(), &req) if err != nil { ResponseMsg(c, e.InvalidParams, serializer.Response{ Data: nil, Msg: err.Error(), Status: e.Failed, }) } ResponseMsg(c, e.SUCCESS, serializer.Response{ Data: nil, Status: e.Ok, }) } func SearchArtistListByKeyword(c *gin.Context) { var idNameReq artist.ArtIdNameRequest if err := c.ShouldBind(&idNameReq); err != nil { logger.Errorf("idNameReq ShouldBind err", err) ResponseQuickMsg(c, e.Failed, err.Error(), nil) return } resp, err := GrpcArtistImpl.ArtistIdName(context.Background(), &idNameReq) if err != nil { ResponseQuickMsg(c, e.Failed, err.Error(), nil) return } for _, v := range resp.Items { if v.BlackListStatus == 2 { v.Name = fmt.Sprintf("#%s", v.Name) } } ResponseQuickMsg(c, e.Ok, resp.Msg, resp.Items) return } func docxToPdf(fileName int64) (pdfUrl string, err error) { // 目标 URL url := fmt.Sprintf("%s/forms/libreoffice/convert", config.PdfHost) fmt.Println("url:-----------------", url) // 打开文件 file, err := os.Open(fmt.Sprintf("./data/%d.docx", fileName)) if err != nil { return "", errors.New("打开doc文件失败") } defer file.Close() // 创建表单 body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("files", "file.docx") if err != nil { return "", errors.New("创建转换pdf表单文件失败") } _, err = io.Copy(part, file) if err != nil { fmt.Println("复制文件到表单失败:", err) return "", errors.New("复制docx文件到pdf表单文件失败") } // 关闭 writer err = writer.Close() if err != nil { return "", errors.New("关闭pdf表单文件失败") } // 创建请求 req, err := http.NewRequest("POST", url, body) if err != nil { fmt.Println("创建请求失败:", err) return } // 设置请求头 req.Header.Set("Content-Type", writer.FormDataContentType()) // 发送请求 client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("发送请求失败:", err) return } defer resp.Body.Close() // 检查响应状态 if resp.StatusCode != http.StatusOK { fmt.Printf("请求失败,状态码: %d\n", resp.StatusCode) return } pdfUrl = fmt.Sprintf("./data/%d.pdf", fileName) // 保存响应内容到文件 outFile, err := os.Create(pdfUrl) if err != nil { return "", errors.New("创建输出pdf文件失败") } defer outFile.Close() _, err = io.Copy(outFile, resp.Body) if err != nil { fmt.Println("保存响应内容失败:", err) return } fmt.Println("pdf文件转换成功,已保存") return } func docxToPdfV2(fileName string) (pdfUrl string, err error) { // 目标 URL url := fmt.Sprintf("%s/forms/libreoffice/convert", config.PdfHost) fmt.Println("url:-----------------", url) // 打开文件 file, err := os.Open(fileName) if err != nil { return "", errors.New("打开doc文件失败") } defer file.Close() // 创建表单 body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("files", "file.docx") if err != nil { return "", errors.New("创建转换pdf表单文件失败") } _, err = io.Copy(part, file) if err != nil { fmt.Println("复制文件到表单失败:", err) return "", errors.New("复制docx文件到pdf表单文件失败") } // 关闭 writer err = writer.Close() if err != nil { return "", errors.New("关闭pdf表单文件失败") } // 创建请求 req, err := http.NewRequest("POST", url, body) if err != nil { fmt.Println("创建请求失败:", err) return } // 设置请求头 req.Header.Set("Content-Type", writer.FormDataContentType()) // 发送请求 client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("发送请求失败:", err) return } defer resp.Body.Close() // 检查响应状态 if resp.StatusCode != http.StatusOK { fmt.Printf("请求失败,状态码: %d\n", resp.StatusCode) return } pdfUrl = fmt.Sprintf("%d.pdf") // 保存响应内容到文件 outFile, err := os.Create(pdfUrl) if err != nil { panic(err) return "", errors.New("创建输出pdf文件失败") } defer outFile.Close() _, err = io.Copy(outFile, resp.Body) if err != nil { fmt.Println("保存响应内容失败:", err) return } fmt.Println("pdf文件转换成功,已保存") return }