fusenapi/server/orders/internal/logic/getorderinvoicelogic.go
laodaming 0af68d5f32 fix
2023-06-15 19:53:15 +08:00

187 lines
7.3 KiB
Go

package logic
import (
"encoding/json"
"fmt"
"fusenapi/constants"
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"fusenapi/utils/pdf"
"strings"
"time"
"context"
"fusenapi/server/orders/internal/svc"
"fusenapi/server/orders/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetOrderInvoiceLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetOrderInvoiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetOrderInvoiceLogic {
return &GetOrderInvoiceLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetOrderInvoiceLogic) GetOrderInvoice(req *types.GetOrderInvoiceReq, userinfo *auth.UserInfo) (resp *basic.Response) {
if userinfo.GetIdType() != auth.IDTYPE_User {
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please login first")
}
//获取用户信息
userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn)
user, err := userModel.FindUserById(l.ctx, userinfo.UserId)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get user info")
}
if user.Id == 0 {
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "user not found")
}
if req.Sn == "" {
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "param sn is required")
}
//查询订单信息
orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn)
orderInfo, err := orderModel.FindOneBySn(l.ctx, userinfo.UserId, req.Sn)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info")
}
if orderInfo.Id == 0 {
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order is not exists")
}
//地址数据
var address gmodel.FsAddress
if err = json.Unmarshal([]byte(*orderInfo.AddressInfo), &address); err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse address info")
}
userName := ""
if user.LastName != nil && user.FirstName != nil && *user.LastName != "" && *user.FirstName != "" {
userName = *user.LastName + " " + *user.FirstName
} else if address.LastName != nil && address.FirstName != nil && *address.LastName != "" && *address.FirstName != "" {
userName = *address.LastName + " " + *address.LastName
}
pdfFileName := *orderInfo.Sn + "_" + userName + "_FusenPack.pdf"
//首款
firstPayment := *orderInfo.TotalAmount / 2
amountDue := int64(0)
//未完全支付
if *orderInfo.IsPayCompleted == 0 {
amountDue = *orderInfo.TotalAmount - firstPayment
}
var (
secondPaymentHtml string
firstStyle1 = `style="padding-bottom: 20px; border-bottom: 1px solid #212121;"`
firstStyle2 = `style="width: 16.66%; padding-bottom: 20px; border-bottom: 1px solid #212121;"`
payHtml = strings.Builder{}
orderHTML strings.Builder
totalAmount float64
rowspan = `rowspan = "12"`
)
if *orderInfo.IsPayCompleted == 1 {
firstStyle1 = ""
firstStyle2 = ""
rowspan = `rowspan = "14"`
remainAmount := float64(*orderInfo.TotalAmount - firstPayment)
secondPaymentHtml = strings.ReplaceAll(constants.SECOND_PAYMENY_HTML, "{{remain_amount}}", fmt.Sprintf("%.2f", remainAmount/100))
}
//获取订单详情列表
orderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn)
orderDetails, err := orderDetailModel.GetOrderDetailsByOrderId(l.ctx, orderInfo.Id)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order details")
}
if len(orderDetails) == 0 {
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order details is empty")
}
productIds := make([]int64, 0, len(orderDetails))
for _, v := range orderDetails {
productIds = append(productIds, *v.ProductId)
}
//获取产品列表
productModel := gmodel.NewFsProductModel(l.svcCtx.MysqlConn)
productList, err := productModel.GetProductListByIds(l.ctx, productIds, "")
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get product list")
}
mapProduct := make(map[int64]int)
for k, v := range productList {
mapProduct[v.Id] = k
}
payModel := gmodel.NewFsPayModel(l.svcCtx.MysqlConn)
payList, err := payModel.GetListByOrderNumber(l.ctx, *orderInfo.Sn)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get payment list")
}
for _, v := range payList {
tem := strings.ReplaceAll(constants.PAYMENT_HTML, "{{pay_amount}}", fmt.Sprintf("%.2f", float64(*v.PayAmount)/100))
tem = strings.ReplaceAll(tem, "{{brand}}", *v.Brand)
tem = strings.ReplaceAll(tem, "{{card_no}}", *v.CardNo)
payHtml.WriteString(tem)
}
detailCount := len(orderDetails)
for k, v := range orderDetails {
amount := float64(*v.Amount)
sumAmount := amount * float64(*v.BuyNum)
totalAmount += sumAmount
var style1, style2 string
if k == (detailCount - 1) {
style1 = "vertical-align: top;"
style2 = "padding-bottom: 20px; border-bottom: 1px solid #212121;"
}
tem := strings.ReplaceAll(constants.ORDER_HTML, "{{amount}}", fmt.Sprintf("%.2f", amount/100))
tem = strings.ReplaceAll(tem, "{{style1}}", style1)
tem = strings.ReplaceAll(tem, "{{style2}}", style2)
tem = strings.ReplaceAll(tem, "{{rowspan}}", rowspan)
tem = strings.ReplaceAll(tem, "{{buy_num}}", fmt.Sprintf("%d", *v.BuyNum))
tem = strings.ReplaceAll(tem, "{{sum_amount}}", fmt.Sprintf("%.2f", sumAmount/100))
if productIndex, ok := mapProduct[*v.ProductId]; ok {
tem = strings.ReplaceAll(tem, "{{product_title}}", *productList[productIndex].Title)
} else {
tem = strings.ReplaceAll(tem, "{{product_title}}", "")
}
orderHTML.WriteString(tem)
}
mainHtml := strings.ReplaceAll(constants.MAIN_INVOICE_HTML, "{{pay_html}}", payHtml.String())
mainHtml = strings.ReplaceAll(mainHtml, "{{amount_due}}", fmt.Sprintf("%.2f", float64(amountDue)/100))
mainHtml = strings.ReplaceAll(mainHtml, "{{second_payment_html}}", secondPaymentHtml)
mainHtml = strings.ReplaceAll(mainHtml, "{{total_amount}}", fmt.Sprintf("%.2f", totalAmount/100))
mainHtml = strings.ReplaceAll(mainHtml, "{{first_payment}}", fmt.Sprintf("%.2f", float64(firstPayment)/100))
mainHtml = strings.ReplaceAll(mainHtml, "{{orderHTML}}", orderHTML.String())
mainHtml = strings.ReplaceAll(mainHtml, "{{city}}", *address.City)
mainHtml = strings.ReplaceAll(mainHtml, "{{state}}", *address.State)
mainHtml = strings.ReplaceAll(mainHtml, "{{zip_code}}", *address.ZipCode)
mainHtml = strings.ReplaceAll(mainHtml, "{{street}}", *address.Street)
mainHtml = strings.ReplaceAll(mainHtml, "{{suite}}", *address.Suite)
mainHtml = strings.ReplaceAll(mainHtml, "{{name}}", userName)
mainHtml = strings.ReplaceAll(mainHtml, "{{first_style1}}", firstStyle1)
mainHtml = strings.ReplaceAll(mainHtml, "{{first_style2}}", firstStyle2)
mainHtml = strings.ReplaceAll(mainHtml, "{{h5Url}}", "http://www.baidu.com") // TODO ????????????
mainHtml = strings.ReplaceAll(mainHtml, "{{order_expire_time}}", time.Unix(*orderInfo.Ctime, req.TimeZone*60).Format("02 Jan,2006"))
//html内容页面转pdf的base64
prfBase64, err := pdf.HtmlToPdfBase64(mainHtml, 2)
if err != nil {
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to generate pdf file")
}
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetOrderInvoiceRsp{
FileName: pdfFileName,
Pdf: prfBase64,
})
}