fusenapi/server/orders/internal/logic/getorderinvoicelogic.go

190 lines
7.4 KiB
Go
Raw Normal View History

2023-06-15 07:28:17 +00:00
package logic
import (
"encoding/json"
2023-06-20 09:28:28 +00:00
"errors"
2023-06-15 11:14:19 +00:00
"fmt"
"fusenapi/constants"
2023-06-15 07:28:17 +00:00
"fusenapi/model/gmodel"
"fusenapi/utils/auth"
"fusenapi/utils/basic"
2023-06-15 11:14:19 +00:00
"fusenapi/utils/pdf"
2023-06-20 09:28:28 +00:00
"gorm.io/gorm"
2023-06-15 11:14:19 +00:00
"strings"
"time"
2023-06-15 07:28:17 +00:00
"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)
2023-06-15 11:14:19 +00:00
user, err := userModel.FindUserById(l.ctx, userinfo.UserId)
2023-06-15 07:28:17 +00:00
if err != nil {
2023-07-11 09:08:19 +00:00
if errors.Is(err, gorm.ErrRecordNotFound) {
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "user not found")
}
2023-06-15 07:28:17 +00:00
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get user info")
}
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 {
2023-06-20 09:28:28 +00:00
if errors.Is(err, gorm.ErrRecordNotFound) {
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the order is not exists")
}
2023-06-15 07:28:17 +00:00
logx.Error(err)
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info")
}
//地址数据
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")
}
2023-06-15 11:14:19 +00:00
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)
2023-06-15 07:28:17 +00:00
2023-06-15 11:14:19 +00:00
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)
2023-06-16 02:10:50 +00:00
mainHtml = strings.ReplaceAll(mainHtml, "{{h5Url}}", constants.H5_URL)
2023-06-16 02:27:42 +00:00
mainHtml = strings.ReplaceAll(mainHtml, "{{order_sn}}", *orderInfo.Sn)
2023-06-15 11:14:19 +00:00
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")
2023-06-15 07:28:17 +00:00
}
2023-06-15 11:14:19 +00:00
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetOrderInvoiceRsp{
FileName: pdfFileName,
Pdf: prfBase64,
})
2023-06-15 07:28:17 +00:00
}