Compare commits
No commits in common. "3d67fbbb6265571b3f828edfb5bb7497d137c2e7" and "b9b7309edc85f7e87f15089292553f0d2c2ceed6" have entirely different histories.
3d67fbbb62
...
b9b7309edc
7
constants/domain_render_img.go
Normal file
7
constants/domain_render_img.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package constants
|
||||||
|
|
||||||
|
// 千人千面windows访问图片的地址
|
||||||
|
const DOMAIN_RENDER_IMG_NAME = "https://fusenrenderimg.kayue.cn"
|
||||||
|
|
||||||
|
// 云渲染域名和访问地址
|
||||||
|
const DOMAIN_NAME = "https://fusenapi.kayue.cn:8010/"
|
||||||
@ -1,8 +1,7 @@
|
|||||||
package constants
|
package constants
|
||||||
|
|
||||||
// 发票主体页面
|
// 主体页面
|
||||||
const MAIN_INVOICE_HTML = `
|
const MAIN_INVOICE_HTML = `<!DOCTYPE html>
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
@ -10,235 +9,230 @@ const MAIN_INVOICE_HTML = `
|
|||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Invoice</title>
|
<title>Invoice</title>
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_warp {
|
|
||||||
background-color: #F8F8FA;
|
|
||||||
padding: 20px 5% 20px 6%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_td {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_td.logo {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_logo {
|
|
||||||
max-height: 15px;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_td.title {
|
|
||||||
color: #212121;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 36px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.information_warp {
|
|
||||||
padding: 30px 5% 30px 6%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.information_td {
|
|
||||||
width: 50%;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
.information_td.bill {
|
|
||||||
color: #212121;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.information_td.right {
|
|
||||||
color: #212121;
|
|
||||||
}
|
|
||||||
|
|
||||||
.information_td.info {
|
|
||||||
color: #666666;
|
|
||||||
line-height: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bill_warp {
|
|
||||||
padding: 0 5% 0 6%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bill_td {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bill_td:first-child {
|
|
||||||
width: 47.59%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bill_td.title {
|
|
||||||
border-top: 2px solid #333;
|
|
||||||
padding: 13px 0 7px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #212121;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bill_td.info {
|
|
||||||
color: #666;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
padding: 8px 0;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bill_warp tr:last-child .bill_td.info {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total_warp {
|
|
||||||
padding: 14px 5% 24px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total_td {
|
|
||||||
color: #212121;
|
|
||||||
padding: 8px 0 7px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total_td.info {
|
|
||||||
color: #666;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total_td.border-dashed {
|
|
||||||
border-bottom: 1px dashed #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total_td.border-solid {
|
|
||||||
border-bottom: 2px solid #333;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total_td.total {
|
|
||||||
padding-top: 12px;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notes_warp {
|
|
||||||
padding: 0 5% 0 6%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notes_td {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #666;
|
|
||||||
font-weight: 300;
|
|
||||||
width: 50%;
|
|
||||||
line-height: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notes_td.title {
|
|
||||||
color: #212121;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notes_td.notes {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body style="margin: 0;">
|
||||||
<!-- header -->
|
<!-- header -->
|
||||||
<table class="header_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
||||||
<tr>
|
style="background-color: #F8F8FA;padding: 0 5%;">
|
||||||
<td class="header_td logo" align="left">
|
<tr height="30px"></tr>
|
||||||
<img class="header_logo" src="https://fusenapi.kayue.cn:8010/storage/email/logo.png" alt="logo">
|
<tr>
|
||||||
</td>
|
<td align="left" rowspan="9" style="vertical-align: top; width: 50%;">
|
||||||
<td class="header_td title" align="right">Invoice</td>
|
<img style="max-height: 40px;max-width: 100%;"
|
||||||
</tr>
|
src="{{h5Url}}/storage/email/logo.png" alt="logo">
|
||||||
</table>
|
</td>
|
||||||
<!-- information -->
|
<td align="left" style="width: 50%;">
|
||||||
<table class="information_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
<span style="color: #212121;font-weight: bold;font-size: 42px; display: block;">Invoice</span>
|
||||||
<tr>
|
</td>
|
||||||
<td class="information_td bill" align="left">Bill To:</td>
|
</tr>
|
||||||
<td class="information_td right" align="right">Invoice No. {{invoice_number}}</td>
|
<tr height="30px"></tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td align="left" style="width: 50%;">
|
||||||
<td class="information_td info" align="left">{{buyer_name}}</td>
|
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Invoice Number:</span>
|
||||||
<td class="information_td right" align="right">Date: {{buy_date}}</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr height="15px"></tr>
|
||||||
<td class="information_td info" align="left">{{street}}</td>
|
<tr>
|
||||||
<td class="information_td" align="right"></td>
|
<td align="left" style="width: 50%;">
|
||||||
</tr>
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{order_sn}}</span>
|
||||||
<tr>
|
</td>
|
||||||
<td class="information_td info" align="left">{{city}}</td>
|
</tr>
|
||||||
<td class="information_td" align="right"></td>
|
<tr height="30px"></tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td align="left" style="width: 50%;">
|
||||||
<td class="information_td info" align="left">{{country}}</td>
|
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Date:</span>
|
||||||
<td class="information_td" align="right"></td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
<tr height="15px"></tr>
|
||||||
<!-- bill -->
|
<tr>
|
||||||
<table class="bill_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
<td align="left" style="width: 50%;">
|
||||||
<!--循环部分-->
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">{{order_expire_time}}</span>
|
||||||
{{product_loop_html}}
|
</td>
|
||||||
<!--循环部分-->
|
</tr>
|
||||||
</table>
|
<tr height="30px"></tr>
|
||||||
<!-- total -->
|
</table>
|
||||||
<table class="total_warp" border="0" align="right" cellpadding="0" cellspacing="0" width="50%">
|
<!-- information -->
|
||||||
<tr>
|
<table border="0" align="center" cellpadding="0" cellspacing="0" width="100%"
|
||||||
<td class="total_td" align="right">Subtotal</td>
|
style="background-color: #fff;padding: 0 5%;">
|
||||||
<td class="total_td info" align="right">${{subtotal_price}}</td>
|
<tr height="30px"></tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td align="left" style="width: 50%;">
|
||||||
<td class="total_td" align="right">Shipping Fee</td>
|
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill To:</span>
|
||||||
<td class="total_td info" align="right">Free</td>
|
</td>
|
||||||
</tr>
|
<td align="left" style="width: 50%;">
|
||||||
<tr>
|
<span style="color: #212121;font-weight: bold;font-size: 24px; display: block;">Bill From:</span>
|
||||||
<td class="total_td border-dashed" align="right">Tax</td>
|
</td>
|
||||||
<td class="total_td info border-dashed" align="right">${{tax}}</td>
|
</tr>
|
||||||
</tr>
|
<tr height="15px"></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="total_td" align="right">Total</td>
|
<td align="left" style="width: 50%;">
|
||||||
<td class="total_td info" align="right">${{total_price}}</td>
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{name}}</span>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
<td align="left" style="width: 50%;">
|
||||||
<td class="total_td border-solid" align="right">Deposit Requested</td>
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
||||||
<td class="total_td info border-solid" align="right">${{deposit_price}}</td>
|
Squeezy LLC</span>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td class="total_td total" align="right">Deposit Due</td>
|
<tr>
|
||||||
<td class="total_td total" align="right">${{deposit_price}}</td>
|
<td align="left" style="width: 50%;">
|
||||||
</tr>
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{street}} {{suite}}</span>
|
||||||
</table>
|
</td>
|
||||||
<!-- notes -->
|
<td align="left" style="width: 50%;">
|
||||||
<table class="notes_warp" border="0" align="center" cellpadding="0" cellspacing="0" width="100%">
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
||||||
<tr>
|
Squeezy LLC</span>
|
||||||
<td class="notes_td title" align="left">Payment Method:</td>
|
</td>
|
||||||
<td class="notes_td title" align="left">Notes:</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td align="left" style="width: 50%;">
|
||||||
<td class="notes_td" align="left">{{payment_method}}</td>
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">{{city}} {{state}} {{zip_code}}</span>
|
||||||
<td class="notes_td notes" align="left" rowspan="2">{{notes}}</td>
|
</td>
|
||||||
</tr>
|
<td align="left" style="width: 50%;">
|
||||||
<tr>
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block; line-height: 42px;">Lemon
|
||||||
<td class="notes_td" align="left">Account No. {{account_number}}</td>
|
Squeezy LLC</span>
|
||||||
</tr>
|
</td>
|
||||||
</table>
|
</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>
|
</body>
|
||||||
|
|
||||||
</html>
|
</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>`
|
||||||
|
|
||||||
// 产品循环部分{{product_loop_html}}
|
// 二次支付html
|
||||||
const PRODUCT_LOOP_HTML_CONTENT = ` <tr>
|
const SECOND_PAYMENY_HTML = `<tr>
|
||||||
<td class="bill_td title" align="left">{{product_name}}</td>
|
<td align="left" colspan="2" style="padding-bottom: 20px; border-bottom: 1px solid #212121;">
|
||||||
<td class="bill_td title" align="right">${{product_item_price}}</td>
|
<span style="color: #666666;font-weight: 400;font-size: 22px; display: block;">Second Payment</span>
|
||||||
<td class="bill_td title" align="right">{{purchase_quantity}}</td>
|
</td>
|
||||||
<td class="bill_td title" align="right">${{product_total_price}}</td>
|
<td align="right" style="width: 16.66%; padding-bottom: 20px; border-bottom: 1px solid #212121;">
|
||||||
</tr>`
|
<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>`
|
||||||
|
|||||||
@ -2,8 +2,8 @@ package constants
|
|||||||
|
|
||||||
// 订单类型
|
// 订单类型
|
||||||
const (
|
const (
|
||||||
DELIVERYMETHODDIRECTMAIL int64 = 1 // 直邮
|
DELIVERYMETHODDIRECTMAIL int64 = 1
|
||||||
DELIVERYMETHODDSCLOUDSTORE int64 = 2 // 云仓
|
DELIVERYMETHODDSCLOUDSTORE int64 = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// 货币
|
// 货币
|
||||||
@ -24,16 +24,16 @@ type PayMethods string
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
PAY_METHOD_CARD PayMethods = "CARD"
|
PAY_METHOD_CARD PayMethods = "CARD"
|
||||||
PAY_METHOD_VISA PayMethods = "VISA"
|
PayMethodVISA PayMethods = "VISA"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 支付状态
|
// 支付状态
|
||||||
type PayStatusCode int64
|
type PayStatusCode int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PAY_STATUS_UNPAID PayStatusCode = 10 //10,未支付
|
PAYSTATUSUNPAID PayStatusCode = 10 //10,未支付
|
||||||
PAY_STATUS_PAID PayStatusCode = 20 //20,已支付
|
PAYSTATUSPAID PayStatusCode = 20 //20,已支付
|
||||||
PAY_STATUS_REFUNDED PayStatusCode = 30 //30,已退款
|
PAYSTATUSREFUNDED PayStatusCode = 30 //30,已退款
|
||||||
)
|
)
|
||||||
|
|
||||||
// 订单支付状态
|
// 订单支付状态
|
||||||
@ -45,22 +45,18 @@ type OrderPayStatusCode int64
|
|||||||
// 30,已付尾款
|
// 30,已付尾款
|
||||||
// 40,已退尾款
|
// 40,已退尾款
|
||||||
const (
|
const (
|
||||||
ORDER_PAY_STATUS_UNPAIDDEPOSIT OrderPayStatusCode = 0
|
ORDERPAYSTATUSUNPAIDDEPOSIT OrderPayStatusCode = 0
|
||||||
ORDER_PAY_STATUS_PAIDDEPOSIT OrderPayStatusCode = 10
|
ORDERPAYSTATUSPAIDDEPOSIT OrderPayStatusCode = 10
|
||||||
ORDER_PAY_STATUS_REFUNDEDDEPOSIT OrderPayStatusCode = 20
|
ORDERPAYSTATUSREFUNDEDDEPOSIT OrderPayStatusCode = 20
|
||||||
ORDER_PAY_STATUS_PAIDDREMAINING OrderPayStatusCode = 30
|
ORDERPAYSTATUSPAIDDREMAINING OrderPayStatusCode = 30
|
||||||
ORDER_PAY_STATUS_REFUNDEDREMAINING OrderPayStatusCode = 40
|
ORDERPAYSTATUSREFUNDEDREMAINING OrderPayStatusCode = 40
|
||||||
)
|
)
|
||||||
|
|
||||||
// 订单状态
|
// 订单状态
|
||||||
type OrderStatusCode int64
|
type OrderStatusCode int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ORDER_STATUS_UNPAIDDEPOSIT OrderStatusCode = 0 // 0,未支付定金
|
ORDER_STATUS_UNPAIDDEPOSIT OrderStatusCode = 0 // 0,未支付定金
|
||||||
ORDER_STATUS_CLOSE OrderStatusCode = 10 // 10,订单已关闭
|
|
||||||
ORDER_STATUS_COMPLETE OrderStatusCode = 20 // 20,订单已完成
|
|
||||||
ORDER_STATUS_DELETE OrderStatusCode = 30 // 20,订单已删除
|
|
||||||
|
|
||||||
ORDER_STATUS_DIRECTMAIL_ORDERED OrderStatusCode = 10100 // 10100,直邮单--已下单
|
ORDER_STATUS_DIRECTMAIL_ORDERED OrderStatusCode = 10100 // 10100,直邮单--已下单
|
||||||
ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING OrderStatusCode = 10100001 // 10100001,直邮单--已下单--尾款
|
ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING OrderStatusCode = 10100001 // 10100001,直邮单--已下单--尾款
|
||||||
ORDER_STATUS_DIRECTMAIL_CANCEL OrderStatusCode = 10101 // 10101,直邮单--已取消
|
ORDER_STATUS_DIRECTMAIL_CANCEL OrderStatusCode = 10101 // 10101,直邮单--已取消
|
||||||
@ -68,13 +64,13 @@ const (
|
|||||||
ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION OrderStatusCode = 10300 // 10300,直邮单--生产完成
|
ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION OrderStatusCode = 10300 // 10300,直邮单--生产完成
|
||||||
ORDER_STATUS_DIRECTMAIL_SHIPPED OrderStatusCode = 10400 // 10400,直邮单--已发货
|
ORDER_STATUS_DIRECTMAIL_SHIPPED OrderStatusCode = 10400 // 10400,直邮单--已发货
|
||||||
ORDER_STATUS_DIRECTMAIL_ARRIVED OrderStatusCode = 10500 // 10500,直邮单--已到达
|
ORDER_STATUS_DIRECTMAIL_ARRIVED OrderStatusCode = 10500 // 10500,直邮单--已到达
|
||||||
|
|
||||||
ORDER_STATUS_CLOUDSTORE_ORDERED OrderStatusCode = 20100 // 20100,云仓单--已下单
|
ORDER_STATUS_CLOUDSTORE_ORDERED OrderStatusCode = 20100 // 20100,云仓单--已下单
|
||||||
ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING OrderStatusCode = 20100001 // 20100001,云仓单--已下单-尾款
|
ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING OrderStatusCode = 20100001 // 20100001,云仓单--已下单-尾款
|
||||||
ORDER_STATUS_CLOUDSTORE_CANCEL OrderStatusCode = 20101 // 20101,云仓单--已取消
|
ORDER_STATUS_CLOUDSTORE_CANCEL OrderStatusCode = 20101 // 20101,云仓单--已取消
|
||||||
ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION OrderStatusCode = 20200 // 20200,云仓单--开始生产
|
ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION OrderStatusCode = 20200 // 20200,云仓单--开始生产
|
||||||
ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION OrderStatusCode = 20300 // 20300,云仓单--生产完成
|
ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION OrderStatusCode = 20300 // 20300,云仓单--生产完成
|
||||||
ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE OrderStatusCode = 20400 // 20400,云仓单--直达仓库
|
ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE OrderStatusCode = 20400 // 20400,云仓单--直达仓库
|
||||||
|
ORDER_STATUS_COMPLETE OrderStatusCode = 30000 // 30000,订单完成
|
||||||
)
|
)
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
@ -83,9 +79,6 @@ var OrderStatusMessage map[OrderStatusCode]string
|
|||||||
// 支付状态名称
|
// 支付状态名称
|
||||||
var PayStatusMessage map[PayStatusCode]string
|
var PayStatusMessage map[PayStatusCode]string
|
||||||
|
|
||||||
// 支付状态名称
|
|
||||||
var OrderPayStatusMessage map[OrderPayStatusCode]string
|
|
||||||
|
|
||||||
// 订单状态--用户可见--直邮
|
// 订单状态--用户可见--直邮
|
||||||
var OrderStatusUserDIRECTMAIL []OrderStatusCode
|
var OrderStatusUserDIRECTMAIL []OrderStatusCode
|
||||||
|
|
||||||
@ -93,50 +86,37 @@ var OrderStatusUserDIRECTMAIL []OrderStatusCode
|
|||||||
var OrderStatusUserCLOUDSTORE []OrderStatusCode
|
var OrderStatusUserCLOUDSTORE []OrderStatusCode
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// 订单状态名称
|
|
||||||
OrderPayStatusMessage = make(map[OrderPayStatusCode]string)
|
|
||||||
OrderPayStatusMessage[ORDER_PAY_STATUS_UNPAIDDEPOSIT] = "Deposit Payment Unpaid"
|
|
||||||
OrderPayStatusMessage[ORDER_PAY_STATUS_PAIDDEPOSIT] = "Deposit Payment Paid"
|
|
||||||
OrderPayStatusMessage[ORDER_PAY_STATUS_REFUNDEDDEPOSIT] = "Deposit Payment Refunded"
|
|
||||||
OrderPayStatusMessage[ORDER_PAY_STATUS_PAIDDREMAINING] = "Final Payment Paid"
|
|
||||||
OrderPayStatusMessage[ORDER_PAY_STATUS_REFUNDEDREMAINING] = "Final Payment Refunded"
|
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
PayStatusMessage = make(map[PayStatusCode]string)
|
PayStatusMessage = make(map[PayStatusCode]string)
|
||||||
PayStatusMessage[PAY_STATUS_UNPAID] = "Unpaid"
|
PayStatusMessage[PAYSTATUSUNPAID] = "Unpaid"
|
||||||
PayStatusMessage[PAY_STATUS_PAID] = "Paid"
|
PayStatusMessage[PAYSTATUSPAID] = "Paid"
|
||||||
PayStatusMessage[PAY_STATUS_REFUNDED] = "Refunded"
|
PayStatusMessage[PAYSTATUSREFUNDED] = "Refunded"
|
||||||
|
|
||||||
// 订单状态名称
|
// 订单状态名称
|
||||||
OrderStatusMessage = make(map[OrderStatusCode]string)
|
OrderStatusMessage = make(map[OrderStatusCode]string)
|
||||||
OrderStatusMessage[ORDER_STATUS_UNPAIDDEPOSIT] = "Deposit Payment Unpaid" // 首款未支付
|
OrderStatusMessage[ORDER_STATUS_UNPAIDDEPOSIT] = "未支付定金"
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOSE] = "Closed" // 已关闭
|
|
||||||
OrderStatusMessage[ORDER_STATUS_COMPLETE] = "Completed" // 已完成
|
|
||||||
OrderStatusMessage[ORDER_STATUS_DELETE] = "Deleted" // 已删除
|
|
||||||
|
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ORDERED] = "Order" // 直邮单--已下单
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ORDERED] = "直邮单--已下单"
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ORDEREDMAINING] = "Final Payment Paid" // 直邮单--已下单--尾款
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION] = "直邮单--开始生产"
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION] = "Start Production" // 直邮单--开始生产
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION] = "直邮单--生产完成"
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION] = "Production Complete" // 直邮单--生产完成
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_SHIPPED] = "直邮单--已发货"
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_SHIPPED] = "Shipped" // 直邮单--已发货
|
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ARRIVED] = "直邮单--已到达"
|
||||||
OrderStatusMessage[ORDER_STATUS_DIRECTMAIL_ARRIVED] = "Delivered" // 直邮单--已到达
|
|
||||||
|
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ORDERED] = "Order" // 云仓单--已下单
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ORDERED] = "云仓单--已下单"
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ORDEREDMAINING] = "Final Payment Paid" // 云仓单--已下单-尾款
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION] = "云仓单--开始生产"
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION] = "Start Production" // 云仓单--开始生产
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION] = "云仓单--生产完成"
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION] = "Production Complete" // 云仓单--生产完成
|
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE] = "云仓单--直达仓库"
|
||||||
OrderStatusMessage[ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE] = "Arrived Inventory" // 云仓单--直达仓库
|
|
||||||
|
OrderStatusMessage[ORDER_STATUS_COMPLETE] = "订单完成"
|
||||||
|
|
||||||
// 订单状态--用户可见--直邮
|
// 订单状态--用户可见--直邮
|
||||||
OrderStatusUserDIRECTMAIL = []OrderStatusCode{
|
OrderStatusUserDIRECTMAIL = []OrderStatusCode{
|
||||||
ORDER_STATUS_UNPAIDDEPOSIT,
|
ORDER_STATUS_UNPAIDDEPOSIT, ORDER_STATUS_COMPLETE,
|
||||||
ORDER_STATUS_DIRECTMAIL_ORDERED, ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION, ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION, ORDER_STATUS_DIRECTMAIL_SHIPPED, ORDER_STATUS_DIRECTMAIL_ARRIVED,
|
ORDER_STATUS_DIRECTMAIL_ORDERED, ORDER_STATUS_DIRECTMAIL_STARTPRODUCTION, ORDER_STATUS_DIRECTMAIL_COMPLETEPRODUCTION, ORDER_STATUS_DIRECTMAIL_SHIPPED, ORDER_STATUS_DIRECTMAIL_ARRIVED,
|
||||||
ORDER_STATUS_COMPLETE, ORDER_STATUS_CLOSE,
|
|
||||||
}
|
}
|
||||||
// 订单状态--用户可见--云仓
|
// 订单状态--用户可见--云仓
|
||||||
OrderStatusUserCLOUDSTORE = []OrderStatusCode{
|
OrderStatusUserCLOUDSTORE = []OrderStatusCode{
|
||||||
ORDER_STATUS_UNPAIDDEPOSIT,
|
ORDER_STATUS_UNPAIDDEPOSIT, ORDER_STATUS_COMPLETE,
|
||||||
ORDER_STATUS_CLOUDSTORE_ORDERED, ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION, ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION, ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE,
|
ORDER_STATUS_CLOUDSTORE_ORDERED, ORDER_STATUS_CLOUDSTORE_STARTPRODUCTION, ORDER_STATUS_CLOUDSTORE_COMPLETEPRODUCTION, ORDER_STATUS_CLOUDSTORE_ARRIVEDWAREHOUSE,
|
||||||
ORDER_STATUS_COMPLETE, ORDER_STATUS_CLOSE,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
package constants
|
|
||||||
|
|
||||||
const (
|
|
||||||
QUEUE_NAME_ORDER = "queue_order"
|
|
||||||
)
|
|
||||||
@ -4,9 +4,12 @@ type Websocket string
|
|||||||
|
|
||||||
// websocket消息类型(主类别)
|
// websocket消息类型(主类别)
|
||||||
const (
|
const (
|
||||||
WEBSOCKET_UNAUTH Websocket = "WEBSOCKET_UNAUTH" //鉴权失败 (1级消息,单向通信)
|
WEBSOCKET_UNAUTH Websocket = "WEBSOCKET_UNAUTH" //鉴权失败 (1级消息,单向通信)
|
||||||
WEBSOCKET_CONNECT_ERR Websocket = "WEBSOCKET_CONNECT_ERR" //ws连接错误 (1级消息,单向通信)
|
WEBSOCKET_CONNECT_ERR Websocket = "WEBSOCKET_CONNECT_ERR" //ws连接错误 (1级消息,单向通信)
|
||||||
WEBSOCKET_CONNECT_SUCCESS Websocket = "WEBSOCKET_CONNECT_SUCCESS" //ws连接成功 (1级消息,单向通信)
|
WEBSOCKET_CONNECT_SUCCESS Websocket = "WEBSOCKET_CONNECT_SUCCESS" //ws连接成功 (1级消息,单向通信)
|
||||||
|
WEBSOCKET_REQUEST_REUSE_LAST_CONNECT Websocket = "WEBSOCKET_REQUEST_REUSE_LAST_CONNECT" //请求恢复为上次连接的标识 (1级消息,单向通信)
|
||||||
|
WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR Websocket = "WEBSOCKET_REQUEST_RESUME_LAST_CONNECT_ERR" //请求恢复为上次连接的标识错误 (1级消息,单向通信)
|
||||||
|
WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW = "WEBSOCKET_INCOME_CACHE_QUEUE_OVERFLOW" //数据接收速度超过数据消费速度(缓冲队列满了)(1级消息,单向通信)
|
||||||
)
|
)
|
||||||
|
|
||||||
// websocket消息类型(通用通知类别)
|
// websocket消息类型(通用通知类别)
|
||||||
|
|||||||
@ -2,22 +2,14 @@
|
|||||||
name=${1%%\\*}
|
name=${1%%\\*}
|
||||||
#进入对应服务目录
|
#进入对应服务目录
|
||||||
cd server/$name
|
cd server/$name
|
||||||
#把https加密密钥对复制进来
|
|
||||||
cp /opt/env.yaml ./
|
|
||||||
cp /opt/server.fusen.3718.cn.pem ./
|
|
||||||
cp /opt/server.fusen.3718.cn.key ./
|
|
||||||
#构建二进制文件
|
#构建二进制文件
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$name-srv ./$name.go
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./bin/api-$name-srv ./$name.go
|
||||||
|
#删除之前旧的镜像
|
||||||
|
docker rmi -f api-$name-srv:latest
|
||||||
|
docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen-test/fusen_docker_hub:latest
|
||||||
#打包docker镜像
|
#打包docker镜像
|
||||||
docker build -t api-$name-srv:latest .
|
docker build -t api-$name-srv:latest .
|
||||||
#删除临时复制进来的文件
|
|
||||||
rm ./env.yaml
|
|
||||||
rm ./server.fusen.3718.cn.pem
|
|
||||||
rm ./server.fusen.3718.cn.key
|
|
||||||
#打tag(测试环境,正式把命名空间fusentest改成fusen)
|
#打tag(测试环境,正式把命名空间fusentest改成fusen)
|
||||||
docker tag api-$name-srv:latest registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
docker tag api-$name-srv:latest registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
||||||
#推送到阿里云镜像库(测试环境,正式把命名空间fusentest改成fusen)
|
#推送到阿里云镜像库(测试环境,正式把命名空间fusentest改成fusen)
|
||||||
docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
docker push registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
||||||
#上传了的镜像
|
|
||||||
docker rmi -f api-$name-srv:latest
|
|
||||||
docker rmi -f registry.cn-hangzhou.aliyuncs.com/fusen-test/$name:latest
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -98,9 +98,11 @@ require (
|
|||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/fatih/color v1.15.0 // indirect
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
github.com/go-logr/logr v1.2.3 // indirect
|
github.com/go-logr/logr v1.2.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
|
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.7.1
|
github.com/go-sql-driver/mysql v1.7.1
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
|
|||||||
13
go.sum
13
go.sum
@ -48,6 +48,7 @@ github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EF
|
|||||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||||
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
|
github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
|
||||||
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
||||||
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
@ -67,6 +68,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
||||||
|
github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOSchFS7Eo=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
@ -137,6 +140,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
@ -159,6 +164,7 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga
|
|||||||
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA=
|
||||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||||
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
|
github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk=
|
||||||
@ -183,6 +189,8 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV
|
|||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
@ -438,12 +446,15 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6
|
|||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||||
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
|
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||||
github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A=
|
github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A=
|
||||||
github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM=
|
github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
@ -574,6 +585,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE=
|
||||||
github.com/zeromicro/go-zero v1.5.4 h1:kRvcYuxcHOkUZvg7887KQl77Qv4klGL7MqGkTBgkpS8=
|
github.com/zeromicro/go-zero v1.5.4 h1:kRvcYuxcHOkUZvg7887KQl77Qv4klGL7MqGkTBgkpS8=
|
||||||
github.com/zeromicro/go-zero v1.5.4/go.mod h1:x/aUyLmSwRECvOyjOf+lhwThBOilJIY+s3slmPAeboA=
|
github.com/zeromicro/go-zero v1.5.4/go.mod h1:x/aUyLmSwRECvOyjOf+lhwThBOilJIY+s3slmPAeboA=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
@ -990,6 +1002,7 @@ gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
package initalize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/utils/queue"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 初始化
|
|
||||||
func InitDelayMessage() *queue.DelayMessage {
|
|
||||||
//创建延迟消息
|
|
||||||
dm := queue.NewDelayMessage()
|
|
||||||
|
|
||||||
go dm.Start()
|
|
||||||
return dm
|
|
||||||
}
|
|
||||||
@ -2,7 +2,6 @@ package initalize
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fusenapi/service/repositories"
|
"fusenapi/service/repositories"
|
||||||
"fusenapi/utils/queue"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -16,17 +15,16 @@ type Repositories struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NewAllRepositorieData struct {
|
type NewAllRepositorieData struct {
|
||||||
GormDB *gorm.DB
|
GormDB *gorm.DB
|
||||||
BLMServiceUrls []string
|
BLMServiceUrl *string
|
||||||
AwsSession *session.Session
|
AwsSession *session.Session
|
||||||
DelayQueue *queue.DelayMessage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAllRepositories(newData *NewAllRepositorieData) *Repositories {
|
func NewAllRepositories(newData *NewAllRepositorieData) *Repositories {
|
||||||
return &Repositories{
|
return &Repositories{
|
||||||
ImageHandle: repositories.NewImageHandle(newData.GormDB, newData.BLMServiceUrls, newData.AwsSession),
|
ImageHandle: repositories.NewImageHandle(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
||||||
NewShoppingCart: repositories.NewShoppingCart(newData.GormDB, newData.BLMServiceUrls, newData.AwsSession),
|
NewShoppingCart: repositories.NewShoppingCart(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
||||||
NewResource: repositories.NewResource(newData.GormDB, newData.BLMServiceUrls, newData.AwsSession),
|
NewResource: repositories.NewResource(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
||||||
NewOrder: repositories.NewOrder(newData.GormDB, newData.AwsSession, newData.DelayQueue),
|
NewOrder: repositories.NewOrder(newData.GormDB, newData.BLMServiceUrl, newData.AwsSession),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,16 +4,15 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// casbin_rule 后台--权限规则表
|
// casbin_rule
|
||||||
type CasbinRule struct {
|
type CasbinRule struct {
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 序号
|
PType *string `gorm:"default:'';" json:"p_type"` //
|
||||||
PType *string `gorm:"default:'';" json:"p_type"` //
|
V0 *string `gorm:"default:'';" json:"v0"` //
|
||||||
V0 *string `gorm:"default:'';" json:"v0"` //
|
V1 *string `gorm:"default:'';" json:"v1"` //
|
||||||
V1 *string `gorm:"default:'';" json:"v1"` //
|
V2 *string `gorm:"default:'';" json:"v2"` //
|
||||||
V2 *string `gorm:"default:'';" json:"v2"` //
|
V3 *string `gorm:"default:'';" json:"v3"` //
|
||||||
V3 *string `gorm:"default:'';" json:"v3"` //
|
V4 *string `gorm:"default:'';" json:"v4"` //
|
||||||
V4 *string `gorm:"default:'';" json:"v4"` //
|
V5 *string `gorm:"default:'';" json:"v5"` //
|
||||||
V5 *string `gorm:"default:'';" json:"v5"` //
|
|
||||||
}
|
}
|
||||||
type CasbinRuleModel struct {
|
type CasbinRuleModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -7,21 +7,23 @@ import (
|
|||||||
|
|
||||||
// fs_address 用户地址表
|
// fs_address 用户地址表
|
||||||
type FsAddress struct {
|
type FsAddress struct {
|
||||||
AddressId int64 `gorm:"primary_key;default:0;auto_increment;" json:"address_id"` //
|
AddressId int64 `gorm:"primary_key;default:0;auto_increment;" json:"address_id"` //
|
||||||
UserId *int64 `gorm:"default:0;" json:"user_id"` // 用户ID
|
UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户ID
|
||||||
FirstName *string `gorm:"default:'';" json:"first_name"` // FirstName
|
AddressName *string `gorm:"default:'';" json:"address_name"` //
|
||||||
LastName *string `gorm:"default:'';" json:"last_name"` // LastName
|
FirstName *string `gorm:"default:'';" json:"first_name"` // FirstName
|
||||||
Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码
|
LastName *string `gorm:"default:'';" json:"last_name"` // LastName
|
||||||
Street *string `gorm:"default:'';" json:"street"` // 街道
|
Mobile *string `gorm:"default:'';" json:"mobile"` // 手机号码
|
||||||
Suite *string `gorm:"default:'';" json:"suite"` // 房号
|
Street *string `gorm:"default:'';" json:"street"` // 街道
|
||||||
City *string `gorm:"default:'';" json:"city"` // 城市
|
Suite *string `gorm:"default:'';" json:"suite"` // 房号
|
||||||
State *string `gorm:"default:'';" json:"state"` //
|
City *string `gorm:"default:'';" json:"city"` // 城市
|
||||||
Country *string `gorm:"default:'';" json:"country"` //
|
State *string `gorm:"default:'';" json:"state"` //
|
||||||
ZipCode *string `gorm:"default:'';" json:"zip_code"` //
|
Country *string `gorm:"default:'';" json:"country"` //
|
||||||
Status *int64 `gorm:"default:0;" json:"status"` // 1正常 0异常
|
ZipCode *string `gorm:"default:'';" json:"zip_code"` //
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间
|
Status *int64 `gorm:"default:0;" json:"status"` // 1正常 0异常
|
||||||
Utime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间
|
IsDefault *int64 `gorm:"index;default:0;" json:"is_default"` // 1默认地址,0非默认地址
|
||||||
Ltime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` // 创建时间
|
||||||
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` // 更新时间
|
||||||
|
Ltime *time.Time `gorm:"index;default:'0000-00-00 00:00:00';" json:"ltime"` // 上次被使用的时间
|
||||||
}
|
}
|
||||||
type FsAddressModel struct {
|
type FsAddressModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -13,30 +13,11 @@ func (a *FsAddressModel) GetOne(ctx context.Context, addressId int64, userId int
|
|||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (resp []*FsAddressWithDefault, err error) {
|
func (a *FsAddressModel) GetUserAllAddress(ctx context.Context, userId int64) (resp []FsAddress, err error) {
|
||||||
resp = make([]*FsAddressWithDefault, 0)
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = ?", userId, 1).Order("`ltime` DESC").Find(&resp).Error
|
||||||
|
|
||||||
var dbresp []*FsAddress
|
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Where("`user_id` = ? and `status` = 1", userId).Order("`ltime` DESC").Find(&dbresp).Error
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now().UTC().AddDate(10, 0, 0).Unix()
|
|
||||||
for _, r := range dbresp {
|
|
||||||
rd := &FsAddressWithDefault{
|
|
||||||
FsAddress: r,
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Ltime.UTC().Unix() > now {
|
|
||||||
rd.IsDefault = 1
|
|
||||||
} else {
|
|
||||||
rd.IsDefault = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
resp = append(resp, rd)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,21 +26,38 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
|
|||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
result = &FsAddress{
|
result = &FsAddress{
|
||||||
UserId: address.UserId,
|
UserId: address.UserId,
|
||||||
FirstName: address.FirstName,
|
AddressName: address.AddressName,
|
||||||
LastName: address.LastName,
|
FirstName: address.FirstName,
|
||||||
Mobile: address.Mobile,
|
LastName: address.LastName,
|
||||||
Street: address.Street,
|
Mobile: address.Mobile,
|
||||||
Suite: address.Suite,
|
Street: address.Street,
|
||||||
City: address.City,
|
Suite: address.Suite,
|
||||||
State: address.State,
|
City: address.City,
|
||||||
Country: address.Country,
|
State: address.State,
|
||||||
ZipCode: address.ZipCode,
|
Country: address.Country,
|
||||||
Status: address.Status,
|
ZipCode: address.ZipCode,
|
||||||
Ctime: &now,
|
Status: address.Status,
|
||||||
Utime: &now,
|
IsDefault: address.IsDefault,
|
||||||
Ltime: &now,
|
Ctime: &now,
|
||||||
|
Utime: &now,
|
||||||
|
Ltime: &now,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lastOne := &FsAddress{}
|
||||||
|
// err = tx.Where("user_id = ?", lastOne.UserId).Order("ltime ASC").Take(&lastOne).Error
|
||||||
|
// if err == gorm.ErrRecordNotFound {
|
||||||
|
// result.Ltime = &now
|
||||||
|
// return tx.Model(&FsAddress{}).Create(result).Error
|
||||||
|
// }
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 根据lastOne处理时间
|
||||||
|
|
||||||
|
// ltime := (*lastOne.Ltime).Add(-time.Second)
|
||||||
|
// result.Ltime = <ime
|
||||||
return tx.Model(&FsAddress{}).Create(result).Error
|
return tx.Model(&FsAddress{}).Create(result).Error
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -73,7 +71,7 @@ func (a *FsAddressModel) CreateOne(ctx context.Context, address *FsAddress) (res
|
|||||||
func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress) (err error) {
|
func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress) (err error) {
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
err = tx.
|
err = tx.
|
||||||
Where("address_id = ? and user_id = ? and status = 1 ", address.AddressId, address.UserId).
|
Where("user_id = ? and address_id = ? and status = 1 ", address.UserId, address.AddressId).
|
||||||
Updates(address).Error
|
Updates(address).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -83,64 +81,34 @@ func (a *FsAddressModel) UpdateAddress(ctx context.Context, address *FsAddress)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64, isDefault int64) (err error) {
|
func (a *FsAddressModel) SettingUserDefaultAddress(ctx context.Context, userId int64, addressId int64) (err error) {
|
||||||
|
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
||||||
|
|
||||||
logx.Info("address_id:", addressId, " set default ", isDefault)
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
var updates = map[string]interface{}{
|
|
||||||
"ltime": now,
|
|
||||||
"utime": now,
|
|
||||||
}
|
|
||||||
|
|
||||||
if isDefault == 1 {
|
err = tx.Model(&FsAddress{}).Where(" `user_id` = ? and `status` = ? and `address_id` = ? ", userId, 1, addressId).
|
||||||
err = tx.Where("`user_id` = ? and `status` = 1 and `ltime` > ? and `address_id` != ?", userId, now.AddDate(10, 0, 0), addressId).
|
UpdateColumn("ltime", now.AddDate(250, 0, 0)).
|
||||||
UpdateColumns(updates).Error
|
UpdateColumn("utime", now).Error
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
updates["ltime"] = now.AddDate(250, 0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
tr := tx.Model(&FsAddress{}).Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
|
|
||||||
UpdateColumns(updates)
|
|
||||||
|
|
||||||
err = tr.Error
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = tx.Where(" `user_id` = ? and `status` = ? and `address_id` != ? and `ltime` > ? ", userId, 1, addressId, now.AddDate(10, 0, 0)).
|
||||||
|
UpdateColumn("ltime", now).Error
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *FsAddressModel) DeleteOne(ctx context.Context, addressId int64, userId int64) (err error) {
|
func (a *FsAddressModel) DeleteOne(ctx context.Context, addressId int64, userId int64) (err error) {
|
||||||
|
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).
|
err = a.db.WithContext(ctx).Model(&FsAddress{}).
|
||||||
Where("`address_id` = ? and `user_id` = ? and `status` = 1 ", addressId, userId).
|
Where("`address_id` = ? and `user_id` = ? and `status` = ? ", addressId, userId, 1).
|
||||||
UpdateColumn("status", 0).Error
|
UpdateColumn("status", 0).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateUsedAddress 当每次订单成功后, 更新一次地址使用时间
|
|
||||||
func (a *FsAddressModel) UpdateUsedAddress(ctx context.Context, addressId int64, userId int64) (err error) {
|
|
||||||
err = a.db.WithContext(ctx).Model(&FsAddress{}).Transaction(func(tx *gorm.DB) error {
|
|
||||||
logx.Info("address_id:", addressId, " update used")
|
|
||||||
now := time.Now().UTC()
|
|
||||||
var updates = map[string]interface{}{
|
|
||||||
"ltime": now,
|
|
||||||
"utime": now,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tx.Where("`address_id` = ? and `user_id` = ? and `status` = 1", addressId, userId).
|
|
||||||
UpdateColumns(updates).Error
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|||||||
@ -20,7 +20,6 @@ type FsAdminApi struct {
|
|||||||
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
||||||
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
||||||
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
||||||
Method *int64 `gorm:"default:0;" json:"method"` // 接口方法
|
|
||||||
}
|
}
|
||||||
type FsAdminApiModel struct {
|
type FsAdminApiModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -32,7 +32,6 @@ type FsAdminMenu struct {
|
|||||||
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
UpdateUid *int64 `gorm:"default:0;" json:"update_uid"` // 更新人
|
||||||
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
DeleteUid *int64 `gorm:"default:0;" json:"delete_uid"` // 删除人
|
||||||
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:1=是 0=否
|
||||||
ApiAuth *[]byte `gorm:"default:'';" json:"api_auth"` //
|
|
||||||
}
|
}
|
||||||
type FsAdminMenuModel struct {
|
type FsAdminMenuModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
package gmodel
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
// fs_admin_role_api 后台--角色接口表
|
|
||||||
type FsAdminRoleApi struct {
|
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 序号
|
|
||||||
RoleId *int64 `gorm:"index;default:0;" json:"role_id"` // 角色ID
|
|
||||||
MenuId *int64 `gorm:"index;default:0;" json:"menu_id"` // 菜单ID
|
|
||||||
ApiId *int64 `gorm:"index;default:0;" json:"api_id"` // 接口ID
|
|
||||||
ApiPath *string `gorm:"default:'';" json:"api_path"` //
|
|
||||||
ApiMethod *int64 `gorm:"default:0;" json:"api_method"` // 接口方法
|
|
||||||
}
|
|
||||||
type FsAdminRoleApiModel struct {
|
|
||||||
db *gorm.DB
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFsAdminRoleApiModel(db *gorm.DB) *FsAdminRoleApiModel {
|
|
||||||
return &FsAdminRoleApiModel{db: db, name: "fs_admin_role_api"}
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
package gmodel
|
|
||||||
// TODO: 使用model的属性做你想做的
|
|
||||||
@ -2,20 +2,18 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// fs_contact 该表暂未使用
|
// fs_contact 该表暂未使用
|
||||||
type FsContact struct {
|
type FsContact struct {
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` //
|
||||||
Name *string `gorm:"default:'';" json:"name"` //
|
Name *string `gorm:"default:'';" json:"name"` // 名字
|
||||||
Email *string `gorm:"index;default:'';" json:"email"` // 邮箱
|
Email *string `gorm:"index;default:'';" json:"email"` // 邮箱
|
||||||
Subject *string `gorm:"default:'0';" json:"subject"` // 主题
|
Subject *int64 `gorm:"default:0;" json:"subject"` // 主题
|
||||||
Message *string `gorm:"default:'';" json:"message"` // 消息
|
Message *string `gorm:"default:'';" json:"message"` // 消息
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
|
||||||
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 是否已处理
|
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 是否已处理
|
||||||
Mark *string `gorm:"default:'';" json:"mark"` // 后台订单备注
|
Mark *string `gorm:"default:'';" json:"mark"` // 后台订单备注
|
||||||
Phone *string `gorm:"default:'';" json:"phone"` //
|
|
||||||
}
|
}
|
||||||
type FsContactModel struct {
|
type FsContactModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -1,9 +1,3 @@
|
|||||||
package gmodel
|
package gmodel
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// TODO: 使用model的属性做你想做的
|
// TODO: 使用model的属性做你想做的
|
||||||
|
|
||||||
func (contact *FsContactModel) Save(ctx context.Context, obj *FsContact) (err error) {
|
|
||||||
return contact.db.WithContext(ctx).Model(&FsContact{}).Create(obj).Error
|
|
||||||
}
|
|
||||||
|
|||||||
@ -32,16 +32,7 @@ func (m *FsGuestModel) GenerateGuestID(ctx context.Context, AccessSecret uint64)
|
|||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
uinfo := &FsUserInfo{
|
|
||||||
Module: FsString("profile"),
|
|
||||||
UserId: FsInt64(0),
|
|
||||||
GuestId: &record.GuestId,
|
|
||||||
Metadata: FsBytes("{}"),
|
|
||||||
Ctime: &now,
|
|
||||||
Utime: &now,
|
|
||||||
}
|
|
||||||
return tx.Model(FsUserInfo{}).Create(uinfo).Error
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -7,24 +7,17 @@ import (
|
|||||||
|
|
||||||
// fs_order 订单表
|
// fs_order 订单表
|
||||||
type FsOrder struct {
|
type FsOrder struct {
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 订单ID
|
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // 订单ID
|
||||||
UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户ID
|
UserId *int64 `gorm:"index;default:0;" json:"user_id"` // 用户ID
|
||||||
DeliveryMethod *int64 `gorm:"index;default:0;" json:"delivery_method"` // 物流类型
|
DeliveryMethod *int64 `gorm:"index;default:0;" json:"delivery_method"` // 物流类型
|
||||||
OrderSn *string `gorm:"unique_key;default:'';" json:"order_sn"` //
|
OrderSn *string `gorm:"unique_key;default:'';" json:"order_sn"` //
|
||||||
OrderSource *string `gorm:"default:'';" json:"order_source"` //
|
OrderSource *string `gorm:"default:'';" json:"order_source"` //
|
||||||
Status *int64 `gorm:"index;default:0;" json:"status"` // 订单状态
|
Status *int64 `gorm:"index;default:0;" json:"status"` // 订单状态
|
||||||
Metadata *[]byte `gorm:"default:'';" json:"metadata"` //
|
Metadata *[]byte `gorm:"default:'';" json:"metadata"` //
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:0=否,1=是
|
IsDel *int64 `gorm:"default:0;" json:"is_del"` // 是否删除:0=否,1=是
|
||||||
PayStatus *int64 `gorm:"default:0;" json:"pay_status"` // 支付状态
|
PayStatus *int64 `gorm:"default:0;" json:"pay_status"` // 支付状态
|
||||||
StatusLink *[]byte `gorm:"default:'';" json:"status_link"` //
|
|
||||||
OrderProduct *[]byte `gorm:"default:'';" json:"order_product"` //
|
|
||||||
OrderAddress *[]byte `gorm:"default:'';" json:"order_address"` //
|
|
||||||
OrderAmount *[]byte `gorm:"default:'';" json:"order_amount"` //
|
|
||||||
PayStatusLink *[]byte `gorm:"default:'';" json:"pay_status_link"` //
|
|
||||||
ShoppingCartSnapshot *[]byte `gorm:"default:'';" json:"shopping_cart_snapshot"` //
|
|
||||||
ShoppingProductSnapshot *[]byte `gorm:"default:'';" json:"shopping_product_snapshot"` //
|
|
||||||
}
|
}
|
||||||
type FsOrderModel struct {
|
type FsOrderModel struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
|
|||||||
@ -73,14 +73,13 @@ type PayStatus struct {
|
|||||||
|
|
||||||
// 订单信息
|
// 订单信息
|
||||||
type OrderInfo struct {
|
type OrderInfo struct {
|
||||||
UserId int64 `json:"user_id"` // 物流类型
|
Ctime *time.Time `json:"ctime"` // 创建日期
|
||||||
Ctime *time.Time `json:"ctime"` // 创建日期
|
DeliveryMethod int64 `json:"delivery_method"` // 物流类型
|
||||||
DeliveryMethod int64 `json:"delivery_method"` // 物流类型
|
Metadata map[string]interface{} `json:"metadata"` // 额外参数
|
||||||
Metadata OrderMetadata `json:"metadata"` // 额外参数
|
OrderSn string `json:"order_sn"` // 订单编号
|
||||||
OrderSn string `json:"order_sn"` // 订单编号
|
Status OrderStatus `json:"status"` // 当前状态
|
||||||
Status OrderStatus `json:"status"` // 当前状态
|
StatusLink []OrderStatus `json:"status_link"` // 状态链路
|
||||||
StatusLink []OrderStatus `json:"status_link"` // 状态链路
|
Utime *time.Time `json:"utime"` // 更新时间
|
||||||
Utime *time.Time `json:"utime"` // 更新时间
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 订单状态--用户
|
// 订单状态--用户
|
||||||
@ -96,24 +95,21 @@ type OrderStatus struct {
|
|||||||
|
|
||||||
// 订单商品
|
// 订单商品
|
||||||
type OrderProduct struct {
|
type OrderProduct struct {
|
||||||
TotalPrice AmountInfo `json:"total_price"` // 商品总价
|
TotalPrice AmountInfo `json:"total_price"` // 商品总价
|
||||||
ItemPrice AmountInfo `json:"item_price"` // 商品单价
|
ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间
|
||||||
ExpectedDeliveryTime *time.Time `json:"expected_delivery_time"` // 预计到货时间
|
PurchaseQuantity PurchaseQuantity `json:"purchase_quantity"` // 购买数量
|
||||||
PurchaseQuantity PurchaseQuantity `json:"purchase_quantity"` // 购买数量
|
ProductID int64 `json:"product_id"` // 商品ID
|
||||||
ProductId int64 `json:"product_id"` // 商品ID
|
ProductName string `json:"product_name"` // 商品名称
|
||||||
ProductSn string `json:"product_sn"` // 商品编码
|
ItemPrice AmountInfo `json:"item_price"` // 商品单价
|
||||||
ProductName string `json:"product_name"` // 商品名称
|
ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照
|
||||||
ProductCover string `json:"product_cover"` // 商品封面
|
ShoppingCartSnapshot *FsShoppingCartData `json:"shopping_cart_snapshot"` // 购物车快照
|
||||||
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
ProductCover string `json:"product_cover"` // 商品封面
|
||||||
ProductSnapshot interface{} `json:"product_snapshot"` // 商品快照
|
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
||||||
ShoppingCartSnapshot *FsShoppingCartData `json:"shopping_cart_snapshot"` // 购物车快照
|
ProductSn string `json:"product_sn"` // 商品编码
|
||||||
|
DiyInformation *UserDiyInformation `json:"diy_information"`
|
||||||
DiyInformation *UserDiyInformation `json:"diy_information"`
|
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
||||||
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
||||||
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
||||||
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
|
||||||
RenderImage string `json:"render_image"`
|
|
||||||
SelectColorIndex int64 `json:"select_color_index"`
|
|
||||||
}
|
}
|
||||||
type PurchaseQuantity struct {
|
type PurchaseQuantity struct {
|
||||||
Current interface{} `json:"current"`
|
Current interface{} `json:"current"`
|
||||||
@ -135,31 +131,3 @@ type OrderProductFittingInfo struct {
|
|||||||
FittingID int64 `json:"fitting_id"` //配件ID
|
FittingID int64 `json:"fitting_id"` //配件ID
|
||||||
FittingName string `json:"fitting_name"` //配件名称
|
FittingName string `json:"fitting_name"` //配件名称
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExpectedDelivery struct {
|
|
||||||
Current time.Time `json:"current"`
|
|
||||||
Initiate time.Time `json:"initiate"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type OrderProductInter struct {
|
|
||||||
CartId int64 `json:"cart_id"` // 购物车ID
|
|
||||||
TotalPrice AmountInfo `json:"total_price"` // 商品总价
|
|
||||||
ItemPrice AmountInfo `json:"item_price"` // 商品单价
|
|
||||||
PurchaseQuantity *PurchaseQuantity `json:"purchase_quantity"` // 购买数量
|
|
||||||
ProductId int64 `json:"product_id"` // 商品ID
|
|
||||||
ProductName string `json:"product_name"` // 商品名称
|
|
||||||
ProductCover string `json:"product_cover"` // 商品封面
|
|
||||||
ProductCoverMetadata map[string]interface{} `json:"product_cover_metadata"` // 商品封面
|
|
||||||
ProductSn string `json:"product_sn"` // 商品编码
|
|
||||||
DiyInformation *UserDiyInformation `json:"diy_information"`
|
|
||||||
SizeInfo *OrderProductSizeInfo `json:"size_info"`
|
|
||||||
FittingInfo *OrderProductFittingInfo `json:"fitting_info"`
|
|
||||||
IsHighlyCustomized int64 `json:"is_highly_customized"`
|
|
||||||
RenderImage string `json:"render_image"`
|
|
||||||
ExpectedDeliveryTime *ExpectedDelivery `json:"expected_delivery_time"` // 预计到货时间
|
|
||||||
ActualDeliveryTime *ExpectedDelivery `json:"actual_delivery_time"` // 实际到货时间
|
|
||||||
}
|
|
||||||
type OrderMetadata struct {
|
|
||||||
ExpectedDeliveryTime *ExpectedDelivery `json:"expected_delivery_time"` // 预计到货时间
|
|
||||||
ActualDeliveryTime *ExpectedDelivery `json:"actual_delivery_time"` // 实际到货时间
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
package gmodel
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// fs_product_collection 产品收藏表
|
|
||||||
type FsProductCollection struct {
|
|
||||||
Id int64 `gorm:"primary_key;default:0;auto_increment;" json:"id"` // id
|
|
||||||
UserId *int64 `gorm:"default:0;" json:"user_id"` // 用户id
|
|
||||||
GuestId *int64 `gorm:"default:0;" json:"guest_id"` // 游客id
|
|
||||||
ProductId *int64 `gorm:"default:0;" json:"product_id"` // 产品id
|
|
||||||
TemplateTag *string `gorm:"default:'';" json:"template_tag"` //
|
|
||||||
SelectColorIndex *int64 `gorm:"default:0;" json:"select_color_index"` // 选择的颜色索引
|
|
||||||
Logo *string `gorm:"default:'';" json:"logo"` // logo地址
|
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
|
||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
|
||||||
}
|
|
||||||
type FsProductCollectionModel struct {
|
|
||||||
db *gorm.DB
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFsProductCollectionModel(db *gorm.DB) *FsProductCollectionModel {
|
|
||||||
return &FsProductCollectionModel{db: db, name: "fs_product_collection"}
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
package gmodel
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
func (c *FsProductCollectionModel) FindOne(ctx context.Context, userId, guestId, productId int64) (resp *FsProductCollection, err error) {
|
|
||||||
err = c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
|
||||||
Where("user_id = ? and guest_id = ? and product_id = ?", userId, guestId, productId).
|
|
||||||
Take(&resp).Error
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建
|
|
||||||
func (c *FsProductCollectionModel) Create(ctx context.Context, data *FsProductCollection) error {
|
|
||||||
return c.db.WithContext(ctx).Model(&FsProductCollection{}).Create(&data).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新
|
|
||||||
func (c *FsProductCollectionModel) Update(ctx context.Context, userId, guestId, productId int64, data *FsProductCollection) error {
|
|
||||||
return c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
|
||||||
Where("user_id = ? and guest_id = ? and product_id = ?", userId, guestId, productId).
|
|
||||||
Updates(&data).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
func (c *FsProductCollectionModel) Delete(ctx context.Context, userId, guestId, productId int64) error {
|
|
||||||
return c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
|
||||||
Where("user_id = ? and guest_id = ? and product_id = ?", userId, guestId, productId).
|
|
||||||
Delete(&FsProductCollection{}).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
func (c *FsProductCollectionModel) Delete2(ctx context.Context, userId, guestId, id int64) error {
|
|
||||||
return c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
|
||||||
Where("user_id = ? and guest_id = ? and id = ?", userId, guestId, id).
|
|
||||||
Delete(&FsProductCollection{}).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取列表
|
|
||||||
func (c *FsProductCollectionModel) GetList(ctx context.Context, userId, guestId int64, page, limit int, sort string) (resp []FsProductCollection, total int64, err error) {
|
|
||||||
db := c.db.WithContext(ctx).Model(&FsProductCollection{}).
|
|
||||||
Where("user_id = ? and guest_id = ?", userId, guestId)
|
|
||||||
if sort != "" {
|
|
||||||
db = db.Order(sort)
|
|
||||||
}
|
|
||||||
if err = db.Count(&total).Error; err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
offset := (page - 1) * limit
|
|
||||||
err = db.Offset(offset).Limit(limit).Find(&resp).Error
|
|
||||||
return resp, total, err
|
|
||||||
}
|
|
||||||
@ -11,11 +11,11 @@ type FsProduct struct {
|
|||||||
Type *int64 `gorm:"default:0;" json:"type"` // 分类ID
|
Type *int64 `gorm:"default:0;" json:"type"` // 分类ID
|
||||||
Title *string `gorm:"default:'';" json:"title"` // 名称
|
Title *string `gorm:"default:'';" json:"title"` // 名称
|
||||||
TitleCn *string `gorm:"default:'';" json:"title_cn"` // 中文名称
|
TitleCn *string `gorm:"default:'';" json:"title_cn"` // 中文名称
|
||||||
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序
|
|
||||||
Cover *string `gorm:"default:'';" json:"cover"` // 封面图
|
Cover *string `gorm:"default:'';" json:"cover"` // 封面图
|
||||||
Imgs *string `gorm:"default:'';" json:"imgs"` // 一个或多个介绍图或视频
|
Imgs *string `gorm:"default:'';" json:"imgs"` // 一个或多个介绍图或视频
|
||||||
Keywords *string `gorm:"default:'';" json:"keywords"` // 关键字
|
Keywords *string `gorm:"default:'';" json:"keywords"` // 关键字
|
||||||
Intro *string `gorm:"default:'';" json:"intro"` // 简要描述
|
Intro *string `gorm:"default:'';" json:"intro"` // 简要描述
|
||||||
|
Sort *int64 `gorm:"default:0;" json:"sort"` // 排序
|
||||||
SelledNum *int64 `gorm:"default:0;" json:"selled_num"` // 已卖数量
|
SelledNum *int64 `gorm:"default:0;" json:"selled_num"` // 已卖数量
|
||||||
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
|
Ctime *int64 `gorm:"default:0;" json:"ctime"` // 添加时间
|
||||||
View *int64 `gorm:"default:0;" json:"view"` // 浏览量
|
View *int64 `gorm:"default:0;" json:"view"` // 浏览量
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import "context"
|
|||||||
|
|
||||||
type RelaFsProduct struct {
|
type RelaFsProduct struct {
|
||||||
FsProduct
|
FsProduct
|
||||||
CoverResource *FsResource `json:"cover_resource" gorm:"foreignkey:cover;references:resource_url"`
|
CoverResource *FsResource `json:"cover_resource" gorm:"foreignkey:cover;references:resource_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FsProductModel) TableName() string {
|
func (m *FsProductModel) TableName() string {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ type FsProductModel3d struct {
|
|||||||
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除
|
Status *int64 `gorm:"default:0;" json:"status"` // 状态位 显示 删除
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
OptionTemplate *int64 `gorm:"default:0;" json:"option_template"` // 配件绑定的公共模板
|
OptionTemplate *int64 `gorm:"default:0;" json:"option_template"` // 配件绑定的公共模板
|
||||||
Price *int64 `gorm:"default:0;" json:"price"` // 仅配件用,配件的价格, 单位:0.1美分
|
Price *int64 `gorm:"default:0;" json:"price"` //
|
||||||
Sku *string `gorm:"default:'';" json:"sku"` // sku
|
Sku *string `gorm:"default:'';" json:"sku"` // sku
|
||||||
IsHot *int64 `gorm:"default:0;" json:"is_hot"` // 是否热门
|
IsHot *int64 `gorm:"default:0;" json:"is_hot"` // 是否热门
|
||||||
IsCloudRender *int64 `gorm:"default:0;" json:"is_cloud_render"` // 是否设置为云渲染模型
|
IsCloudRender *int64 `gorm:"default:0;" json:"is_cloud_render"` // 是否设置为云渲染模型
|
||||||
|
|||||||
@ -2,11 +2,6 @@ package gmodel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"fusenapi/constants"
|
|
||||||
"sort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 阶梯价结构
|
// 阶梯价结构
|
||||||
@ -157,72 +152,3 @@ func (d *FsProductModel3dModel) FindOneByProductIdSizeIdTag(ctx context.Context,
|
|||||||
err = db.Take(&resp).Error
|
err = db.Take(&resp).Error
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *FsProductModel3dModel) GetAllByProductIdsTags(ctx context.Context, productIds []int64, tags []int, fields ...string) (resp []FsProductModel3d, err error) {
|
|
||||||
if len(productIds) == 0 || len(tags) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
db := d.db.WithContext(ctx).Model(&FsProductModel3d{}).
|
|
||||||
Where("`product_id` in (?) and `tag` in (?) and `status` = ?", productIds, tags, 1).
|
|
||||||
Order("sort DESC")
|
|
||||||
if len(fields) != 0 {
|
|
||||||
db = db.Select(fields[0])
|
|
||||||
}
|
|
||||||
err = db.Find(&resp).Error
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取每个产品最低价格
|
|
||||||
func (d *FsProductModel3dModel) GetProductMinPrice(ctx context.Context, productIds []int64, mapProductMinPrice map[int64]int64) error {
|
|
||||||
//获取产品模型价格列表
|
|
||||||
modelList, err := d.GetAllByProductIdsTags(ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,product_id,price,tag,part_id,step_price")
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("failed to get model list")
|
|
||||||
}
|
|
||||||
mapModelMinPrice := make(map[int64]int64)
|
|
||||||
//每个模型/配件存储最小价格
|
|
||||||
for _, modelInfo := range modelList {
|
|
||||||
switch *modelInfo.Tag {
|
|
||||||
case constants.TAG_MODEL: //模型
|
|
||||||
if modelInfo.StepPrice == nil || len(*modelInfo.StepPrice) == 0 {
|
|
||||||
mapModelMinPrice[modelInfo.Id] = 0
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var stepPrice StepPriceJsonStruct
|
|
||||||
if err = json.Unmarshal(*modelInfo.StepPrice, &stepPrice); err != nil {
|
|
||||||
return errors.New(fmt.Sprintf("failed to parse model step price:%d", modelInfo.Id))
|
|
||||||
}
|
|
||||||
lenRange := len(stepPrice.PriceRange)
|
|
||||||
if lenRange == 0 {
|
|
||||||
mapModelMinPrice[modelInfo.Id] = 0
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
sort.SliceStable(stepPrice.PriceRange, func(i, j int) bool {
|
|
||||||
return stepPrice.PriceRange[i].Price > stepPrice.PriceRange[j].Price
|
|
||||||
})
|
|
||||||
mapModelMinPrice[modelInfo.Id] = stepPrice.PriceRange[lenRange-1].Price
|
|
||||||
case constants.TAG_PARTS: //配件
|
|
||||||
mapModelMinPrice[modelInfo.Id] = *modelInfo.Price
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//给产品存储最小价格
|
|
||||||
for _, v := range modelList {
|
|
||||||
if *v.Tag != constants.TAG_MODEL {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
itemPrice := mapModelMinPrice[v.Id]
|
|
||||||
if *v.PartId > 0 {
|
|
||||||
if fittingPrice, ok := mapModelMinPrice[*v.PartId]; ok {
|
|
||||||
itemPrice += fittingPrice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if minPrice, ok := mapProductMinPrice[*v.ProductId]; ok {
|
|
||||||
if itemPrice < minPrice {
|
|
||||||
mapProductMinPrice[*v.ProductId] = itemPrice
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
mapProductMinPrice[*v.ProductId] = itemPrice
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ type FsShoppingCart struct {
|
|||||||
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
||||||
Snapshot *string `gorm:"default:'';" json:"snapshot"` //
|
Snapshot *string `gorm:"default:'';" json:"snapshot"` //
|
||||||
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
||||||
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制,该类行无法跳详情页)
|
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制只能后台增加如购物车)
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,12 +27,14 @@ type FsShoppingCartData struct {
|
|||||||
FittingId *int64 `gorm:"default:0;" json:"fitting_id"` // 配件id
|
FittingId *int64 `gorm:"default:0;" json:"fitting_id"` // 配件id
|
||||||
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
PurchaseQuantity *int64 `gorm:"default:0;" json:"purchase_quantity"` // 购买数量
|
||||||
Snapshot *map[string]interface{} `gorm:"default:'';" json:"snapshot"` //
|
Snapshot *map[string]interface{} `gorm:"default:'';" json:"snapshot"` //
|
||||||
|
SnapshotData *string `gorm:"default:'';" json:"snapshot_data"` //
|
||||||
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
IsSelected *int64 `gorm:"default:0;" json:"is_selected"` // 是否被选中 0非 1是
|
||||||
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制只能后台增加如购物车)
|
IsHighlyCustomized *int64 `gorm:"default:0;" json:"is_highly_customized"` // 是否高度定制 0非 1是(针对客人高度定制只能后台增加如购物车)
|
||||||
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
Ctime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"ctime"` //
|
||||||
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
Utime *time.Time `gorm:"default:'0000-00-00 00:00:00';" json:"utime"` //
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 快照json数据结构
|
||||||
// 购物车快照数据结构
|
// 购物车快照数据结构
|
||||||
type CartSnapshot struct {
|
type CartSnapshot struct {
|
||||||
Logo string `json:"logo"` //logo地址
|
Logo string `json:"logo"` //logo地址
|
||||||
@ -51,17 +53,16 @@ type ProductInfo struct {
|
|||||||
ProductSn string `json:"product_sn"`
|
ProductSn string `json:"product_sn"`
|
||||||
}
|
}
|
||||||
type ModelInfo struct {
|
type ModelInfo struct {
|
||||||
ModelJson interface{} `json:"model_json"` //模型设计json数据
|
ModelJson string `json:"model_json"` //模型设计json数据
|
||||||
}
|
}
|
||||||
type FittingInfo struct {
|
type FittingInfo struct {
|
||||||
FittingJson interface{} `json:"fitting_json"` //配件设计json数据
|
FittingJson string `json:"fitting_json"` //配件设计json数据
|
||||||
FittingName string `json:"fitting_name"` //配件名称
|
FittingName string `json:"fitting_name"` //配件名称
|
||||||
|
|
||||||
}
|
}
|
||||||
type TemplateInfo struct {
|
type TemplateInfo struct {
|
||||||
TemplateJson interface{} `json:"template_json"` //模板设计json数据
|
TemplateJson string `json:"template_json"` //模板设计json数据
|
||||||
TemplateTag string `json:"template_tag"` //模板标签
|
TemplateTag string `json:"template_tag"` //模板标签
|
||||||
SelectColorIndex int64 `json:"select_color_index"` //颜色选择索引
|
|
||||||
}
|
}
|
||||||
type SizeInfo struct {
|
type SizeInfo struct {
|
||||||
Inch string `json:"inch"`
|
Inch string `json:"inch"`
|
||||||
@ -76,8 +77,8 @@ type UserDiyInformation struct {
|
|||||||
Slogan string `json:"slogan"` //slogan
|
Slogan string `json:"slogan"` //slogan
|
||||||
}
|
}
|
||||||
type LightInfo struct {
|
type LightInfo struct {
|
||||||
LightJson interface{} `json:"light_json"` //灯光设计json数据
|
LightJson string `json:"light_json"` //灯光设计json数据
|
||||||
LightName string `json:"light_name"` //名称
|
LightName string `json:"light_name"` //名称
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取单个
|
// 获取单个
|
||||||
|
|||||||
@ -47,7 +47,9 @@ func (p *FsUserInfoModel) CreateOrUpdate(gormDB *gorm.DB, req *FsUserInfo) (resp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *FsUserInfoModel) MergeMetadata(userId int64, meta any) error {
|
func (m *FsUserInfoModel) MergeMetadata(userId int64, meta any) error {
|
||||||
return fssql.MetadataModulePATCH(m.db, "profile", FsUserInfo{}, meta, "user_id = ?", userId)
|
return fssql.MetadataModulePATCH(m.db, "profile", FsUserInfo{}, map[string]any{
|
||||||
|
"base": meta,
|
||||||
|
}, "user_id = ?", userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId int64) (map[string]any, error) {
|
func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId int64) (map[string]any, error) {
|
||||||
@ -79,11 +81,3 @@ func (m *FsUserInfoModel) GetProfile(ctx context.Context, pkey string, userId in
|
|||||||
}
|
}
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
func (m *FsUserInfoModel) FindOneByUser(ctx context.Context, userId, guestId int64) (resp *FsUserInfo, err error) {
|
|
||||||
if userId > 0 {
|
|
||||||
err = m.db.WithContext(ctx).Model(&FsUserInfo{}).Where("user_id = ?", userId).Take(&resp).Error
|
|
||||||
} else {
|
|
||||||
err = m.db.WithContext(ctx).Model(&FsUserInfo{}).Where("user_id = ? and guest_id = ?", userId, guestId).Take(&resp).Error
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|||||||
@ -121,58 +121,13 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
|
|||||||
user.GoogleId = &googleId
|
user.GoogleId = &googleId
|
||||||
user.PasswordHash = &token.Password
|
user.PasswordHash = &token.Password
|
||||||
user.FirstName = &firstName
|
user.FirstName = &firstName
|
||||||
user.LastName = &lastName
|
user.FirstName = &lastName
|
||||||
err = tx.Model(&FsUser{}).Create(user).Error
|
err = tx.Model(&FsUser{}).Create(user).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 继承guest_id的资源表
|
// 继承guest_id的资源表
|
||||||
return InheritGuestIdResource(tx, user.Id, token.GuestId, func(txResouce, txUserMaterial, txUserInfo *gorm.DB) error {
|
return InheritGuestIdResource(tx, user.Id, token.GuestId, nil)
|
||||||
userProfileBase := UserProfileBase{
|
|
||||||
FirstName: *user.FirstName,
|
|
||||||
LastName: *user.LastName,
|
|
||||||
Email: *user.Email,
|
|
||||||
}
|
|
||||||
|
|
||||||
userProfile := &UserProfile{
|
|
||||||
ProfileBase: userProfileBase,
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata, err := json.Marshal(userProfile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now().UTC()
|
|
||||||
uinfo := &FsUserInfo{
|
|
||||||
Module: FsString("profile"),
|
|
||||||
UserId: &user.Id,
|
|
||||||
GuestId: &token.GuestId,
|
|
||||||
Metadata: &metadata,
|
|
||||||
Ctime: &now,
|
|
||||||
Utime: &now,
|
|
||||||
}
|
|
||||||
|
|
||||||
// logx.Error(metadata)
|
|
||||||
|
|
||||||
err = txUserInfo.Where("module = 'profile' and user_id = ?", *uinfo.UserId).Take(nil).Error
|
|
||||||
if err != nil {
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
err = tx.Model(&FsUserInfo{}).Create(uinfo).Error
|
|
||||||
// logx.Info(err, "*uinfo.UserId:", *uinfo.UserId, " ", uinfo.Id)
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fssql.MetadataModulePATCH(txUserInfo, "profile", FsUserInfo{}, metadata, "user_id = ?", *uinfo.UserId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -223,7 +178,6 @@ func (u *FsUserModel) RegisterByFusen(ctx context.Context, token *auth.RegisterT
|
|||||||
FirstName: FirstName,
|
FirstName: FirstName,
|
||||||
LastName: LastName,
|
LastName: LastName,
|
||||||
Resetaurant: Resetaurant,
|
Resetaurant: Resetaurant,
|
||||||
Email: *user.Email,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userProfile := &UserProfile{
|
userProfile := &UserProfile{
|
||||||
|
|||||||
@ -36,22 +36,11 @@ func FsBool(v bool) *bool {
|
|||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
func FsBytes(v string) *[]byte {
|
|
||||||
bs := []byte(v)
|
|
||||||
return &bs
|
|
||||||
}
|
|
||||||
|
|
||||||
// SubscriptionStatus 订阅状态
|
// SubscriptionStatus 订阅状态
|
||||||
type SubscriptionStatus struct {
|
type SubscriptionStatus struct {
|
||||||
NotificationEmail struct {
|
SubEmail bool `json:"all_emails"`
|
||||||
OrderUpdate bool `json:"order_update"`
|
ItemMap *struct {
|
||||||
Newseleter bool `json:"newseleter"`
|
} `json:"item_map"`
|
||||||
} `json:"notification_email"`
|
|
||||||
|
|
||||||
NotificationPhone struct {
|
|
||||||
OrderUpdate bool `json:"order_update"`
|
|
||||||
Newseleter bool `json:"newseleter"`
|
|
||||||
} `json:"notification_phone"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserProfile struct {
|
type UserProfile struct {
|
||||||
@ -63,13 +52,8 @@ type UserProfile struct {
|
|||||||
type UserProfileBase struct {
|
type UserProfileBase struct {
|
||||||
FirstName string `json:"first_name"` // 首名
|
FirstName string `json:"first_name"` // 首名
|
||||||
LastName string `json:"last_name"` // 后名
|
LastName string `json:"last_name"` // 后名
|
||||||
Email string `json:"email"` // email
|
UserName string `json:"user_name"` // 用户名
|
||||||
Mobile string `json:"mobile"` // 电话
|
Mobile string `json:"mobile"` // 电话
|
||||||
Resetaurant string `json:"resetaurant"` // 不知道干什么
|
Resetaurant string `json:"resetaurant"` // 不知道干什么
|
||||||
Company string `json:"company"` // 公司
|
Company string `json:"company"` // 公司
|
||||||
}
|
}
|
||||||
|
|
||||||
type FsAddressWithDefault struct {
|
|
||||||
*FsAddress
|
|
||||||
IsDefault int64 `json:"is_default"`
|
|
||||||
}
|
|
||||||
|
|||||||
@ -4,13 +4,12 @@ import "gorm.io/gorm"
|
|||||||
|
|
||||||
// AllModelsGen 所有Model集合,修改单行,只要不改字段名,不会根据新的内容修改,需要修改的话手动删除
|
// AllModelsGen 所有Model集合,修改单行,只要不改字段名,不会根据新的内容修改,需要修改的话手动删除
|
||||||
type AllModelsGen struct {
|
type AllModelsGen struct {
|
||||||
CasbinRule *CasbinRuleModel // casbin_rule 后台--权限规则表
|
CasbinRule *CasbinRuleModel // casbin_rule
|
||||||
FsAddress *FsAddressModel // fs_address 用户地址表
|
FsAddress *FsAddressModel // fs_address 用户地址表
|
||||||
FsAdminApi *FsAdminApiModel // fs_admin_api 后台--接口表
|
FsAdminApi *FsAdminApiModel // fs_admin_api 后台--接口表
|
||||||
FsAdminDepartment *FsAdminDepartmentModel // fs_admin_department 后台--部门表
|
FsAdminDepartment *FsAdminDepartmentModel // fs_admin_department 后台--部门表
|
||||||
FsAdminMenu *FsAdminMenuModel // fs_admin_menu 后台--菜单表
|
FsAdminMenu *FsAdminMenuModel // fs_admin_menu 后台--菜单表
|
||||||
FsAdminRole *FsAdminRoleModel // fs_admin_role 后台--角色表
|
FsAdminRole *FsAdminRoleModel // fs_admin_role 后台--角色表
|
||||||
FsAdminRoleApi *FsAdminRoleApiModel // fs_admin_role_api 后台--角色接口表
|
|
||||||
FsAdminUser *FsAdminUserModel // fs_admin_user 后台--管理员表
|
FsAdminUser *FsAdminUserModel // fs_admin_user 后台--管理员表
|
||||||
FsAuthAssignment *FsAuthAssignmentModel // fs_auth_assignment 用户角色和权限信息
|
FsAuthAssignment *FsAuthAssignmentModel // fs_auth_assignment 用户角色和权限信息
|
||||||
FsAuthItem *FsAuthItemModel // fs_auth_item 用户角色和权限信息
|
FsAuthItem *FsAuthItemModel // fs_auth_item 用户角色和权限信息
|
||||||
@ -68,7 +67,6 @@ type AllModelsGen struct {
|
|||||||
FsPay *FsPayModel // fs_pay 支付记录
|
FsPay *FsPayModel // fs_pay 支付记录
|
||||||
FsPayEvent *FsPayEventModel // fs_pay_event 支付回调事件日志
|
FsPayEvent *FsPayEventModel // fs_pay_event 支付回调事件日志
|
||||||
FsProduct *FsProductModel // fs_product 产品表
|
FsProduct *FsProductModel // fs_product 产品表
|
||||||
FsProductCollection *FsProductCollectionModel // fs_product_collection 产品收藏表
|
|
||||||
FsProductCopy1 *FsProductCopy1Model // fs_product_copy1 产品表
|
FsProductCopy1 *FsProductCopy1Model // fs_product_copy1 产品表
|
||||||
FsProductDesign *FsProductDesignModel // fs_product_design 产品设计表
|
FsProductDesign *FsProductDesignModel // fs_product_design 产品设计表
|
||||||
FsProductDesignGather *FsProductDesignGatherModel // fs_product_design_gather
|
FsProductDesignGather *FsProductDesignGatherModel // fs_product_design_gather
|
||||||
@ -123,7 +121,6 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
|
|||||||
FsAdminDepartment: NewFsAdminDepartmentModel(gdb),
|
FsAdminDepartment: NewFsAdminDepartmentModel(gdb),
|
||||||
FsAdminMenu: NewFsAdminMenuModel(gdb),
|
FsAdminMenu: NewFsAdminMenuModel(gdb),
|
||||||
FsAdminRole: NewFsAdminRoleModel(gdb),
|
FsAdminRole: NewFsAdminRoleModel(gdb),
|
||||||
FsAdminRoleApi: NewFsAdminRoleApiModel(gdb),
|
|
||||||
FsAdminUser: NewFsAdminUserModel(gdb),
|
FsAdminUser: NewFsAdminUserModel(gdb),
|
||||||
FsAuthAssignment: NewFsAuthAssignmentModel(gdb),
|
FsAuthAssignment: NewFsAuthAssignmentModel(gdb),
|
||||||
FsAuthItem: NewFsAuthItemModel(gdb),
|
FsAuthItem: NewFsAuthItemModel(gdb),
|
||||||
@ -181,7 +178,6 @@ func NewAllModels(gdb *gorm.DB) *AllModelsGen {
|
|||||||
FsPay: NewFsPayModel(gdb),
|
FsPay: NewFsPayModel(gdb),
|
||||||
FsPayEvent: NewFsPayEventModel(gdb),
|
FsPayEvent: NewFsPayEventModel(gdb),
|
||||||
FsProduct: NewFsProductModel(gdb),
|
FsProduct: NewFsProductModel(gdb),
|
||||||
FsProductCollection: NewFsProductCollectionModel(gdb),
|
|
||||||
FsProductCopy1: NewFsProductCopy1Model(gdb),
|
FsProductCopy1: NewFsProductCopy1Model(gdb),
|
||||||
FsProductDesign: NewFsProductDesignModel(gdb),
|
FsProductDesign: NewFsProductDesignModel(gdb),
|
||||||
FsProductDesignGather: NewFsProductDesignGatherModel(gdb),
|
FsProductDesignGather: NewFsProductDesignGatherModel(gdb),
|
||||||
|
|||||||
@ -91,20 +91,23 @@ func main() {
|
|||||||
routes...))
|
routes...))
|
||||||
}
|
}
|
||||||
|
|
||||||
Backends = append(Backends, NewBackend(mux,
|
|
||||||
fmt.Sprintf("http://%s:%d", "localhost", 9501),
|
|
||||||
"/api/v1/namespaces/kubernetes-dashboard"))
|
|
||||||
|
|
||||||
// 定义用于服务Vue dist文件夹的静态文件服务器
|
// 定义用于服务Vue dist文件夹的静态文件服务器
|
||||||
fs := http.FileServer(http.Dir(vueBuild))
|
fs := http.FileServer(http.Dir(vueBuild))
|
||||||
indexHtmlPath := vueBuild + "/index.html"
|
indexHtmlPath := vueBuild + "/index.html"
|
||||||
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if strings.HasPrefix(r.URL.Path, "/api/") {
|
if strings.HasPrefix(r.URL.Path, "/api/") {
|
||||||
|
|
||||||
r.ParseMultipartForm(100 << 20)
|
r.ParseMultipartForm(100 << 20)
|
||||||
|
// if err != nil {
|
||||||
|
// logx.Error(err)
|
||||||
|
// }
|
||||||
|
|
||||||
// 对/api开头的请求进行反向代理
|
// 对/api开头的请求进行反向代理
|
||||||
proxy := httputil.NewSingleHostReverseProxy(apiURL)
|
proxy := httputil.NewSingleHostReverseProxy(apiURL)
|
||||||
proxy.ServeHTTP(w, r)
|
proxy.ServeHTTP(w, r)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 根据请求路径判断是服务静态文件或者是返回index.html
|
// 根据请求路径判断是服务静态文件或者是返回index.html
|
||||||
idx := strings.Index(r.URL.Path[1:], "/")
|
idx := strings.Index(r.URL.Path[1:], "/")
|
||||||
|
|||||||
@ -48,7 +48,7 @@ run_server() {
|
|||||||
|
|
||||||
# 循环检查screen进程是否存在
|
# 循环检查screen进程是否存在
|
||||||
|
|
||||||
[ -f .gitignore ] || (echo "$server_name" > .gitignore && echo "main" >> .gitignore)
|
[ -f .gitignore ] || echo $server_name > .gitignore
|
||||||
# 使用 screen 运行 go run <server_name>.go
|
# 使用 screen 运行 go run <server_name>.go
|
||||||
|
|
||||||
echo "Running $server_name"
|
echo "Running $server_name"
|
||||||
|
|||||||
1
server/auth/.gitignore
vendored
1
server/auth/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
auth
|
auth
|
||||||
main
|
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
FROM alpine
|
FROM alpine
|
||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-auth-srv /www/fusenapi/
|
COPY ./bin/api-assistant-srv /www/fusenapi/
|
||||||
COPY ./env.yaml /opt/
|
COPY ./etc /www/fusenapi/etc
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
CMD ["/www/fusenapi/api-assistant-srv"]
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-auth-srv"]
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@ Name: auth
|
|||||||
Host: localhost
|
Host: localhost
|
||||||
Port: 9980
|
Port: 9980
|
||||||
ReplicaId: 10
|
ReplicaId: 10
|
||||||
HomePage: "http://www.fusen.3718.cn"
|
|
||||||
MainAddress: "https://server.fusen.3718.cn:9900"
|
MainAddress: "https://server.fusen.3718.cn:9900"
|
||||||
WebsocketAddr: "https://server.fusen.3718.cn:9914"
|
WebsocketAddr: "https://server.fusen.3718.cn:9914"
|
||||||
SourceMysql: "fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen"
|
SourceMysql: "fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen"
|
||||||
|
|||||||
@ -12,7 +12,6 @@ type Config struct {
|
|||||||
Auth types.Auth
|
Auth types.Auth
|
||||||
ReplicaId uint64
|
ReplicaId uint64
|
||||||
|
|
||||||
HomePage string
|
|
||||||
MainAddress string
|
MainAddress string
|
||||||
WebsocketAddr string
|
WebsocketAddr string
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ func init() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeLimit = check.NewTimeLimit[string](EmailTaskResendTime)
|
TimeLimit = check.NewTimelimit[string](EmailTaskResendTime)
|
||||||
|
|
||||||
// Initialize the email manager
|
// Initialize the email manager
|
||||||
EmailManager = &EmailSender{
|
EmailManager = &EmailSender{
|
||||||
@ -53,17 +53,16 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EmailFormat struct {
|
type EmailFormat struct {
|
||||||
TemplateName string // 模板名字
|
TemplateName string // 模板名字
|
||||||
UniqueKey string // 用于处理唯一的任务,重发都会被利用到
|
UniqueKey string // 用于处理唯一的任务,重发都会被利用到
|
||||||
TargetEmail string // 发送的目标email
|
TargetEmail string // 发送的目标email
|
||||||
CompanyName string // fs公司名
|
CompanyName string // fs公司名
|
||||||
ConfirmationLink string // fs确认连接
|
ConfirmationLink string // fs确认连接
|
||||||
SenderName string // 发送人
|
SenderName string // 发送人
|
||||||
SenderTitle string // 发送标题
|
SenderTitle string // 发送标题
|
||||||
Extend map[string]string // 扩展参数
|
Extend map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证邮件格式是否符合要求
|
|
||||||
func (eformat *EmailFormat) Vaild() error {
|
func (eformat *EmailFormat) Vaild() error {
|
||||||
|
|
||||||
// 1. 检查模板名称
|
// 1. 检查模板名称
|
||||||
@ -124,47 +123,39 @@ type EmailTask struct {
|
|||||||
SendTime time.Time // 处理的任务时间
|
SendTime time.Time // 处理的任务时间
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessEmailTasks 是 EmailSender 结构体的方法,用于处理邮件任务。
|
|
||||||
func (m *EmailSender) ProcessEmailTasks() {
|
func (m *EmailSender) ProcessEmailTasks() {
|
||||||
for {
|
for {
|
||||||
// 从 EmailTasks 通道中接收邮件任务
|
|
||||||
emailformat, ok := <-m.EmailTasks
|
emailformat, ok := <-m.EmailTasks
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Println("Email task channel closed")
|
log.Println("Email task channel closed")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证邮件格式是否合法
|
|
||||||
err := emailformat.Vaild()
|
err := emailformat.Vaild()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加锁,避免并发修改 emailSending 字典
|
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
|
|
||||||
// 检查 emailSending 字典中是否已存在相同的任务
|
|
||||||
_, isSending := m.emailSending[emailformat.UniqueKey]
|
_, isSending := m.emailSending[emailformat.UniqueKey]
|
||||||
if isSending {
|
if isSending {
|
||||||
m.lock.Unlock()
|
m.lock.Unlock()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将邮件任务添加到 emailSending 字典中
|
|
||||||
m.emailSending[emailformat.UniqueKey] = &EmailTask{
|
m.emailSending[emailformat.UniqueKey] = &EmailTask{
|
||||||
Email: emailformat,
|
Email: emailformat,
|
||||||
SendTime: time.Now().UTC(),
|
SendTime: time.Now().UTC(),
|
||||||
}
|
}
|
||||||
m.lock.Unlock()
|
m.lock.Unlock()
|
||||||
|
|
||||||
// 获取一个信号量,限制同时发送的邮件任务数量
|
// Acquire a token
|
||||||
m.semaphore <- struct{}{}
|
m.semaphore <- struct{}{}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer func() { <-m.semaphore }() // 释放一个信号量
|
defer func() { <-m.semaphore }() // Release a token
|
||||||
|
|
||||||
// 渲染邮件模板内容
|
|
||||||
content := RenderEmailTemplate(
|
content := RenderEmailTemplate(
|
||||||
emailformat.TemplateName,
|
emailformat.TemplateName,
|
||||||
emailformat.CompanyName,
|
emailformat.CompanyName,
|
||||||
@ -173,41 +164,34 @@ func (m *EmailSender) ProcessEmailTasks() {
|
|||||||
emailformat.SenderTitle,
|
emailformat.SenderTitle,
|
||||||
emailformat.Extend,
|
emailformat.Extend,
|
||||||
)
|
)
|
||||||
|
|
||||||
// 发送邮件
|
|
||||||
err := smtp.SendMail("smtp.gmail.com:587", m.Auth, m.FromEmail, []string{emailformat.TargetEmail}, content)
|
err := smtp.SendMail("smtp.gmail.com:587", m.Auth, m.FromEmail, []string{emailformat.TargetEmail}, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to send email to %s: %v\n", emailformat, err)
|
log.Printf("Failed to send email to %s: %v\n", emailformat, err)
|
||||||
// 重新发送邮件
|
|
||||||
m.Resend(emailformat.UniqueKey, content)
|
m.Resend(emailformat.UniqueKey, content)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resend 是 EmailSender 结构体的方法,用于重发邮件。
|
// Resend 重发邮件
|
||||||
func (m *EmailSender) Resend(uniqueKey string, content []byte) {
|
func (m *EmailSender) Resend(uniqueKey string, content []byte) {
|
||||||
// 等待一段时间后重发邮件,避免频繁重发
|
|
||||||
time.Sleep(m.ResendTimeLimit)
|
time.Sleep(m.ResendTimeLimit)
|
||||||
|
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
defer m.lock.Unlock()
|
defer m.lock.Unlock()
|
||||||
|
// Check if the email task still exists and has not been sent successfully
|
||||||
// 检查邮件任务是否仍存在并且未成功发送
|
|
||||||
if task, ok := m.emailSending[uniqueKey]; ok && task.SendTime.Add(m.ResendTimeLimit).After(time.Now().UTC()) {
|
if task, ok := m.emailSending[uniqueKey]; ok && task.SendTime.Add(m.ResendTimeLimit).After(time.Now().UTC()) {
|
||||||
err := smtp.SendMail(task.Email.TargetEmail, m.Auth, m.FromEmail, []string{task.Email.TargetEmail}, content)
|
err := smtp.SendMail(task.Email.TargetEmail, m.Auth, m.FromEmail, []string{task.Email.TargetEmail}, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to resend email to %s: %v\n", task.Email.TargetEmail, err)
|
log.Printf("Failed to resend email to %s: %v\n", task.Email.TargetEmail, err)
|
||||||
} else {
|
} else {
|
||||||
// 从 emailSending 字典中删除已成功发送的邮件任务
|
|
||||||
delete(m.emailSending, uniqueKey)
|
delete(m.emailSending, uniqueKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearExpiredTasks 是 EmailSender 结构体的方法,用于清除过期的邮件任务。
|
// ClearExpiredTasks 清除过期的邮件任务
|
||||||
func (m *EmailSender) ClearExpiredTasks() {
|
func (m *EmailSender) ClearExpiredTasks() {
|
||||||
// 每分钟触发一次清除操作
|
|
||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
@ -215,7 +199,6 @@ func (m *EmailSender) ClearExpiredTasks() {
|
|||||||
<-ticker.C
|
<-ticker.C
|
||||||
|
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
// 遍历 emailSending 字典,删除发送时间超过一定限制的过期任务
|
|
||||||
for email, task := range m.emailSending {
|
for email, task := range m.emailSending {
|
||||||
if task.SendTime.Add(m.ResendTimeLimit).Before(time.Now().UTC()) {
|
if task.SendTime.Add(m.ResendTimeLimit).Before(time.Now().UTC()) {
|
||||||
delete(m.emailSending, email)
|
delete(m.emailSending, email)
|
||||||
@ -225,19 +208,8 @@ func (m *EmailSender) ClearExpiredTasks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderEmailTemplate 是一个渲染邮件模板的函数,根据给定的参数生成邮件内容。
|
|
||||||
// 参数:
|
|
||||||
// - templateName: 邮件模板的名称
|
|
||||||
// - companyName: 公司名称
|
|
||||||
// - confirmationLink: 确认链接
|
|
||||||
// - senderName: 发件人姓名
|
|
||||||
// - senderTitle: 发件人职务
|
|
||||||
// - extend: 扩展字段,包含其他自定义键值对的映射
|
|
||||||
// 返回值:
|
|
||||||
// - []byte: 渲染后的邮件内容(以字节切片形式返回)
|
|
||||||
|
|
||||||
func RenderEmailTemplate(templateName, companyName, confirmationLink, senderName, senderTitle string, extend map[string]string) []byte {
|
func RenderEmailTemplate(templateName, companyName, confirmationLink, senderName, senderTitle string, extend map[string]string) []byte {
|
||||||
// 创建一个包含邮件模板所需数据的映射
|
|
||||||
data := map[string]string{
|
data := map[string]string{
|
||||||
"CompanyName": companyName,
|
"CompanyName": companyName,
|
||||||
"ConfirmationLink": confirmationLink,
|
"ConfirmationLink": confirmationLink,
|
||||||
@ -245,20 +217,16 @@ func RenderEmailTemplate(templateName, companyName, confirmationLink, senderName
|
|||||||
"SenderTitle": senderTitle,
|
"SenderTitle": senderTitle,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将扩展字段中的键值对添加到数据映射中
|
|
||||||
for k, v := range extend {
|
for k, v := range extend {
|
||||||
data[k] = v
|
data[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建一个字节缓冲区,用于存储渲染后的邮件内容
|
|
||||||
var result bytes.Buffer
|
var result bytes.Buffer
|
||||||
|
// result.Write([]byte("MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"))
|
||||||
// 使用给定的数据映射执行邮件模板渲染
|
|
||||||
err := tpls.ExecuteTemplate(&result, templateName, data)
|
err := tpls.ExecuteTemplate(&result, templateName, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将渲染后的邮件内容转换为字节切片并返回
|
|
||||||
return result.Bytes()
|
return result.Bytes()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import (
|
|||||||
"fusenapi/server/auth/internal/svc"
|
"fusenapi/server/auth/internal/svc"
|
||||||
"fusenapi/server/auth/internal/types"
|
"fusenapi/server/auth/internal/types"
|
||||||
|
|
||||||
|
"github.com/474420502/requests"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/rest/httpx"
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -48,6 +49,7 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
|
|||||||
event.Data = wevent.DataEmailRegister{
|
event.Data = wevent.DataEmailRegister{
|
||||||
JwtToken: jwtToken,
|
JwtToken: jwtToken,
|
||||||
}
|
}
|
||||||
err = wevent.CommonNotify(svcCtx.Config.WebsocketAddr, token.Wid, event)
|
err = CommonNotify(svcCtx.Config.WebsocketAddr, token.Wid, event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// logx.Error(err, token.TraceId)
|
// logx.Error(err, token.TraceId)
|
||||||
return err
|
return err
|
||||||
@ -64,6 +66,34 @@ func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CommonNotify(WebsocketAddr, wid string, event *wevent.WebsocketEvent) error {
|
||||||
|
|
||||||
|
reqWebsocketAddr := fmt.Sprintf("%s/api/websocket/common_notify", WebsocketAddr)
|
||||||
|
tp := requests.Post(reqWebsocketAddr)
|
||||||
|
tp.SetBodyJson(requests.M{
|
||||||
|
"wid": wid,
|
||||||
|
"data": event,
|
||||||
|
})
|
||||||
|
|
||||||
|
wresp, err := tp.Execute()
|
||||||
|
if err != nil {
|
||||||
|
// logx.Error(err, token.TraceId)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := wresp.Json()
|
||||||
|
|
||||||
|
if !result.Get("code").Exists() {
|
||||||
|
return fmt.Errorf("send %s is error", reqWebsocketAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.Get("code").Int() != 200 {
|
||||||
|
return fmt.Errorf("%s", result.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEmailConfirmation, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEmailConfirmation, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
@ -146,7 +176,7 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
|
|||||||
}
|
}
|
||||||
|
|
||||||
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
||||||
err = wevent.CommonNotify(l.svcCtx.Config.MainAddress, rt.Wid, event)
|
err = CommonNotify(l.svcCtx.Config.MainAddress, rt.Wid, event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err, rt.TraceId)
|
logx.Error(err, rt.TraceId)
|
||||||
return resp.SetStatus(basic.CodeResetPasswordErr, err.Error())
|
return resp.SetStatus(basic.CodeResetPasswordErr, err.Error())
|
||||||
|
|||||||
@ -47,10 +47,6 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
|
|||||||
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(req.Email) > 50 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOAuthEmailErr, "email len must < 50")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !TimeLimit.Is(req.Email) {
|
if !TimeLimit.Is(req.Email) {
|
||||||
return resp.SetStatus(basic.CodeEmailTimeShortErr)
|
return resp.SetStatus(basic.CodeEmailTimeShortErr)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,10 +41,6 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf
|
|||||||
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
return resp.SetStatus(basic.CodeOAuthEmailErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(req.Email) > 50 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOAuthEmailErr, "email len must < 50")
|
|
||||||
}
|
|
||||||
|
|
||||||
// _, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(l.ctx, req.Email)
|
// _, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(l.ctx, req.Email)
|
||||||
// if err == nil {
|
// if err == nil {
|
||||||
// return resp.SetStatus(basic.CodeEmailExistsErr)
|
// return resp.SetStatus(basic.CodeEmailExistsErr)
|
||||||
|
|||||||
@ -50,7 +50,7 @@ func (l *UserResetPasswordHtmlLogic) UserResetPasswordHtml(req *types.RequestUse
|
|||||||
func (l *UserResetPasswordHtmlLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
func (l *UserResetPasswordHtmlLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
||||||
|
|
||||||
err := tpls.ExecuteTemplate(w, "reset_confirm.tpl", map[string]string{
|
err := tpls.ExecuteTemplate(w, "reset_confirm.tpl", map[string]string{
|
||||||
"HomePage": l.svcCtx.Config.HomePage,
|
"HomePage": "http://www.fusen.3718.cn",
|
||||||
"ResetToken": l.ResetToken,
|
"ResetToken": l.ResetToken,
|
||||||
"ResetPasswordLink": l.svcCtx.Config.MainAddress + "/api/auth/reset/password",
|
"ResetPasswordLink": l.svcCtx.Config.MainAddress + "/api/auth/reset/password",
|
||||||
})
|
})
|
||||||
|
|||||||
@ -39,10 +39,6 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
if len(req.NewPassword) > 30 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodePasswordErr, "password len must < 30")
|
|
||||||
}
|
|
||||||
|
|
||||||
rt, err := l.svcCtx.ResetTokenManger.Decrypt(req.ResetToken) // ResetToken
|
rt, err := l.svcCtx.ResetTokenManger.Decrypt(req.ResetToken) // ResetToken
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
@ -55,7 +51,7 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(rt.CreateAt) > 30*time.Minute {
|
if time.Since(rt.CreateAt) > 30*time.Minute {
|
||||||
return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "verification links expire after 30 minute.")
|
return resp.SetStatusWithMessage(basic.CodeOAuthConfirmationTimeoutErr, "Verification links expire after 30 minute.")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error {
|
err = l.svcCtx.AllModels.FsUser.Transaction(l.ctx, func(tx *gorm.DB) error {
|
||||||
@ -71,7 +67,7 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *user.PasswordHash == req.NewPassword {
|
if *user.PasswordHash == req.NewPassword {
|
||||||
return fmt.Errorf("the password is the same as the old one. it needs to be changed")
|
return fmt.Errorf("the password is the same as the old one. It needs to be changed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx.Where("id = ?", rt.UserId).Update("PasswordHash", req.NewPassword).Error
|
return tx.Where("id = ?", rt.UserId).Update("PasswordHash", req.NewPassword).Error
|
||||||
@ -83,7 +79,7 @@ func (l *UserResetPasswordLogic) UserResetPassword(req *types.RequestUserResetPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
event := wevent.NewWebsocketEventSuccess(wevent.UserResetToken, rt.TraceId)
|
||||||
err = wevent.CommonNotify(l.svcCtx.Config.WebsocketAddr, rt.Wid, event)
|
err = CommonNotify(l.svcCtx.Config.WebsocketAddr, rt.Wid, event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err, rt.TraceId)
|
logx.Error(err, rt.TraceId)
|
||||||
return resp.SetStatusWithMessage(basic.CodeResetPasswordErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeResetPasswordErr, err.Error())
|
||||||
|
|||||||
@ -39,7 +39,7 @@ func (l *UserResetTokenLogic) UserResetToken(req *types.RequestUserResetToken, u
|
|||||||
user, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(context.TODO(), req.Email)
|
user, err := l.svcCtx.AllModels.FsUser.FindUserByEmail(context.TODO(), req.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, err.Error())
|
return resp.SetStatus(basic.CodeRequestParamsErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
token := &auth.ResetToken{
|
token := &auth.ResetToken{
|
||||||
|
|||||||
1
server/base/.gitignore
vendored
1
server/base/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
base
|
base
|
||||||
main
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
FROM alpine
|
|
||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
|
||||||
COPY ./bin/api-base-srv /www/fusenapi/
|
|
||||||
COPY ./env.yaml /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-base-srv"]
|
|
||||||
1
server/canteen/.gitignore
vendored
1
server/canteen/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
canteen
|
canteen
|
||||||
main
|
|
||||||
|
|||||||
@ -2,7 +2,5 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-canteen-srv /www/fusenapi/
|
COPY ./bin/api-canteen-srv /www/fusenapi/
|
||||||
COPY ./env.yaml /opt/
|
COPY ./etc /www/fusenapi/etc
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-canteen-srv"]
|
CMD ["/www/fusenapi/api-canteen-srv"]
|
||||||
|
|||||||
2
server/collection/.gitignore
vendored
2
server/collection/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
collection
|
|
||||||
main
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
FROM alpine
|
|
||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
|
||||||
COPY ./bin/api-collection-srv /www/fusenapi/
|
|
||||||
COPY ./env.yaml /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-collection-srv"]
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/fsconfig"
|
|
||||||
|
|
||||||
"fusenapi/server/collection/internal/config"
|
|
||||||
"fusenapi/server/collection/internal/handler"
|
|
||||||
"fusenapi/server/collection/internal/svc"
|
|
||||||
"github.com/zeromicro/go-zero/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
var configFile = flag.String("f", "etc/collection.yaml", "the config file")
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
var c config.Config
|
|
||||||
fsconfig.StartNacosConfig(*configFile, &c, nil)
|
|
||||||
|
|
||||||
c.Timeout = int64(time.Second * 15)
|
|
||||||
server := rest.MustNewServer(c.RestConf, rest.WithCustomCors(auth.FsCors, func(w http.ResponseWriter) {
|
|
||||||
}))
|
|
||||||
defer server.Stop()
|
|
||||||
|
|
||||||
ctx := svc.NewServiceContext(c)
|
|
||||||
handler.RegisterHandlers(server, ctx)
|
|
||||||
|
|
||||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
|
||||||
server.Start()
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
Name: collection
|
|
||||||
Host: 0.0.0.0
|
|
||||||
Port: 9922
|
|
||||||
Timeout: 15000 #服务超时时间(毫秒)
|
|
||||||
SourceMysql: fsreaderwriter:XErSYmLELKMnf3Dh@tcp(fusen.cdmigcvz3rle.us-east-2.rds.amazonaws.com:3306)/fusen
|
|
||||||
SourceRabbitMq: ""
|
|
||||||
Auth:
|
|
||||||
AccessSecret: fusen2023
|
|
||||||
AccessExpire: 2592000
|
|
||||||
RefreshAfter: 1592000
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/server/collection/internal/types"
|
|
||||||
"github.com/zeromicro/go-zero/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
rest.RestConf
|
|
||||||
SourceMysql string
|
|
||||||
Auth types.Auth
|
|
||||||
SourceRabbitMq string
|
|
||||||
BLMService struct {
|
|
||||||
Version string
|
|
||||||
Urls []string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"fusenapi/server/collection/internal/logic"
|
|
||||||
"fusenapi/server/collection/internal/svc"
|
|
||||||
"fusenapi/server/collection/internal/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetCollectProductListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
var req types.GetCollectProductListReq
|
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建一个业务逻辑层实例
|
|
||||||
l := logic.NewGetCollectProductListLogic(r.Context(), svcCtx)
|
|
||||||
|
|
||||||
rl := reflect.ValueOf(l)
|
|
||||||
basic.BeforeLogic(w, r, rl)
|
|
||||||
|
|
||||||
resp := l.GetCollectProductList(&req, userinfo)
|
|
||||||
|
|
||||||
if !basic.AfterLogic(w, r, rl, resp) {
|
|
||||||
basic.NormalAfterLogic(w, r, resp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT.
|
|
||||||
package handler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"fusenapi/server/collection/internal/svc"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|
||||||
server.AddRoutes(
|
|
||||||
[]rest.Route{
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/collection/collect_product",
|
|
||||||
Handler: CollectProductHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/collection/delete_collect_product",
|
|
||||||
Handler: DeleteCollectProductHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/collection/get_collect_product_list",
|
|
||||||
Handler: GetCollectProductListHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/collection/test_ai",
|
|
||||||
Handler: TestAiHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/collection/test_pdf",
|
|
||||||
Handler: TestPdfHandler(serverCtx),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/collection/internal/svc"
|
|
||||||
"fusenapi/server/collection/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CollectProductLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCollectProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CollectProductLogic {
|
|
||||||
return &CollectProductLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *CollectProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *CollectProductLogic) CollectProduct(req *types.CollectProductReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
if !userinfo.IsUser() && !userinfo.IsGuest() {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in before collect product")
|
|
||||||
}
|
|
||||||
//查询产品
|
|
||||||
productInfo, err := l.svcCtx.AllModels.FsProduct.FindOne(l.ctx, req.ProductId)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "the product is not found")
|
|
||||||
}
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "faile to get product info")
|
|
||||||
}
|
|
||||||
//校验下状态
|
|
||||||
/*if *productInfo.Status != 1 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product status is unNormal")
|
|
||||||
}*/
|
|
||||||
//下架了
|
|
||||||
if *productInfo.IsShelf == 0 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product is off shelf")
|
|
||||||
}
|
|
||||||
if *productInfo.IsDel == 1 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "the product is deleted")
|
|
||||||
}
|
|
||||||
//查询收藏
|
|
||||||
_, err = l.svcCtx.AllModels.FsProductCollection.FindOne(l.ctx, userinfo.UserId, userinfo.GuestId, req.ProductId)
|
|
||||||
if err != nil {
|
|
||||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to check repeat of collection")
|
|
||||||
}
|
|
||||||
//创建
|
|
||||||
now := time.Now().UTC()
|
|
||||||
err = l.svcCtx.AllModels.FsProductCollection.Create(l.ctx, &gmodel.FsProductCollection{
|
|
||||||
UserId: &userinfo.UserId,
|
|
||||||
GuestId: &userinfo.GuestId,
|
|
||||||
ProductId: &req.ProductId,
|
|
||||||
TemplateTag: &req.TemplateTag,
|
|
||||||
SelectColorIndex: &req.SelectColorIndex,
|
|
||||||
Logo: &req.Logo,
|
|
||||||
Ctime: &now,
|
|
||||||
Utime: &now,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to collect product")
|
|
||||||
}
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "The product has been collected successfully")
|
|
||||||
}
|
|
||||||
return resp.SetStatusAddMessage(basic.CodeOK, "You have collect this product and don`t need to repeat again")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *CollectProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/collection/internal/svc"
|
|
||||||
"fusenapi/server/collection/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeleteCollectProductLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDeleteCollectProductLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteCollectProductLogic {
|
|
||||||
return &DeleteCollectProductLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *DeleteCollectProductLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *DeleteCollectProductLogic) DeleteCollectProduct(req *types.DeleteCollectProductReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
if !userinfo.IsUser() && !userinfo.IsGuest() {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeUnAuth, "please sign in before to collect product")
|
|
||||||
}
|
|
||||||
for _, id := range req.Ids {
|
|
||||||
err := l.svcCtx.AllModels.FsProductCollection.Delete2(l.ctx, userinfo.UserId, userinfo.GuestId, id)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to remove product collection")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *DeleteCollectProductLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -1,190 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"fusenapi/constants"
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
"fusenapi/utils/format"
|
|
||||||
"fusenapi/utils/s3url_to_s3id"
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/collection/internal/svc"
|
|
||||||
"fusenapi/server/collection/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetCollectProductListLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetCollectProductListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCollectProductListLogic {
|
|
||||||
return &GetCollectProductListLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *GetCollectProductListLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *GetCollectProductListLogic) GetCollectProductList(req *types.GetCollectProductListReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
if req.CurrentPage <= 0 {
|
|
||||||
req.CurrentPage = constants.DEFAULT_PAGE
|
|
||||||
}
|
|
||||||
limit := 10
|
|
||||||
//查询列表
|
|
||||||
collectionList, total, err := l.svcCtx.AllModels.FsProductCollection.GetList(l.ctx, userinfo.UserId, userinfo.GuestId, req.CurrentPage, limit, "id DESC")
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get collection list")
|
|
||||||
}
|
|
||||||
//没有数据
|
|
||||||
if len(collectionList) == 0 {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCollectProductListRsp{
|
|
||||||
Meta: types.Meta{
|
|
||||||
TotalCount: total,
|
|
||||||
PageCount: int64(math.Ceil(float64(total) / float64(limit))),
|
|
||||||
CurrentPage: req.CurrentPage,
|
|
||||||
PerPage: limit,
|
|
||||||
},
|
|
||||||
List: []types.GetCollectProductListRspItem{},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
productIds := make([]int64, 0, len(collectionList))
|
|
||||||
for _, v := range collectionList {
|
|
||||||
productIds = append(productIds, *v.ProductId)
|
|
||||||
}
|
|
||||||
//获取产品所有模型+配件来计算最低价
|
|
||||||
modelList, err := l.svcCtx.AllModels.FsProductModel3d.GetAllByProductIdsTags(l.ctx, productIds, []int{constants.TAG_MODEL, constants.TAG_PARTS}, "id,tag,product_id,part_id,price,step_price")
|
|
||||||
mapModel := make(map[int64]int)
|
|
||||||
for k, v := range modelList {
|
|
||||||
mapModel[v.Id] = k
|
|
||||||
}
|
|
||||||
//计算最低价
|
|
||||||
mapProductMinPrice := make(map[int64]int64)
|
|
||||||
for _, v := range modelList {
|
|
||||||
if *v.Tag != constants.TAG_MODEL {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var stepPrice gmodel.StepPriceJsonStruct
|
|
||||||
if err = json.Unmarshal(*v.StepPrice, &stepPrice); err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeJsonErr, fmt.Sprintf("failed to parse step price:%d", v.Id))
|
|
||||||
}
|
|
||||||
//阶梯最低单价
|
|
||||||
itemPrice := int64(0)
|
|
||||||
if len(stepPrice.PriceRange) > 0 {
|
|
||||||
itemPrice = stepPrice.PriceRange[0].Price
|
|
||||||
}
|
|
||||||
//配件价格
|
|
||||||
if fittingIndex, ok := mapModel[*v.PartId]; ok {
|
|
||||||
itemPrice += *modelList[fittingIndex].Price
|
|
||||||
}
|
|
||||||
//查询比较最低价
|
|
||||||
if minPrice, ok := mapProductMinPrice[*v.ProductId]; ok {
|
|
||||||
if minPrice < itemPrice {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mapProductMinPrice[*v.ProductId] = itemPrice
|
|
||||||
}
|
|
||||||
//获取产品列表
|
|
||||||
productList, err := l.svcCtx.AllModels.FsProduct.GetProductListByIdsWithoutStatus(l.ctx, productIds, "")
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product list")
|
|
||||||
}
|
|
||||||
mapProduct := make(map[int64]int)
|
|
||||||
resourceIds := make([]string, 0, len(productList))
|
|
||||||
for k, v := range productList {
|
|
||||||
mapProduct[v.Id] = k
|
|
||||||
resourceIds = append(resourceIds, s3url_to_s3id.GetS3ResourceIdFormUrl(*v.Cover))
|
|
||||||
}
|
|
||||||
sizeCounts, err := l.svcCtx.AllModels.FsProductSize.GetGroupProductSizeByStatus(l.ctx, productIds, 1)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product size count")
|
|
||||||
}
|
|
||||||
mapProductSizeCount := make(map[int64]int64)
|
|
||||||
for _, v := range sizeCounts {
|
|
||||||
mapProductSizeCount[v.ProductId] = v.Num
|
|
||||||
}
|
|
||||||
//获取资源列表
|
|
||||||
resourceList, err := l.svcCtx.AllModels.FsResource.FindAllByResourceIds(l.ctx, resourceIds)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get resource list")
|
|
||||||
}
|
|
||||||
mapResourceMetadata := make(map[string]interface{})
|
|
||||||
for _, v := range resourceList {
|
|
||||||
var metadata interface{}
|
|
||||||
if err = json.Unmarshal(*v.Metadata, &metadata); err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatusAddMessage(basic.CodeJsonErr, fmt.Sprintf("failed to parse resource metadata:%s", v.ResourceId))
|
|
||||||
}
|
|
||||||
mapResourceMetadata[*v.ResourceUrl] = metadata
|
|
||||||
}
|
|
||||||
listRsp := make([]types.GetCollectProductListRspItem, 0, len(collectionList))
|
|
||||||
for _, collection := range collectionList {
|
|
||||||
productName := ""
|
|
||||||
cover := ""
|
|
||||||
isShelf := int64(0)
|
|
||||||
isDeleted := int64(0)
|
|
||||||
var coverMetadata interface{}
|
|
||||||
if productIndex, ok := mapProduct[*collection.ProductId]; ok {
|
|
||||||
productName = *productList[productIndex].Title
|
|
||||||
cover = *productList[productIndex].Cover
|
|
||||||
isShelf = *productList[productIndex].IsShelf
|
|
||||||
isDeleted = *productList[productIndex].IsDel
|
|
||||||
if metadata, ok := mapResourceMetadata[cover]; ok {
|
|
||||||
coverMetadata = metadata
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sizeCount := int64(0)
|
|
||||||
if count, ok := mapProductSizeCount[*collection.ProductId]; ok {
|
|
||||||
sizeCount = count
|
|
||||||
}
|
|
||||||
minPrice := ""
|
|
||||||
if price, ok := mapProductMinPrice[*collection.ProductId]; ok {
|
|
||||||
minPrice = format.CentitoDollar(price, 3)
|
|
||||||
}
|
|
||||||
listRsp = append(listRsp, types.GetCollectProductListRspItem{
|
|
||||||
Id: collection.Id,
|
|
||||||
ProductId: *collection.ProductId,
|
|
||||||
ProductName: productName,
|
|
||||||
Logo: *collection.Logo,
|
|
||||||
Cover: cover,
|
|
||||||
CoverMetadata: coverMetadata,
|
|
||||||
SelectColorIndex: *collection.SelectColorIndex,
|
|
||||||
TemplateTag: *collection.TemplateTag,
|
|
||||||
SizeCount: sizeCount,
|
|
||||||
MinPrice: minPrice,
|
|
||||||
IsShelf: isShelf,
|
|
||||||
IsDeleted: isDeleted,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetCollectProductListRsp{
|
|
||||||
Meta: types.Meta{
|
|
||||||
TotalCount: total,
|
|
||||||
PageCount: int64(math.Ceil(float64(total) / float64(limit))),
|
|
||||||
CurrentPage: req.CurrentPage,
|
|
||||||
PerPage: limit,
|
|
||||||
},
|
|
||||||
List: listRsp,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *GetCollectProductListLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,50 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fusenapi/server/collection/internal/svc"
|
|
||||||
"fusenapi/server/collection/internal/types"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
"fusenapi/utils/pdf"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestPdfLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTestPdfLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TestPdfLogic {
|
|
||||||
return &TestPdfLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *TestPdfLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *TestPdfLogic) TestPdf(req *types.TestPdfReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeOK, "你干嘛,哎哟")
|
|
||||||
switch req.Type {
|
|
||||||
case "url":
|
|
||||||
case "html":
|
|
||||||
default:
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid type")
|
|
||||||
}
|
|
||||||
res, err := pdf.HtmlToPdfBase64(req.Content, req.Type)
|
|
||||||
if err != nil {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
|
||||||
}
|
|
||||||
return resp.SetStatus(basic.CodeOK, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *TestPdfLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package svc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/initalize"
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/server/collection/internal/config"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ServiceContext struct {
|
|
||||||
Config config.Config
|
|
||||||
MysqlConn *gorm.DB
|
|
||||||
AllModels *gmodel.AllModelsGen
|
|
||||||
RabbitMq *initalize.RabbitMqHandle
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
|
||||||
conn := initalize.InitMysql(c.SourceMysql)
|
|
||||||
|
|
||||||
return &ServiceContext{
|
|
||||||
Config: c,
|
|
||||||
MysqlConn: conn,
|
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
|
||||||
RabbitMq: initalize.InitRabbitMq(c.SourceRabbitMq, nil),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT.
|
|
||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CollectProductReq struct {
|
|
||||||
ProductId int64 `json:"product_id"`
|
|
||||||
Logo string `json:"logo"`
|
|
||||||
SelectColorIndex int64 `json:"select_color_index"`
|
|
||||||
TemplateTag string `json:"template_tag"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCollectProductReq struct {
|
|
||||||
Ids []int64 `json:"ids"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetCollectProductListReq struct {
|
|
||||||
CurrentPage int `form:"current_page"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetCollectProductListRsp struct {
|
|
||||||
Meta Meta `json:"meta"` //分页信息
|
|
||||||
List []GetCollectProductListRspItem `json:"list"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetCollectProductListRspItem struct {
|
|
||||||
Id int64 `json:"id"`
|
|
||||||
ProductId int64 `json:"product_id"`
|
|
||||||
ProductName string `json:"product_name"`
|
|
||||||
Logo string `json:"logo"`
|
|
||||||
Cover string `json:"cover"`
|
|
||||||
CoverMetadata interface{} `json:"coverMetadata"`
|
|
||||||
SelectColorIndex int64 `json:"select_color_index"`
|
|
||||||
TemplateTag string `json:"template_tag"`
|
|
||||||
SizeCount int64 `json:"size_count"`
|
|
||||||
MinPrice string `json:"min_price"`
|
|
||||||
IsShelf int64 `json:"is_shelf"`
|
|
||||||
IsDeleted int64 `json:"is_deleted"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestAiReq struct {
|
|
||||||
Num int `form:"num"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestPdfReq struct {
|
|
||||||
Content string `json:"content"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Request struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type Response struct {
|
|
||||||
Code int `json:"code"`
|
|
||||||
Message string `json:"msg"`
|
|
||||||
Data interface{} `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Auth struct {
|
|
||||||
AccessSecret string `json:"accessSecret"`
|
|
||||||
AccessExpire int64 `json:"accessExpire"`
|
|
||||||
RefreshAfter int64 `json:"refreshAfter"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
Filename string `fsfile:"filename"`
|
|
||||||
Header map[string][]string `fsfile:"header"`
|
|
||||||
Size int64 `fsfile:"size"`
|
|
||||||
Data []byte `fsfile:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Meta struct {
|
|
||||||
TotalCount int64 `json:"total_count"`
|
|
||||||
PageCount int64 `json:"page_count"`
|
|
||||||
CurrentPage int `json:"current_page"`
|
|
||||||
PerPage int `json:"per_page"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 设置Response的Code和Message值
|
|
||||||
func (resp *Response) Set(Code int, Message string) *Response {
|
|
||||||
return &Response{
|
|
||||||
Code: Code,
|
|
||||||
Message: Message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set 设置整个Response
|
|
||||||
func (resp *Response) SetWithData(Code int, Message string, Data interface{}) *Response {
|
|
||||||
return &Response{
|
|
||||||
Code: Code,
|
|
||||||
Message: Message,
|
|
||||||
Data: Data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStatus 设置默认StatusResponse(内部自定义) 默认msg, 可以带data, data只使用一个参数
|
|
||||||
func (resp *Response) SetStatus(sr *basic.StatusResponse, data ...interface{}) *Response {
|
|
||||||
newResp := &Response{
|
|
||||||
Code: sr.Code,
|
|
||||||
}
|
|
||||||
if len(data) == 1 {
|
|
||||||
newResp.Data = data[0]
|
|
||||||
}
|
|
||||||
return newResp
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStatusWithMessage 设置默认StatusResponse(内部自定义) 非默认msg, 可以带data, data只使用一个参数
|
|
||||||
func (resp *Response) SetStatusWithMessage(sr *basic.StatusResponse, msg string, data ...interface{}) *Response {
|
|
||||||
newResp := &Response{
|
|
||||||
Code: sr.Code,
|
|
||||||
Message: msg,
|
|
||||||
}
|
|
||||||
if len(data) == 1 {
|
|
||||||
newResp.Data = data[0]
|
|
||||||
}
|
|
||||||
return newResp
|
|
||||||
}
|
|
||||||
1
server/data-transfer/.gitignore
vendored
1
server/data-transfer/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
data-transfer
|
data-transfer
|
||||||
main
|
|
||||||
|
|||||||
@ -2,7 +2,5 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-data-transfer-srv /www/fusenapi/
|
COPY ./bin/api-data-transfer-srv /www/fusenapi/
|
||||||
COPY ./env.yaml /opt/
|
COPY ./etc /www/fusenapi/etc
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-data-transfer-srv"]
|
CMD ["/www/fusenapi/api-data-transfer-srv"]
|
||||||
|
|||||||
1
server/home-user-auth/.gitignore
vendored
1
server/home-user-auth/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
home-user-auth
|
home-user-auth
|
||||||
main
|
|
||||||
|
|||||||
@ -2,7 +2,5 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-home-user-auth-srv /www/fusenapi/
|
COPY ./bin/api-home-user-auth-srv /www/fusenapi/
|
||||||
COPY ./env.yaml /opt/
|
COPY ./etc /www/fusenapi/etc
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-home-user-auth-srv"]
|
CMD ["/www/fusenapi/api-home-user-auth-srv"]
|
||||||
|
|||||||
@ -36,7 +36,9 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
BLMService struct {
|
BLMService struct {
|
||||||
Version string
|
Url string
|
||||||
Urls []string
|
LogoCombine struct {
|
||||||
|
Url string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,11 +17,36 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/user/fonts",
|
Path: "/api/user/fonts",
|
||||||
Handler: UserFontsHandler(serverCtx),
|
Handler: UserFontsHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/user/get-type",
|
||||||
|
Handler: UserGetTypeHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/user/basic-info",
|
||||||
|
Handler: UserSaveBasicInfoHandler(serverCtx),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/api/user/status-config",
|
Path: "/api/user/status-config",
|
||||||
Handler: UserStatusConfigHandler(serverCtx),
|
Handler: UserStatusConfigHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/user/basic-info",
|
||||||
|
Handler: UserBasicInfoHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/user/address-list",
|
||||||
|
Handler: UserAddressListHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/api/user/add-address",
|
||||||
|
Handler: UserAddAddressHandler(serverCtx),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/user/contact-service",
|
Path: "/api/user/contact-service",
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/home-user-auth/internal/logic"
|
||||||
|
"fusenapi/server/home-user-auth/internal/svc"
|
||||||
|
"fusenapi/server/home-user-auth/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UserAddAddressHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.RequestAddAddress
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewUserAddAddressLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.UserAddAddress(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"fusenapi/server/home-user-auth/internal/logic"
|
||||||
|
"fusenapi/server/home-user-auth/internal/svc"
|
||||||
|
"fusenapi/server/home-user-auth/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UserAddressListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var req types.Request
|
||||||
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个业务逻辑层实例
|
||||||
|
l := logic.NewUserAddressListLogic(r.Context(), svcCtx)
|
||||||
|
|
||||||
|
rl := reflect.ValueOf(l)
|
||||||
|
basic.BeforeLogic(w, r, rl)
|
||||||
|
|
||||||
|
resp := l.UserAddressList(&req, userinfo)
|
||||||
|
|
||||||
|
if !basic.AfterLogic(w, r, rl, resp) {
|
||||||
|
basic.NormalAfterLogic(w, r, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
98
server/home-user-auth/internal/logic/useraddaddresslogic.go
Normal file
98
server/home-user-auth/internal/logic/useraddaddresslogic.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fusenapi/model/gmodel"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/home-user-auth/internal/svc"
|
||||||
|
"fusenapi/server/home-user-auth/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserAddAddressLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserAddAddressLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserAddAddressLogic {
|
||||||
|
return &UserAddAddressLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *UserAddAddressLogic) UserAddAddress(req *types.RequestAddAddress, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
// userinfo 传入值时, 一定不为null
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth) // 如果不是用户信息, 返回未授权错误
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认这个IsDefault的值范围
|
||||||
|
if !auth.CheckValueRange(req.IsDefault, 0, 1) {
|
||||||
|
return resp.SetStatus(basic.CodeSafeValueRangeErr) // IsDefault值超出范围, 返回安全值范围错误
|
||||||
|
}
|
||||||
|
|
||||||
|
m := l.svcCtx.AllModels.FsAddress // 创建地址模型
|
||||||
|
var status int64 = 1 // 默认地址状态为1(正常)
|
||||||
|
|
||||||
|
// 如果ID为0, 表示新增地址
|
||||||
|
if req.Id == 0 {
|
||||||
|
var (
|
||||||
|
country string = "USA" // 国家默认为美国
|
||||||
|
isDefautl int64 = 1 // 默认地址为1
|
||||||
|
)
|
||||||
|
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
||||||
|
AddressName: &req.Name,
|
||||||
|
FirstName: &req.FirstName,
|
||||||
|
LastName: &req.LastName,
|
||||||
|
Mobile: &req.Mobile,
|
||||||
|
Street: &req.Street,
|
||||||
|
Suite: &req.Suite,
|
||||||
|
City: &req.City,
|
||||||
|
State: &req.State,
|
||||||
|
Country: &country,
|
||||||
|
Status: &status,
|
||||||
|
UserId: &userinfo.UserId,
|
||||||
|
ZipCode: &req.ZipCode,
|
||||||
|
IsDefault: &isDefautl,
|
||||||
|
}
|
||||||
|
created, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err) // 日志记录错误
|
||||||
|
return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误
|
||||||
|
}
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": created.AddressId}) // 返回成功并返回地址ID
|
||||||
|
}
|
||||||
|
|
||||||
|
address := &gmodel.FsAddress{
|
||||||
|
AddressId: req.Id,
|
||||||
|
AddressName: &req.Name,
|
||||||
|
FirstName: &req.FirstName,
|
||||||
|
LastName: &req.LastName,
|
||||||
|
Mobile: &req.Mobile,
|
||||||
|
Street: &req.Street,
|
||||||
|
Suite: &req.Suite,
|
||||||
|
City: &req.City,
|
||||||
|
State: &req.State,
|
||||||
|
Status: &status,
|
||||||
|
UserId: &userinfo.UserId,
|
||||||
|
ZipCode: &req.ZipCode,
|
||||||
|
IsDefault: &req.IsDefault,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入数据库 更新地址
|
||||||
|
err := m.UpdateAddress(l.ctx, address)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatus(basic.CodeDbUpdateErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.SetStatus(basic.CodeOK, map[string]int64{"id": address.AddressId})
|
||||||
|
}
|
||||||
42
server/home-user-auth/internal/logic/useraddresslistlogic.go
Normal file
42
server/home-user-auth/internal/logic/useraddresslistlogic.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"fusenapi/server/home-user-auth/internal/svc"
|
||||||
|
"fusenapi/server/home-user-auth/internal/types"
|
||||||
|
"fusenapi/utils/auth"
|
||||||
|
"fusenapi/utils/basic"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserAddressListLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserAddressListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserAddressListLogic {
|
||||||
|
return &UserAddressListLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *UserAddressListLogic) UserAddressList(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
|
if !userinfo.IsUser() {
|
||||||
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := l.svcCtx.AllModels.FsAddress
|
||||||
|
|
||||||
|
data, err := m.GetUserAllAddress(l.ctx, userinfo.UserId)
|
||||||
|
if err != nil {
|
||||||
|
logx.Error(err)
|
||||||
|
return resp.SetStatusWithMessage(basic.CodeServiceErr, err.Error())
|
||||||
|
}
|
||||||
|
return resp.SetStatus(basic.CodeOK, data)
|
||||||
|
}
|
||||||
@ -62,7 +62,6 @@ func (l *UserLogoSetLogic) UserLogoSet(req *types.UserLogoSetReq, userinfo *auth
|
|||||||
ResourceId: defaultMaterialInfo.ResourceId,
|
ResourceId: defaultMaterialInfo.ResourceId,
|
||||||
ResourceUrl: defaultMaterialInfo.ResourceUrl,
|
ResourceUrl: defaultMaterialInfo.ResourceUrl,
|
||||||
Ctime: &nowTime,
|
Ctime: &nowTime,
|
||||||
Metadata: defaultMaterialInfo.Metadata,
|
|
||||||
}
|
}
|
||||||
MaterialCreateRes := l.svcCtx.MysqlConn.Create(&defaultMaterial)
|
MaterialCreateRes := l.svcCtx.MysqlConn.Create(&defaultMaterial)
|
||||||
err = MaterialCreateRes.Error
|
err = MaterialCreateRes.Error
|
||||||
|
|||||||
@ -38,9 +38,9 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||||||
SharedState: nil,
|
SharedState: nil,
|
||||||
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
|
||||||
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
||||||
GormDB: initalize.InitMysql(c.SourceMysql),
|
GormDB: initalize.InitMysql(c.SourceMysql),
|
||||||
BLMServiceUrls: c.BLMService.Urls,
|
BLMServiceUrl: &c.BLMService.Url,
|
||||||
AwsSession: session.Must(session.NewSession(&config)),
|
AwsSession: session.Must(session.NewSession(&config)),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
server/info/.gitignore
vendored
1
server/info/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
info
|
info
|
||||||
main
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
FROM alpine
|
|
||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
|
||||||
COPY ./bin/api-info-srv /www/fusenapi/
|
|
||||||
COPY ./env.yaml /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-info-srv"]
|
|
||||||
@ -14,7 +14,7 @@ import (
|
|||||||
func AddressDefaultHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func AddressDefaultHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.AddressDefaultRequest
|
var req types.AddressIdRequest
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -42,11 +42,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/info/address/update",
|
Path: "/api/info/address/update",
|
||||||
Handler: AddressUpdateHandler(serverCtx),
|
Handler: AddressUpdateHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/info/address/update/used",
|
|
||||||
Handler: AddressUsedUpdateHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
Path: "/api/info/address/delete",
|
Path: "/api/info/address/delete",
|
||||||
@ -57,16 +52,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/info/address/list",
|
Path: "/api/info/address/list",
|
||||||
Handler: AddressListHandler(serverCtx),
|
Handler: AddressListHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodGet,
|
|
||||||
Path: "/api/info/restaurant/list",
|
|
||||||
Handler: RestaurantListHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/info/contact/us",
|
|
||||||
Handler: ContactUsHandler(serverCtx),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import (
|
|||||||
func UpdateProfileBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
func UpdateProfileBaseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var req types.ProfileRequest
|
var req types.ProfileBaseRequest
|
||||||
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
userinfo, err := basic.RequestParse(w, r, svcCtx, &req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -49,33 +49,32 @@ func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, userinfo *auth.U
|
|||||||
// 如果ID为0, 表示新增地址
|
// 如果ID为0, 表示新增地址
|
||||||
|
|
||||||
var (
|
var (
|
||||||
country string = "USA" // 国家默认为美国
|
country string = "USA" // 国家默认为美国
|
||||||
status int64 = 1 // 默认地址状态为1(正常)
|
isDefautl int64 = 1 // 默认地址为1
|
||||||
|
status int64 = 1 // 默认地址状态为1(正常)
|
||||||
)
|
)
|
||||||
|
|
||||||
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
createOne := &gmodel.FsAddress{ // 构建FsAddress结构体
|
||||||
FirstName: &req.FirstName,
|
AddressName: &req.AddressName,
|
||||||
LastName: &req.LastName,
|
FirstName: &req.FirstName,
|
||||||
Mobile: &req.Mobile,
|
LastName: &req.LastName,
|
||||||
Street: &req.Street,
|
Mobile: &req.Mobile,
|
||||||
Suite: &req.Suite,
|
Street: &req.Street,
|
||||||
City: &req.City,
|
Suite: &req.Suite,
|
||||||
State: &req.State,
|
City: &req.City,
|
||||||
Country: &country,
|
State: &req.State,
|
||||||
Status: &status,
|
Country: &country,
|
||||||
UserId: &userinfo.UserId,
|
Status: &status,
|
||||||
ZipCode: &req.ZipCode,
|
UserId: &userinfo.UserId,
|
||||||
|
ZipCode: &req.ZipCode,
|
||||||
|
IsDefault: &isDefautl,
|
||||||
}
|
}
|
||||||
address, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
_, err := m.CreateOne(l.ctx, createOne) // 新增地址
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err) // 日志记录错误
|
logx.Error(err) // 日志记录错误
|
||||||
return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误
|
return resp.SetStatus(basic.CodeDbCreateErr) // 返回数据库创建错误
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.IsDefault > 0 {
|
|
||||||
m.SettingUserDefaultAddress(l.ctx, userinfo.UserId, address.AddressId, req.IsDefault)
|
|
||||||
}
|
|
||||||
|
|
||||||
addresses, err := m.GetUserAllAddress(l.ctx, userinfo.UserId)
|
addresses, err := m.GetUserAllAddress(l.ctx, userinfo.UserId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
@ -83,7 +82,6 @@ func (l *AddressAddLogic) AddressAdd(req *types.AddressRequest, userinfo *auth.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]any{
|
return resp.SetStatus(basic.CodeOK, map[string]any{
|
||||||
"address_id": address.AddressId,
|
|
||||||
"address_list": addresses,
|
"address_list": addresses,
|
||||||
}) // 返回成功并返回地址ID
|
}) // 返回成功并返回地址ID
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ func NewAddressDefaultLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ad
|
|||||||
// func (l *AddressDefaultLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
// func (l *AddressDefaultLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (l *AddressDefaultLogic) AddressDefault(req *types.AddressDefaultRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *AddressDefaultLogic) AddressDefault(req *types.AddressIdRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
|
|
||||||
@ -38,26 +38,12 @@ func (l *AddressDefaultLogic) AddressDefault(req *types.AddressDefaultRequest, u
|
|||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确认这个IsDefault的值范围
|
err := l.svcCtx.AllModels.FsAddress.SettingUserDefaultAddress(l.ctx, userinfo.UserId, req.AddressId)
|
||||||
if !auth.CheckValueRange(req.IsDefault, 0, 1) {
|
|
||||||
return resp.SetStatus(basic.CodeSafeValueRangeErr) // IsDefault值超出范围, 返回安全值范围错误
|
|
||||||
}
|
|
||||||
|
|
||||||
err := l.svcCtx.AllModels.FsAddress.SettingUserDefaultAddress(l.ctx, userinfo.UserId, req.AddressId, req.IsDefault)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
addresses, err := l.svcCtx.AllModels.FsAddress.GetUserAllAddress(l.ctx, userinfo.UserId)
|
return resp.SetStatus(basic.CodeOK)
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatus(basic.CodeDbSqlErr) // 返回数据库创建错误
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]any{
|
|
||||||
"address_id": req.AddressId,
|
|
||||||
"address_list": addresses,
|
|
||||||
}) // 返回成功并返回地址ID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|||||||
@ -43,9 +43,7 @@ func (l *AddressDeleteLogic) AddressDelete(req *types.AddressIdRequest, userinfo
|
|||||||
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]any{
|
return resp.SetStatus(basic.CodeOK)
|
||||||
"address_id": req.AddressId,
|
|
||||||
}) // 返回成功并返回地址ID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|||||||
@ -40,11 +40,6 @@ func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *
|
|||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确认这个IsDefault的值范围
|
|
||||||
if !auth.CheckValueRange(req.IsDefault, 0, 1) {
|
|
||||||
return resp.SetStatus(basic.CodeSafeValueRangeErr) // IsDefault值超出范围, 返回安全值范围错误
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
|
|
||||||
if req.AddressId == 0 {
|
if req.AddressId == 0 {
|
||||||
@ -52,17 +47,19 @@ func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *
|
|||||||
}
|
}
|
||||||
|
|
||||||
address := gmodel.FsAddress{
|
address := gmodel.FsAddress{
|
||||||
AddressId: req.AddressId,
|
AddressId: req.AddressId,
|
||||||
UserId: &userinfo.UserId,
|
UserId: &userinfo.UserId,
|
||||||
FirstName: &req.FirstName,
|
IsDefault: &req.IsDefault,
|
||||||
LastName: &req.LastName,
|
AddressName: &req.AddressName,
|
||||||
Mobile: &req.Mobile,
|
FirstName: &req.FirstName,
|
||||||
ZipCode: &req.ZipCode,
|
LastName: &req.LastName,
|
||||||
Street: &req.Street,
|
Mobile: &req.Mobile,
|
||||||
Suite: &req.Suite,
|
ZipCode: &req.ZipCode,
|
||||||
City: &req.City,
|
Street: &req.Street,
|
||||||
State: &req.State,
|
Suite: &req.Suite,
|
||||||
Utime: &now,
|
City: &req.City,
|
||||||
|
State: &req.State,
|
||||||
|
Utime: &now,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := l.svcCtx.AllModels.FsAddress.UpdateAddress(l.ctx, &address)
|
err := l.svcCtx.AllModels.FsAddress.UpdateAddress(l.ctx, &address)
|
||||||
@ -70,19 +67,7 @@ func (l *AddressUpdateLogic) AddressUpdate(req *types.AddressRequest, userinfo *
|
|||||||
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
l.svcCtx.AllModels.FsAddress.SettingUserDefaultAddress(l.ctx, userinfo.UserId, address.AddressId, req.IsDefault)
|
return resp.SetStatus(basic.CodeOK)
|
||||||
|
|
||||||
addresses, err := l.svcCtx.AllModels.FsAddress.GetUserAllAddress(l.ctx, userinfo.UserId)
|
|
||||||
if err != nil {
|
|
||||||
logx.Error(err)
|
|
||||||
return resp.SetStatus(basic.CodeDbSqlErr) // 返回数据库创建错误
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]any{
|
|
||||||
"address_id": req.AddressId,
|
|
||||||
"address_list": addresses,
|
|
||||||
}) // 返回成功并返回地址ID
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/info/internal/svc"
|
|
||||||
"fusenapi/server/info/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AddressUsedUpdateLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAddressUsedUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddressUsedUpdateLogic {
|
|
||||||
return &AddressUsedUpdateLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *AddressUsedUpdateLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *AddressUsedUpdateLogic) AddressUsedUpdate(req *types.AddressIdRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
// userinfo 传入值时, 一定不为null
|
|
||||||
if !userinfo.IsUser() {
|
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
|
||||||
}
|
|
||||||
|
|
||||||
err := l.svcCtx.AllModels.FsAddress.UpdateUsedAddress(l.ctx, req.AddressId, userinfo.UserId)
|
|
||||||
if err != nil {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeApiErr, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]any{
|
|
||||||
"address_id": req.AddressId,
|
|
||||||
}) // 返回成功并返回地址ID
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *AddressUsedUpdateLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/model/gmodel"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/info/internal/svc"
|
|
||||||
"fusenapi/server/info/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ContactUsLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewContactUsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ContactUsLogic {
|
|
||||||
return &ContactUsLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *ContactUsLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *ContactUsLogic) ContactUs(req *types.ContactUsRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
// userinfo 传入值时, 一定不为null
|
|
||||||
|
|
||||||
if !auth.ValidateEmail(req.Email) {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "email format error")
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Message == "" {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "remarks must exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now().UTC()
|
|
||||||
err := l.svcCtx.AllModels.FsContact.Save(l.ctx, &gmodel.FsContact{
|
|
||||||
Name: &req.Name,
|
|
||||||
Email: &req.Email,
|
|
||||||
Phone: &req.Phone,
|
|
||||||
Message: &req.Message,
|
|
||||||
Status: gmodel.FsInt64(0),
|
|
||||||
Ctime: &now,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *ContactUsLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/info/internal/svc"
|
|
||||||
"fusenapi/server/info/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RestaurantListLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRestaurantListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RestaurantListLogic {
|
|
||||||
return &RestaurantListLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *RestaurantListLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *RestaurantListLogic) RestaurantList(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
// userinfo 传入值时, 一定不为null
|
|
||||||
|
|
||||||
values := []string{
|
|
||||||
"Pizza Shop",
|
|
||||||
"Coffee Shop",
|
|
||||||
"Salad Shop",
|
|
||||||
"Other Non-Asian Restaurants",
|
|
||||||
"Fried Chicken / Burger / Sandwich Restaurant",
|
|
||||||
"Other Restaurants",
|
|
||||||
"Bakery / Dessert Shop",
|
|
||||||
"Ramen /Vietnamese / Thai / Korean / Chinese",
|
|
||||||
"Breakfast & Brunch",
|
|
||||||
"Moxican",
|
|
||||||
"Pho",
|
|
||||||
"Ramen",
|
|
||||||
"Chinese",
|
|
||||||
"Burgers",
|
|
||||||
"Sushi Restaurant",
|
|
||||||
"Indian",
|
|
||||||
"Vegan",
|
|
||||||
"Smoothie",
|
|
||||||
"Healthy",
|
|
||||||
"Soup",
|
|
||||||
"Italian",
|
|
||||||
"Boba Tea Shop",
|
|
||||||
"Other",
|
|
||||||
"Korean / Thai",
|
|
||||||
"Bar",
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, values)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *RestaurantListLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -30,15 +30,13 @@ func NewUpdateProfileBaseLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
|||||||
// func (l *UpdateProfileBaseLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
// func (l *UpdateProfileBaseLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (l *UpdateProfileBaseLogic) UpdateProfileBase(req *types.ProfileRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
func (l *UpdateProfileBaseLogic) UpdateProfileBase(req *types.ProfileBaseRequest, userinfo *auth.UserInfo) (resp *basic.Response) {
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
||||||
// userinfo 传入值时, 一定不为null
|
// userinfo 传入值时, 一定不为null
|
||||||
if !userinfo.IsUser() {
|
if !userinfo.IsUser() {
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.ProfileBase.Email = nil
|
|
||||||
|
|
||||||
err := l.svcCtx.AllModels.FsUserInfo.MergeMetadata(userinfo.UserId, req)
|
err := l.svcCtx.AllModels.FsUserInfo.MergeMetadata(userinfo.UserId, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err) // 日志记录错误
|
logx.Error(err) // 日志记录错误
|
||||||
|
|||||||
@ -5,13 +5,6 @@ import (
|
|||||||
"fusenapi/utils/basic"
|
"fusenapi/utils/basic"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContactUsRequest struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserInfoRequest struct {
|
type UserInfoRequest struct {
|
||||||
Module []string `json:"module"`
|
Module []string `json:"module"`
|
||||||
}
|
}
|
||||||
@ -25,53 +18,33 @@ type AddressIdRequest struct {
|
|||||||
AddressId int64 `json:"address_id"` // 地址id
|
AddressId int64 `json:"address_id"` // 地址id
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressDefaultRequest struct {
|
type AddressNameRequest struct {
|
||||||
AddressId int64 `json:"address_id"` // 地址id
|
AddressName string `json:"address_name"` // 地址
|
||||||
IsDefault int64 `json:"is_default"` // 是否默认
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddressRequest struct {
|
type AddressRequest struct {
|
||||||
AddressId int64 `json:"address_id,optional"`
|
AddressId int64 `json:"address_id,optional"`
|
||||||
IsDefault int64 `json:"is_default"` //是否默认
|
IsDefault int64 `json:"is_default"` //是否默认
|
||||||
FirstName string `json:"first_name"` //first_name
|
AddressName string `json:"address_name"` //收货人
|
||||||
LastName string `json:"last_name"` //last_name
|
FirstName string `json:"first_name"` //first_name
|
||||||
Mobile string `json:"mobile"` //手机
|
LastName string `json:"last_name"` //last_name
|
||||||
ZipCode string `json:"zip_code"` //邮编
|
Mobile string `json:"mobile"` //手机
|
||||||
Street string `json:"street"` //街道
|
ZipCode string `json:"zip_code"` //邮编
|
||||||
Suite string `json:"suite"` //房号
|
Street string `json:"street"` //街道
|
||||||
City string `json:"city"` //城市
|
Suite string `json:"suite"` //房号
|
||||||
State string `json:"state"` //州
|
City string `json:"city"` //城市
|
||||||
|
State string `json:"state"` //州
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProfileRequest struct {
|
type ProfileBaseRequest struct {
|
||||||
ProfileBase *ProfileBase `json:"base,optional,omitempty"` // 基础的个人消息, 姓名 公司等
|
|
||||||
SubscriptionStatus *SubscriptionStatus `json:"sub_status,optional,omitempty"` // 订阅的通知状态
|
|
||||||
}
|
|
||||||
|
|
||||||
type ProfileBase struct {
|
|
||||||
FirstName *string `json:"first_name,optional,omitempty"` // 首名
|
FirstName *string `json:"first_name,optional,omitempty"` // 首名
|
||||||
LastName *string `json:"last_name,optional,omitempty"` // 后名
|
LastName *string `json:"last_name,optional,omitempty"` // 后名
|
||||||
Email *string `json:"email,optional,omitempty"` // email
|
UserName *string `json:"user_name,optional,omitempty"` // 用户名
|
||||||
Mobile *string `json:"mobile,optional,omitempty"` // 电话
|
Mobile *string `json:"mobile,optional,omitempty"` // 电话
|
||||||
Resetaurant *string `json:"resetaurant,optional,omitempty"` // 不知道干什么
|
Resetaurant *string `json:"resetaurant,optional,omitempty"` // 不知道干什么
|
||||||
Company *string `json:"company,optional,omitempty"` // 公司
|
Company *string `json:"company,optional,omitempty"` // 公司
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubscriptionStatus struct {
|
|
||||||
NotificationEmail NotificationEmail `json:"notification_email,optional,omitempty"`
|
|
||||||
NotificationPhone NotificationPhone `json:"notification_phone,optional,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type NotificationEmail struct {
|
|
||||||
OrderUpdate bool `json:"order_update,optional,omitempty"`
|
|
||||||
Newseleter bool `json:"newseleter,optional,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type NotificationPhone struct {
|
|
||||||
OrderUpdate bool `json:"order_update,optional,omitempty"`
|
|
||||||
Newseleter bool `json:"newseleter,optional,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type QueryProfileRequest struct {
|
type QueryProfileRequest struct {
|
||||||
TopKey string `json:"top_key"` // 首名
|
TopKey string `json:"top_key"` // 首名
|
||||||
}
|
}
|
||||||
|
|||||||
1
server/map-library/.gitignore
vendored
1
server/map-library/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
map-library
|
map-library
|
||||||
main
|
|
||||||
|
|||||||
@ -2,7 +2,5 @@ FROM alpine
|
|||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
WORKDIR /www/fusenapi/
|
||||||
COPY ./bin/api-map-library-srv /www/fusenapi/
|
COPY ./bin/api-map-library-srv /www/fusenapi/
|
||||||
COPY ./env.yaml /opt/
|
COPY ./etc /www/fusenapi/etc
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-map-library-srv"]
|
CMD ["/www/fusenapi/api-map-library-srv"]
|
||||||
|
|||||||
1
server/order/.gitignore
vendored
1
server/order/.gitignore
vendored
@ -1,2 +1 @@
|
|||||||
order
|
order
|
||||||
main
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
FROM alpine
|
|
||||||
|
|
||||||
WORKDIR /www/fusenapi/
|
|
||||||
COPY ./bin/api-order-srv /www/fusenapi/
|
|
||||||
COPY ./env.yaml /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.pem /opt/
|
|
||||||
COPY ./server.fusen.3718.cn.key /opt/
|
|
||||||
CMD ["/www/fusenapi/api-order-srv"]
|
|
||||||
@ -27,16 +27,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/api/order/create-prepayment-balance",
|
Path: "/api/order/create-prepayment-balance",
|
||||||
Handler: CreatePrePaymentByBalanceHandler(serverCtx),
|
Handler: CreatePrePaymentByBalanceHandler(serverCtx),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/order/delete",
|
|
||||||
Handler: DeleteOrderHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Method: http.MethodPost,
|
|
||||||
Path: "/api/order/close",
|
|
||||||
Handler: CloseOrderHandler(serverCtx),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
Path: "/api/order/list",
|
Path: "/api/order/list",
|
||||||
|
|||||||
@ -1,56 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/service/repositories"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/order/internal/svc"
|
|
||||||
"fusenapi/server/order/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CloseOrderLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCloseOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CloseOrderLogic {
|
|
||||||
return &CloseOrderLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *CloseOrderLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *CloseOrderLogic) CloseOrder(req *types.CloseOrderReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
// userinfo 传入值时, 一定不为null
|
|
||||||
if !userinfo.IsUser() {
|
|
||||||
// 如果是,返回未授权的错误码
|
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
|
||||||
}
|
|
||||||
res, err := l.svcCtx.Repositories.NewOrder.Close(l.ctx, &repositories.CloseReq{
|
|
||||||
UserId: userinfo.UserId,
|
|
||||||
OrderSn: req.OrderSn,
|
|
||||||
Type: 1,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return resp.SetStatus(&res.ErrorCode)
|
|
||||||
}
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *CloseOrderLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package logic
|
package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"fusenapi/constants"
|
"fusenapi/constants"
|
||||||
"fusenapi/service/repositories"
|
"fusenapi/service/repositories"
|
||||||
"fusenapi/utils/auth"
|
"fusenapi/utils/auth"
|
||||||
@ -41,7 +40,7 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth
|
|||||||
// 如果是,返回未授权的错误码
|
// 如果是,返回未授权的错误码
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
return resp.SetStatus(basic.CodeUnAuth)
|
||||||
}
|
}
|
||||||
tPlus60Days := time.Now().AddDate(0, 0, 60).UTC()
|
tPlus60Days := time.Now().AddDate(0, 0, 60)
|
||||||
res, err := l.svcCtx.Repositories.NewOrder.Create(l.ctx, &repositories.CreateReq{
|
res, err := l.svcCtx.Repositories.NewOrder.Create(l.ctx, &repositories.CreateReq{
|
||||||
ExpectedDeliveryTime: tPlus60Days,
|
ExpectedDeliveryTime: tPlus60Days,
|
||||||
CurrentCurrency: string(constants.CURRENCYUSD),
|
CurrentCurrency: string(constants.CURRENCYUSD),
|
||||||
@ -55,36 +54,6 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth
|
|||||||
return resp.SetStatus(&res.ErrorCode)
|
return resp.SetStatus(&res.ErrorCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 延时任务
|
|
||||||
// l.svcCtx.DelayQueue.AddTask(time.Now().Add(time.Minute*30), constants.QUEUE_NAME_ORDER, func(args ...interface{}) {
|
|
||||||
// ctx := context.Background()
|
|
||||||
// orderSn := args[0].(string)
|
|
||||||
// svcCtx := svc.ServiceContext{
|
|
||||||
// Config: l.svcCtx.Config,
|
|
||||||
// Repositories: l.svcCtx.Repositories,
|
|
||||||
// }
|
|
||||||
// svcCtx.Repositories.NewOrder.Close(ctx, &repositories.CloseReq{
|
|
||||||
// OrderSn: orderSn,
|
|
||||||
// Type: 1,
|
|
||||||
// })
|
|
||||||
// }, []interface{}{res.OrderSn})
|
|
||||||
|
|
||||||
// 延时任务
|
|
||||||
time.AfterFunc(time.Minute*30, func() {
|
|
||||||
orderSn := res.OrderSn
|
|
||||||
fmt.Println("延时任务: OrderSn--", orderSn)
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
svcCtx := svc.ServiceContext{
|
|
||||||
Config: l.svcCtx.Config,
|
|
||||||
Repositories: l.svcCtx.Repositories,
|
|
||||||
}
|
|
||||||
svcCtx.Repositories.NewOrder.Close(ctx, &repositories.CloseReq{
|
|
||||||
OrderSn: orderSn,
|
|
||||||
Type: 1,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return resp.SetStatus(basic.CodeOK, map[string]interface{}{
|
return resp.SetStatus(basic.CodeOK, map[string]interface{}{
|
||||||
"order_sn": res.OrderSn,
|
"order_sn": res.OrderSn,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,55 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fusenapi/service/repositories"
|
|
||||||
"fusenapi/utils/auth"
|
|
||||||
"fusenapi/utils/basic"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"fusenapi/server/order/internal/svc"
|
|
||||||
"fusenapi/server/order/internal/types"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DeleteOrderLogic struct {
|
|
||||||
logx.Logger
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDeleteOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteOrderLogic {
|
|
||||||
return &DeleteOrderLogic{
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理进入前逻辑w,r
|
|
||||||
// func (l *DeleteOrderLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (l *DeleteOrderLogic) DeleteOrder(req *types.DeleteOrderReq, userinfo *auth.UserInfo) (resp *basic.Response) {
|
|
||||||
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
|
|
||||||
// userinfo 传入值时, 一定不为null
|
|
||||||
if !userinfo.IsUser() {
|
|
||||||
// 如果是,返回未授权的错误码
|
|
||||||
return resp.SetStatus(basic.CodeUnAuth)
|
|
||||||
}
|
|
||||||
res, err := l.svcCtx.Repositories.NewOrder.Delete(l.ctx, &repositories.DeleteReq{
|
|
||||||
UserId: userinfo.UserId,
|
|
||||||
OrderSn: req.OrderSn,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return resp.SetStatus(&res.ErrorCode)
|
|
||||||
}
|
|
||||||
return resp.SetStatus(basic.CodeOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
|
|
||||||
// func (l *DeleteOrderLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
|
|
||||||
// // httpx.OkJsonCtx(r.Context(), w, resp)
|
|
||||||
// }
|
|
||||||
@ -2,7 +2,6 @@ package svc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fusenapi/server/order/internal/config"
|
"fusenapi/server/order/internal/config"
|
||||||
"fusenapi/utils/queue"
|
|
||||||
|
|
||||||
"fusenapi/initalize"
|
"fusenapi/initalize"
|
||||||
"fusenapi/model/gmodel"
|
"fusenapi/model/gmodel"
|
||||||
@ -16,22 +15,17 @@ type ServiceContext struct {
|
|||||||
MysqlConn *gorm.DB
|
MysqlConn *gorm.DB
|
||||||
AllModels *gmodel.AllModelsGen
|
AllModels *gmodel.AllModelsGen
|
||||||
Repositories *initalize.Repositories
|
Repositories *initalize.Repositories
|
||||||
DelayQueue *queue.DelayMessage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
conn := initalize.InitMysql(c.SourceMysql)
|
conn := initalize.InitMysql(c.SourceMysql)
|
||||||
// delayQueue := initalize.InitDelayMessage()
|
|
||||||
repositories := initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
|
||||||
GormDB: conn,
|
|
||||||
// DelayQueue: delayQueue,
|
|
||||||
})
|
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
MysqlConn: conn,
|
MysqlConn: conn,
|
||||||
AllModels: gmodel.NewAllModels(conn),
|
AllModels: gmodel.NewAllModels(conn),
|
||||||
Repositories: repositories,
|
Repositories: initalize.NewAllRepositories(&initalize.NewAllRepositorieData{
|
||||||
// DelayQueue: delayQueue,
|
GormDB: conn,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user