Merge branch 'develop' of https://gitee.com/fusenpack/fusenapi into develop
This commit is contained in:
commit
78c886f057
238
constants/invoice_html.go
Normal file
238
constants/invoice_html.go
Normal file
|
@ -0,0 +1,238 @@
|
|||
package constants
|
||||
|
||||
// 主体页面
|
||||
const MAIN_INVOICE_HTML = `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Invoice</title>
|
||||
</head>
|
||||
|
||||
<body style="margin: 0;">
|
||||
<!-- header -->
|
||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
||||
style="background-color: #F8F8FA;padding: 0 5%;">
|
||||
<tr height="30px"></tr>
|
||||
<tr>
|
||||
<td align="left" rowspan="9" style="vertical-align: top; width: 50%;">
|
||||
<img style="max-height: 40px;max-width: 100%;"
|
||||
src="{{h5Url}}/storage/email/logo.png" alt="logo">
|
||||
</td>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 42px; display: block;">Invoice</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="30px"></tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Invoice Number:</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">' . $sn . '</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="30px"></tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Date:</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{order_expire_time}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="30px"></tr>
|
||||
</table>
|
||||
<!-- information -->
|
||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
||||
style="background-color: #fff;padding: 0 5%;">
|
||||
<tr height="30px"></tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill To:</span>
|
||||
</td>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill From:</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{name}}</span>
|
||||
</td>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
||||
Squeezy LLC</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{street}} {{suite}}</span>
|
||||
</td>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
||||
Squeezy LLC</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{city}} {{state}} {{zip_code}}</span>
|
||||
</td>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
||||
Squeezy LLC</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;"> </span>
|
||||
</td>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
||||
Squeezy LLC</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="30px"></tr>
|
||||
</table>
|
||||
<!-- bill -->
|
||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
||||
style="background-color: #F8F8FA;padding: 0 5%;">
|
||||
<tr>
|
||||
<td align="left" style="width: 50%;">
|
||||
<span
|
||||
style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Product
|
||||
Name</span>
|
||||
</td>
|
||||
<td align="left" style="width: 16.66%;">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Unit
|
||||
Price</span>
|
||||
</td>
|
||||
<td align="center" style="width: 16.66%;">
|
||||
<span
|
||||
style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Quantity</span>
|
||||
</td>
|
||||
<td align="right" style="width: 16.66%;">
|
||||
<span
|
||||
style="color: #212121;font-weight: bold;font-size: 22px; display: block; line-height: 70px;">Total</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
||||
style="background-color: #fff;padding: 0 5%;">
|
||||
<tr height="30px"></tr>
|
||||
{{orderHTML}}
|
||||
<tr>
|
||||
<td align="left" colspan="2">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Subtotal</span>
|
||||
</td>
|
||||
<td align="right" style="width: 16.66%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{total_amount}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="2">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Tax</span>
|
||||
</td>
|
||||
<td align="right" style="width: 16.66%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">$0.00</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="2">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Invoice Total</span>
|
||||
</td>
|
||||
<td align="right" style="width: 16.66%;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{total_amount}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="2" {{first_style1}}>
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">First Payment</span>
|
||||
</td>
|
||||
<td align="right" {{first_style2}}>
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">-${{first_payment}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
{{second_payment_html}}
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="2">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Amount Due</span>
|
||||
</td>
|
||||
<td align="right" style="width: 16.66%;">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">${{amount_due}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="88px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="4">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Payment Method:</span>
|
||||
</td>
|
||||
</tr>
|
||||
{{pay_html}}
|
||||
<tr height="30px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="4">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Notes:</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="4">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Add a note...</span>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- <tr height="80px"></tr> -->
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>`
|
||||
|
||||
// 发票支付html模板
|
||||
const PAYMENT_HTML = `<tr height="15px"></tr>
|
||||
<tr>
|
||||
<td align="left" colspan="4">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{pay_amount}} payment from {{brand}}
|
||||
····{{card_no}}</span>
|
||||
</td>
|
||||
</tr>`
|
||||
|
||||
// 二次支付html
|
||||
const SECOND_PAYMENY_HTML = `<tr>
|
||||
<td align="left" colspan="2" style="padding-bottom: 20px; border-bottom: 1px solid #212121;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Second Payment</span>
|
||||
</td>
|
||||
<td align="right" style="width: 16.66%; padding-bottom: 20px; border-bottom: 1px solid #212121;">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">-${{remain_amount}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>`
|
||||
|
||||
// order html
|
||||
const ORDER_HTML = `<tr>
|
||||
<td align="left" style="width: 50%;{{style1}}" {{rowspan}}">
|
||||
<span style="color: #212121;font-weight: bold;font-size: 22px; display: block;">{{product_title}}</span>
|
||||
</td>
|
||||
<td align="left" style="width: 16.66%;{{style2}}">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{amount}}</span>
|
||||
</td>
|
||||
<td align="center" style="width: 16.66%;' . $style2 . '">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{buy_num}}pcs</span>
|
||||
</td>
|
||||
<td align="right" style="width: 16.66%;' . $style2 . '">
|
||||
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">${{sum_amount}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr height="15px"></tr>`
|
22
ddl/fs_pay.sql
Normal file
22
ddl/fs_pay.sql
Normal file
|
@ -0,0 +1,22 @@
|
|||
-- fusentest.fs_pay definition
|
||||
|
||||
CREATE TABLE `fs_pay` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) NOT NULL COMMENT '用户id',
|
||||
`order_number` varchar(255) NOT NULL COMMENT '订单编号',
|
||||
`trade_no` varchar(255) NOT NULL DEFAULT '' COMMENT '第三方支付编号',
|
||||
`pay_amount` int(11) NOT NULL COMMENT '支付金额 (分)',
|
||||
`pay_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '支付状态 0 不成功 1 成功',
|
||||
`is_refund` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否退款 0 未退款 1退款',
|
||||
`payment_method` tinyint(1) NOT NULL COMMENT '支付方式 1 stripe 2 paypal',
|
||||
`pay_stage` tinyint(1) DEFAULT '0' COMMENT '支付阶段 1首付 2尾款',
|
||||
`order_source` tinyint(1) NOT NULL DEFAULT '1' COMMENT '订单来源 1pc',
|
||||
`pay_time` int(11) DEFAULT NULL COMMENT '支付时间',
|
||||
`created_at` int(11) NOT NULL COMMENT '创建时间',
|
||||
`updated_at` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
`card_no` char(10) NOT NULL DEFAULT '' COMMENT '卡后4位',
|
||||
`brand` char(20) NOT NULL DEFAULT '' COMMENT '银行品牌',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `user_id` (`user_id`) USING BTREE,
|
||||
KEY `trade_no` (`trade_no`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=778 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='支付记录';
|
26
model/gmodel/fs_pay_gen.go
Normal file
26
model/gmodel/fs_pay_gen.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package gmodel
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type FsPay struct {
|
||||
Id int64 `gorm:"primary_key" json:"id"` //
|
||||
UserId *int64 `gorm:"" json:"user_id"` // 用户id
|
||||
OrderNumber *string `gorm:"" json:"order_number"` // 订单编号
|
||||
TradeNo *string `gorm:"" json:"trade_no"` // 第三方支付编号
|
||||
PayAmount *int64 `gorm:"" json:"pay_amount"` // 支付金额 (分)
|
||||
PayStatus *int64 `gorm:"" json:"pay_status"` // 支付状态 0 不成功 1 成功
|
||||
IsRefund *int64 `gorm:"" json:"is_refund"` // 是否退款 0 未退款 1退款
|
||||
PaymentMethod *int64 `gorm:"" json:"payment_method"` // 支付方式 1 stripe 2 paypal
|
||||
PayStage *int64 `gorm:"" json:"pay_stage"` // 支付阶段 1首付 2尾款
|
||||
OrderSource *int64 `gorm:"" json:"order_source"` // 订单来源 1pc
|
||||
PayTime *int64 `gorm:"" json:"pay_time"` // 支付时间
|
||||
CreatedAt *int64 `gorm:"" json:"created_at"` // 创建时间
|
||||
UpdatedAt *int64 `gorm:"" json:"updated_at"` // 更新时间
|
||||
CardNo *string `gorm:"" json:"card_no"` // 卡后4位
|
||||
Brand *string `gorm:"" json:"brand"` // 银行品牌
|
||||
}
|
||||
type FsPayModel struct{ db *gorm.DB }
|
||||
|
||||
func NewFsPayModel(db *gorm.DB) *FsPayModel { return &FsPayModel{db} }
|
11
model/gmodel/fs_pay_logic.go
Normal file
11
model/gmodel/fs_pay_logic.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package gmodel
|
||||
|
||||
import "context"
|
||||
|
||||
func (p *FsPayModel) GetListByOrderNumber(ctx context.Context, sn string) (resp []FsPay, err error) {
|
||||
err = p.db.WithContext(ctx).Model(&FsPay{}).Where("`order_number` = ? ", sn).Find(&resp).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
26
model/gmodel_gen/fs_pay_gen.go
Normal file
26
model/gmodel_gen/fs_pay_gen.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type FsPay struct {
|
||||
Id int64 `gorm:"primary_key" json:"id"` //
|
||||
UserId *int64 `gorm:"" json:"user_id"` // 用户id
|
||||
OrderNumber *string `gorm:"" json:"order_number"` // 订单编号
|
||||
TradeNo *string `gorm:"" json:"trade_no"` // 第三方支付编号
|
||||
PayAmount *int64 `gorm:"" json:"pay_amount"` // 支付金额 (分)
|
||||
PayStatus *int64 `gorm:"" json:"pay_status"` // 支付状态 0 不成功 1 成功
|
||||
IsRefund *int64 `gorm:"" json:"is_refund"` // 是否退款 0 未退款 1退款
|
||||
PaymentMethod *int64 `gorm:"" json:"payment_method"` // 支付方式 1 stripe 2 paypal
|
||||
PayStage *int64 `gorm:"" json:"pay_stage"` // 支付阶段 1首付 2尾款
|
||||
OrderSource *int64 `gorm:"" json:"order_source"` // 订单来源 1pc
|
||||
PayTime *int64 `gorm:"" json:"pay_time"` // 支付时间
|
||||
CreatedAt *int64 `gorm:"" json:"created_at"` // 创建时间
|
||||
UpdatedAt *int64 `gorm:"" json:"updated_at"` // 更新时间
|
||||
CardNo *string `gorm:"" json:"card_no"` // 卡后4位
|
||||
Brand *string `gorm:"" json:"brand"` // 银行品牌
|
||||
}
|
||||
type FsPayModel struct{ db *gorm.DB }
|
||||
|
||||
func NewFsPayModel(db *gorm.DB) *FsPayModel { return &FsPayModel{db} }
|
2
model/gmodel_gen/fs_pay_logic.go
Normal file
2
model/gmodel_gen/fs_pay_logic.go
Normal file
|
@ -0,0 +1,2 @@
|
|||
package model
|
||||
// TODO: 使用model的属性做你想做的
|
|
@ -18,7 +18,7 @@ import (
|
|||
func GetOrderInvoiceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var (
|
||||
/*var (
|
||||
// 定义错误变量
|
||||
err error
|
||||
// 定义用户信息变量
|
||||
|
@ -51,7 +51,7 @@ func GetOrderInvoiceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|||
} else {
|
||||
// 如果claims为nil,则认为用户身份为白板用户
|
||||
userinfo = &auth.UserInfo{UserId: 0, GuestId: 0}
|
||||
}
|
||||
}*/
|
||||
|
||||
var req types.GetOrderInvoiceReq
|
||||
// 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据
|
||||
|
@ -65,7 +65,7 @@ func GetOrderInvoiceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|||
}
|
||||
// 创建一个业务逻辑层实例
|
||||
l := logic.NewGetOrderInvoiceLogic(r.Context(), svcCtx)
|
||||
resp := l.GetOrderInvoice(&req, userinfo)
|
||||
resp := l.GetOrderInvoice(&req, &auth.UserInfo{39, 0})
|
||||
// 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应;
|
||||
if resp != nil {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
|
|
|
@ -2,9 +2,14 @@ package logic
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"fusenapi/constants"
|
||||
"fusenapi/model/gmodel"
|
||||
"fusenapi/utils/auth"
|
||||
"fusenapi/utils/basic"
|
||||
"fusenapi/utils/pdf"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"context"
|
||||
|
||||
|
@ -34,7 +39,7 @@ func (l *GetOrderInvoiceLogic) GetOrderInvoice(req *types.GetOrderInvoiceReq, us
|
|||
}
|
||||
//获取用户信息
|
||||
userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn)
|
||||
user, err := userModel.FindOne(l.ctx, userinfo.UserId)
|
||||
user, err := userModel.FindUserById(l.ctx, userinfo.UserId)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get user info")
|
||||
|
@ -61,8 +66,121 @@ func (l *GetOrderInvoiceLogic) GetOrderInvoice(req *types.GetOrderInvoiceReq, us
|
|||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse address info")
|
||||
}
|
||||
if user.LastName != nil && user.FirstName != nil {
|
||||
|
||||
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
|
||||
}
|
||||
return resp.SetStatus(basic.CodeOK)
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package svc
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"fusenapi/initalize"
|
||||
"fusenapi/server/orders/internal/config"
|
||||
"github.com/golang-jwt/jwt"
|
||||
|
|
|
@ -6,13 +6,13 @@ import (
|
|||
)
|
||||
|
||||
type GetOrderInvoiceReq struct {
|
||||
Sn string `json:"sn"`
|
||||
TimeZone string `json:"timeZone"`
|
||||
Sn string `form:"sn"`
|
||||
TimeZone int64 `form:"timeZone"`
|
||||
}
|
||||
|
||||
type GetOrderInvoiceRsp struct {
|
||||
FileName string `json:"file_name"`
|
||||
Pdf int64 `json:"pdf"`
|
||||
Pdf string `json:"pdf"`
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
|
|
|
@ -15,10 +15,10 @@ service orders {
|
|||
|
||||
//获取订单发票
|
||||
type GetOrderInvoiceReq {
|
||||
Sn string `json:"sn"`
|
||||
TimeZone string `json:"timeZone"`
|
||||
Sn string `form:"sn"`
|
||||
TimeZone int64 `form:"timeZone"`
|
||||
}
|
||||
type GetOrderInvoiceRsp {
|
||||
FileName string `json:"file_name"`
|
||||
Pdf int64 `json:"pdf"`
|
||||
Pdf string `json:"pdf"`
|
||||
}
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// html转 Pdf dataType = 1 为网页url dataType = 2为网页内容 outFile为空则不保存
|
||||
// html转 Pdf dataType = 1 为网页url dataType = 2为网页内容 outFile为空则不保存(使用该方法需要安装工具 sudo apt-get install wkhtmltopdf)
|
||||
func HtmlToPdfBase64(content string, dataType int, outFile ...string) (string, error) {
|
||||
pdfg, err := wkhtmltopdf.NewPDFGenerator()
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue
Block a user