package logic import ( "bytes" "encoding/json" "fusenapi/model/gmodel" "fusenapi/utils/auth" "fusenapi/utils/basic" "fusenapi/utils/collect" "fusenapi/utils/format" "log" "strings" "text/template" "context" "fusenapi/server/backend/internal/svc" "fusenapi/server/backend/internal/types" "github.com/tidwall/gjson" "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) type QuotationDetailLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewQuotationDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QuotationDetailLogic { return &QuotationDetailLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func GetPrice(num int64, stepNum []int64, stepPrice []int64) int64 { //阶梯价计算 if num > stepNum[len(stepNum)-1] { return stepPrice[len(stepPrice)-1] } for k, v := range stepNum { if num <= v { return stepPrice[k] } } return 0 } // GetDemoHtml 报价单 func (l *QuotationDetailLogic) GetDemoHtml(quot *gmodel.FsQuotation, quotationProduct []*gmodel.FsQuotationProduct) (htmlcontent string, err error) { // htmlContent := "" priceHtml := "" // productNum := len(quotationProduct) // page := 3 // pageTotal := 3 + productNum for _, quotProduct := range quotationProduct { var priceInfo []map[string]interface{} err := json.Unmarshal([]byte(*quotProduct.PriceInfo), &priceInfo) if err != nil { return "", err } priceHtmlTpl := ` {{range $i, $parr := .priceInfo}} {{if lt $i 3}} <div class="pr-card"> <p class="pr">${{$parr.price}}</p> <p class="num">{{$parr.num}}<span> Units</span></p> </div> {{else}} <div class="pr-card" style="margin-right: 8px;"> <p class="pr">${{$parr.price}}</p> <p class="num">{{$parr.num}}<span> Units</span></p> </div> {{end}} {{end}}` tpl := template.Must(template.New("prCardTpl").Parse(priceHtmlTpl)) buf := &bytes.Buffer{} err = tpl.Execute(buf, map[string]interface{}{ "priceInfo": priceInfo, }) if err != nil { log.Println(err) return "", err } priceHtml = buf.String() } tpl := template.New("quto") tpl = tpl.Funcs(format.TemplateFuncMap) tpl = template.Must(tpl.ParseFiles(templatePath + "/products.tpl")) buf := &bytes.Buffer{} tpl.Execute(buf, map[string]interface{}{ "products": collect.StructSliceJson2Maps(quotationProduct), "price_html": priceHtml, }) htmlContent := buf.String() // log.Println(htmlContent) return htmlContent, nil } func (l *QuotationDetailLogic) QuotationDetail(req *types.RequestQuotationId, userinfo *auth.BackendUserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null quot, err := l.svcCtx.AllModels.FsQuotation.FindOneOnlyById(l.ctx, req.QuotationId) if err != nil { if err == gorm.ErrRecordNotFound { return resp.SetStatus(basic.CodeDbRecordNotFoundErr) } return resp.SetStatus(basic.CodeDbSqlErr) } CanteenProduct, err := l.svcCtx.AllModels.FsCanteenProduct.GetAllByCanteenTypeIdOrderAsc(l.ctx, *quot.CanteenType) if err != nil { if err == gorm.ErrRecordNotFound { return resp.SetStatus(basic.CodeDbRecordNotFoundErr) } return resp.SetStatus(basic.CodeDbSqlErr) } quotationProduct, err := l.svcCtx.AllModels.FsQuotationProduct.GetAllByQuotationIdOrderAsc(l.ctx, req.QuotationId) if err != nil { if err != gorm.ErrRecordNotFound { return resp.SetStatus(basic.CodeDbSqlErr) } } var target any = quotationProduct if len(quotationProduct) == 0 { target = CanteenProduct } jdata, err := json.Marshal(target) if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeJsonErr) } list := gjson.ParseBytes(jdata) qFlag := len(quotationProduct) > 0 //获取备注模板 // markList, err := l.svcCtx.AllModels.FsQuotationRemarkTemplate.GetAllSelectContent(l.ctx) var productIds = collect.ArrayColumnTag[int64](CanteenProduct, "product_id") productList, err := l.svcCtx.AllModels.FsProduct.FindAllOnlyByIds(l.ctx, productIds) if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeDbSqlErr) } productListMap := collect.Array2MapByKeyTag[int64](productList, "id") //获取size信息 var sizeIds = collect.ArrayColumnTag[int64](CanteenProduct, "size_id") sizes, err := l.svcCtx.AllModels.FsProductSize.GetAllSelectIdAndCapacityByIds(l.ctx, sizeIds) if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeDbSqlErr) } sizesMap := collect.Array2MapByKeyTag[int64](sizes, "id") //获取价格信息 productPrice, err := l.svcCtx.AllModels.FsProductPrice.GetAllSelectBySizeId(l.ctx, sizeIds) if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeDbSqlErr) } productPriceMap := collect.Array2MapByKeyTag[int64](productPrice, "size_id") // product := []map[string]interface{}{} products := []map[string]interface{}{} for _, parr := range list.Array() { var priceList []map[string]int64 if !qFlag { if price, ok := productPriceMap[parr.Get("size_id").Int()]; !ok { priceList = []map[string]int64{ {"num": 1, "price": 0}, {"num": 1, "price": 0}, {"num": 1, "price": 0}, } } else { i := 0 price.StepNum = collect.ArrayString2Int(strings.Split(price.StepNum.(string), ",")) price.StepPrice = collect.ArrayString2Int(strings.Split(price.StepPrice.(string), ",")) for price.MinBuyNum < int64(len(price.StepNum.([]string))+5) && i < 3 { priceList = append(priceList, map[string]int64{ "num": int64(price.MinBuyNum * price.EachBoxNum), "price": GetPrice(price.MinBuyNum, price.StepNum.([]int64), price.StepPrice.([]int64)) / 100, }) price.MinBuyNum++ i++ } if len(priceList) < 3 { for j := 0; j < 3-len(priceList); j++ { priceList = append(priceList, map[string]int64{"num": 1, "price": 0}) } } } } var ( Id any priceInfo any mark any sid any isGift bool name any size any cycle any img any num any ) if qFlag { Id = parr.Get("id") err = json.Unmarshal([]byte(parr.Get("price_info").String()), &priceInfo) if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeJsonErr) } if parr.Get("sid").Exists() { sid = parr.Get("sid").Int() } name = parr.Get("name").String() size = parr.Get("size").Int() cycle = parr.Get("cycle").Int() img = parr.Get("img").String() if parr.Get("remark").Exists() { err = json.Unmarshal([]byte(parr.Get("remark").String()), &mark) if err != nil { logx.Error(err) return resp.SetStatus(basic.CodeJsonErr) } } num = parr.Get("num").Int() } else { if parr.Get("sid").Exists() { sid = parr.Get("sid").Int() } product := productListMap[parr.Get("product_id").Int()] name = product.Title size = sizesMap[parr.Get("size_id").Int()].Capacity cycle = *product.ProduceDays + *product.DeliveryDays img = "" mark = []string{} priceInfo = priceList num = 1 } products = append(products, map[string]interface{}{ "id": Id, "s_id": sid, "is_gift": isGift, "name": name, "size": size, "cycle": cycle, "img": img, "mark": mark, "price_list": priceInfo, "num": num, }) } htmlContent, err := l.GetDemoHtml(", quotationProduct) if err != nil { panic(err) } log.Println(htmlContent) saler, err := l.svcCtx.AllModels.FsQuotationSaler.GetOne(l.ctx, quot.Id) if err != nil { logx.Error(err) if err == gorm.ErrRecordNotFound { return resp.SetStatus(basic.CodeDbRecordNotFoundErr) } return resp.SetStatus(basic.CodeDbSqlErr) } // log.Println(saler) tpl := template.New("quto") tpl = tpl.Funcs(format.TemplateFuncMap) tpl = template.Must(tpl.ParseFiles(templatePath + "/return_html.tpl")) buf := &bytes.Buffer{} err = tpl.Execute(buf, map[string]interface{}{ "demoHtml": htmlContent, "qutoInfo": collect.StructJson2Map(quot), "salerInfo": collect.StructJson2Map(saler), }) if err != nil { return resp.SetStatus(basic.CodeApiErr) } // returnHtmlContent := buf.String() return resp.SetStatus(basic.CodeOK) }