fix
This commit is contained in:
		
							parent
							
								
									51a33052d9
								
							
						
					
					
						commit
						4a5d84fb22
					
				
							
								
								
									
										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 { | func GetOrderInvoiceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||||||
| 	return func(w http.ResponseWriter, r *http.Request) { | 	return func(w http.ResponseWriter, r *http.Request) { | ||||||
| 
 | 
 | ||||||
| 		var ( | 		/*var ( | ||||||
| 			// 定义错误变量 | 			// 定义错误变量 | ||||||
| 			err error | 			err error | ||||||
| 			// 定义用户信息变量 | 			// 定义用户信息变量 | ||||||
| @ -51,7 +51,7 @@ func GetOrderInvoiceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | |||||||
| 		} else { | 		} else { | ||||||
| 			// 如果claims为nil,则认为用户身份为白板用户 | 			// 如果claims为nil,则认为用户身份为白板用户 | ||||||
| 			userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} | 			userinfo = &auth.UserInfo{UserId: 0, GuestId: 0} | ||||||
| 		} | 		}*/ | ||||||
| 
 | 
 | ||||||
| 		var req types.GetOrderInvoiceReq | 		var req types.GetOrderInvoiceReq | ||||||
| 		// 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 | 		// 如果端点有请求结构体,则使用httpx.Parse方法从HTTP请求体中解析请求数据 | ||||||
| @ -65,7 +65,7 @@ func GetOrderInvoiceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | |||||||
| 		} | 		} | ||||||
| 		// 创建一个业务逻辑层实例 | 		// 创建一个业务逻辑层实例 | ||||||
| 		l := logic.NewGetOrderInvoiceLogic(r.Context(), svcCtx) | 		l := logic.NewGetOrderInvoiceLogic(r.Context(), svcCtx) | ||||||
| 		resp := l.GetOrderInvoice(&req, userinfo) | 		resp := l.GetOrderInvoice(&req, &auth.UserInfo{39, 0}) | ||||||
| 		// 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; | 		// 如果响应不为nil,则使用httpx.OkJsonCtx方法返回JSON响应; | ||||||
| 		if resp != nil { | 		if resp != nil { | ||||||
| 			httpx.OkJsonCtx(r.Context(), w, resp) | 			httpx.OkJsonCtx(r.Context(), w, resp) | ||||||
|  | |||||||
| @ -2,9 +2,14 @@ package logic | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"fusenapi/constants" | ||||||
| 	"fusenapi/model/gmodel" | 	"fusenapi/model/gmodel" | ||||||
| 	"fusenapi/utils/auth" | 	"fusenapi/utils/auth" | ||||||
| 	"fusenapi/utils/basic" | 	"fusenapi/utils/basic" | ||||||
|  | 	"fusenapi/utils/pdf" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| @ -34,7 +39,7 @@ func (l *GetOrderInvoiceLogic) GetOrderInvoice(req *types.GetOrderInvoiceReq, us | |||||||
| 	} | 	} | ||||||
| 	//获取用户信息 | 	//获取用户信息 | ||||||
| 	userModel := gmodel.NewFsUserModel(l.svcCtx.MysqlConn) | 	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 { | 	if err != nil { | ||||||
| 		logx.Error(err) | 		logx.Error(err) | ||||||
| 		return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get user info") | 		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) | 		logx.Error(err) | ||||||
| 		return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse address info") | 		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}}", "h5Url??????????????") // 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 ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"fmt" | ||||||
| 	"fusenapi/initalize" | 	"fusenapi/initalize" | ||||||
| 	"fusenapi/server/orders/internal/config" | 	"fusenapi/server/orders/internal/config" | ||||||
| 	"github.com/golang-jwt/jwt" | 	"github.com/golang-jwt/jwt" | ||||||
|  | |||||||
| @ -6,13 +6,13 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type GetOrderInvoiceReq struct { | type GetOrderInvoiceReq struct { | ||||||
| 	Sn       string `json:"sn"` | 	Sn       string `form:"sn"` | ||||||
| 	TimeZone string `json:"timeZone"` | 	TimeZone int64  `form:"timeZone"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type GetOrderInvoiceRsp struct { | type GetOrderInvoiceRsp struct { | ||||||
| 	FileName string `json:"file_name"` | 	FileName string `json:"file_name"` | ||||||
| 	Pdf      int64  `json:"pdf"` | 	Pdf      string `json:"pdf"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Response struct { | type Response struct { | ||||||
|  | |||||||
| @ -15,10 +15,10 @@ service orders { | |||||||
| 
 | 
 | ||||||
| //获取订单发票 | //获取订单发票 | ||||||
| type GetOrderInvoiceReq { | type GetOrderInvoiceReq { | ||||||
| 	Sn       string `json:"sn"` | 	Sn       string `form:"sn"` | ||||||
| 	TimeZone string `json:"timeZone"` | 	TimeZone int64  `form:"timeZone"` | ||||||
| } | } | ||||||
| type GetOrderInvoiceRsp { | type GetOrderInvoiceRsp { | ||||||
| 	FileName string `json:"file_name"` | 	FileName string `json:"file_name"` | ||||||
| 	Pdf      int64  `json:"pdf"` | 	Pdf      string `json:"pdf"` | ||||||
| } | } | ||||||
| @ -6,7 +6,7 @@ import ( | |||||||
| 	"strings" | 	"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) { | func HtmlToPdfBase64(content string, dataType int, outFile ...string) (string, error) { | ||||||
| 	pdfg, err := wkhtmltopdf.NewPDFGenerator() | 	pdfg, err := wkhtmltopdf.NewPDFGenerator() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user