elf 7 months ago
parent 79bf817d2d
commit 96cf907894

@ -7,6 +7,7 @@ import (
"gold-shop/service"
"gold-shop/utils/result"
"gold-shop/utils/weixin"
"net/http"
"strconv"
)
@ -67,7 +68,7 @@ func GetPayments(c *gin.Context) (result.Data, error) {
if err != nil {
return nil, errors.NewBusinessError("参数错误")
}
payments, total := service.PaymentService.GetPayments(user(c).ID, paymentQueryRequest.Page, paymentQueryRequest.PageSize)
payments, total := service.PaymentService.GetUserPayments(user(c).ID, paymentQueryRequest.Page, paymentQueryRequest.PageSize)
data := result.Data{
"payments": payments,
"total": total,
@ -90,7 +91,7 @@ func GetOrders(c *gin.Context) (result.Data, error) {
if err != nil {
return nil, errors.NewBusinessError("参数错误")
}
orders, total := service.OrderService.GetOrders(user(c).ID, orderQueryRequest.Page, orderQueryRequest.PageSize)
orders, total := service.OrderService.GetUserOrders(user(c).ID, orderQueryRequest.Page, orderQueryRequest.PageSize)
data := result.Data{
"orders": orders,
"total": total,
@ -128,3 +129,21 @@ func GetWxOpenId(c *gin.Context) (result.Data, error) {
data := result.Data{"openid": res.Openid}
return data, nil
}
func SaveAlipayAccount(c *gin.Context) (result.Data, error) {
alipayAccount := c.PostForm("alipayAccount")
err := service.UserService.SaveAlipayAccount(alipayAccount, user(c))
return nil, err
}
func TransferPayNotify(c *gin.Context) {
var req request.TransferPayNotifyRequest
err := c.ShouldBindQuery(&req)
if err != nil {
c.String(http.StatusOK, "fail")
return
}
service.PaymentService.AfterTransferPayNotify(req)
c.String(http.StatusOK, "success")
return
}

@ -0,0 +1,31 @@
package manage
import (
"github.com/gin-gonic/gin"
"gold-shop/errors"
request "gold-shop/request/manage"
"gold-shop/service"
"gold-shop/utils/excel"
"gold-shop/utils/result"
)
func GetOrders(c *gin.Context) (result.Data, error) {
var req request.OrderQueryRequest
err := c.ShouldBindQuery(&req)
if err != nil {
return nil, errors.NewBusinessError("参数错误")
}
orders, total := service.OrderService.GetOrders(req)
data := result.Data{
"records": orders,
"total": total,
}
return data, nil
}
func DownloadOrders(c *gin.Context) {
var req request.OrderQueryRequest
_ = c.ShouldBindQuery(&req)
f := service.OrderService.GenerateOrdersExcel(req)
excel.Download(f, "订单列表.xlsx", c)
}

@ -0,0 +1,31 @@
package manage
import (
"github.com/gin-gonic/gin"
"gold-shop/errors"
request "gold-shop/request/manage"
"gold-shop/service"
"gold-shop/utils/excel"
"gold-shop/utils/result"
)
func GetPayments(c *gin.Context) (result.Data, error) {
var req request.PaymentQueryRequest
err := c.ShouldBindQuery(&req)
if err != nil {
return nil, errors.NewBusinessError("参数错误")
}
records, total := service.PaymentService.GetPayments(req)
data := result.Data{
"records": records,
"total": total,
}
return data, nil
}
func DownloadPayments(c *gin.Context) {
var req request.PaymentQueryRequest
_ = c.ShouldBindQuery(&req)
f := service.PaymentService.GeneratePaymentsExcel(req)
excel.Download(f, "支付列表.xlsx", c)
}

@ -0,0 +1,33 @@
package manage
import (
"fmt"
"github.com/gin-gonic/gin"
"gold-shop/errors"
request "gold-shop/request/manage"
"gold-shop/service"
"gold-shop/utils/excel"
"gold-shop/utils/result"
)
func GetUsers(c *gin.Context) (result.Data, error) {
var req request.UserQueryRequest
err := c.ShouldBindQuery(&req)
fmt.Println("ssp", req)
if err != nil {
return nil, errors.NewBusinessError("参数错误")
}
users, total := service.UserService.GetUsers(req)
data := result.Data{
"records": users,
"total": total,
}
return data, nil
}
func DownloadUsers(c *gin.Context) {
var req request.UserQueryRequest
_ = c.ShouldBindQuery(&req)
f := service.UserService.GenerateUsersExcel(req)
excel.Download(f, "用户列表.xlsx", c)
}

@ -17,9 +17,11 @@ redis:
password: ""
db: 0
payment:
base-url: "http://api2.lfwin.com"
api-key: "00014005"
sign-key: "punr8ucu"
base-url: "http://api2uat.lfwin.com"
# api-key: "00014005"
# sign-key: "punr8ucu"
api-key: "231809002"
sign-key: "3wr2ymiz"
wx-pay:
sub-app-id: "wxb1bec7d809e7cf40"
sub-app-secret: ""

@ -39,13 +39,19 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/redis/go-redis/v9 v9.5.1 // indirect
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.3 // indirect
github.com/smartwalle/ncrypto v1.0.4 // indirect
github.com/smartwalle/ngx v1.0.9 // indirect
github.com/smartwalle/nsign v1.0.9 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
github.com/xuri/excelize/v2 v2.8.1 // indirect
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.22.0 // indirect

@ -81,6 +81,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
@ -89,6 +91,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/smartwalle/alipay/v3 v3.2.20 h1:IjpG3YYgUgzCfS0z/EHlUbbr0OlrmOBHUst/3FzToYE=
github.com/smartwalle/alipay/v3 v3.2.20/go.mod h1:KWg91KsY+eIOf26ZfZeH7bed1bWulGpGrL1ErHF3jWo=
github.com/smartwalle/ncrypto v1.0.4 h1:P2rqQxDepJwgeO5ShoC+wGcK2wNJDmcdBOWAksuIgx8=
@ -115,6 +122,12 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0=
github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.8.1 h1:pZLMEwK8ep+CLIUWpWmvW8IWE/yxqG0I1xcN6cVMGuQ=
github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluUhG7c+CEE=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4=
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=

Binary file not shown.

@ -14,19 +14,7 @@ import (
const FilePath = "config.yaml"
func InitConfig() *config.Config {
currentDir, err := os.Getwd()
if err != nil {
panic(err)
}
fmt.Println("currentDir: " + currentDir)
filePath := currentDir + "/" + FilePath
//filePath := "/var/www/gold-shop/" + FilePath
fmt.Println("filepath: " + filePath)
func InitConfig(filePath string) *config.Config {
content, err := os.ReadFile(filePath)
if err != nil {
fmt.Printf("err: %v\n", err)

@ -2,6 +2,7 @@ package main
import (
"encoding/json"
"flag"
"fmt"
"github.com/fvbock/endless"
"github.com/gin-gonic/gin"
@ -16,14 +17,19 @@ import (
)
func main() {
RunServer()
initial()
runServer()
}
func RunServer() {
global.Config = initialize.InitConfig()
func initial() {
var configFilePath string
flag.StringVar(&configFilePath, "config", "./config.yaml", "配置文件")
flag.Parse()
global.Config = initialize.InitConfig(configFilePath)
global.DB = initialize.InitDB(global.Config)
global.Redis = initialize.InitRedis(global.Config)
}
func runServer() {
r := gin.Default()
s := &http.Server{
Addr: ":8080",

@ -8,21 +8,11 @@ import (
func CorsMiddleware(module string) gin.HandlerFunc {
return cors.New(cors.Config{
// AllowOrigins 允许跨域的域名
AllowOrigins: []string{"*"},
// AllowMethods 是允许客户端请求的跨域协议
AllowMethods: []string{"PUT", "PATCH", "GET", "POST", "DELETE", "OPTIONS"},
// AllowHeaders 是允许客户端访问的请求头列表
AllowHeaders: []string{"Origin", "Origin", "Content-Length", "Content-Type", "Authorization"},
// ExposeHeaders 是允许客户端访问的响应头列表
ExposeHeaders: []string{"Content-Length", "Authorization"},
// AllowCredentials 是允许客户端传递cookie等认证信息如果设置为trueAllowOrigin不能设置为*,必须指定具体的域名
AllowAllOrigins: true,
//AllowOrigins: []string{"*"},
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization"},
AllowCredentials: false,
// AllowOriginFunc 用于自定义跨域请求的域名
//AllowOriginFunc: func(origin string) bool {
// return origin == "https://github.com"
//},
// MaxAge 设置缓存时间
MaxAge: 12 * time.Hour,
})
}

@ -12,6 +12,9 @@ import (
func JwtMiddleware(role string) gin.HandlerFunc {
return func(c *gin.Context) {
token := c.Request.Header.Get("Authorization")
if token == "" {
token = c.Query("token")
}
result := utils.Result{}
if token == "" {
result.Code = utils.Error

@ -6,10 +6,11 @@ import (
)
type Order struct {
ID uint
ID int
OrderNo string
UserID int
Amount float64
User User `gorm:"foreignKey:UserID;references:ID"`
OrderProducts []OrderProduct `gorm:"foreignKey:OrderNo;references:OrderNo"`
CreatedAt time.Time
UpdatedAt time.Time

@ -5,13 +5,21 @@ import (
"time"
)
const PaymentStatusSuccess = 1
const PaymentStatusFailed = 2
const PaymentStatusWait = 0
type Payment struct {
ID uint
ID int
PaymentNo string
UserID int
Amount float64
User User `gorm:"foreignKey:UserID;references:ID"`
PayType string
OpenID string
ErrorMessage string
PayerCardNo string
PayerAccountName string
Status int
CreatedAt time.Time
UpdatedAt time.Time
@ -33,3 +41,16 @@ func (p Payment) MarshalJSON() ([]byte, error) {
Alias: (*Alias)(&p),
})
}
func (p Payment) GetStatusText() string {
statusText := ""
switch p.Status {
case PaymentStatusSuccess:
statusText = "支付成功"
case PaymentStatusFailed:
statusText = "支付失败"
case PaymentStatusWait:
statusText = "待支付"
}
return statusText
}

@ -5,6 +5,9 @@ import (
"time"
)
const UserStatusActive = 1
const UserStatusDisable = 2
type User struct {
ID int
Mobile string
@ -13,6 +16,7 @@ type User struct {
MasterUserId int `json:"-"`
PasswordHash string `json:"-"`
PaymentPasswordHash string `json:"-"`
AlipayAccount string
Profit float64
Balance float64
Status int
@ -34,3 +38,14 @@ func (u User) MarshalJSON() ([]byte, error) {
Alias: (*Alias)(&u),
})
}
func (u User) GetStatusText() string {
statusText := ""
switch u.Status {
case UserStatusActive:
statusText = "正常"
case UserStatusDisable:
statusText = "禁用"
}
return statusText
}

@ -0,0 +1,10 @@
package manage
import "gold-shop/request"
type OrderQueryRequest struct {
request.PageQueryRequest
UserID int `form:"userId"`
Mobile string `form:"mobile"`
OrderNo string `form:"orderNo"`
}

@ -0,0 +1,11 @@
package manage
import "gold-shop/request"
type PaymentQueryRequest struct {
request.PageQueryRequest
UserID int `form:"userId"`
Mobile string `form:"mobile"`
PaymentNo string `form:"paymentNo"`
Status string `form:"status"`
}

@ -0,0 +1,9 @@
package manage
import "gold-shop/request"
type UserQueryRequest struct {
request.PageQueryRequest
Mobile string `form:"mobile"`
Status string `form:"status"`
}

@ -0,0 +1,17 @@
package request
type TransferPayNotifyRequest struct {
OutOrderID string `json:"out_orderid"`
ApiKey string `json:"apikey"`
PayerCardNo string `json:"payer_card_no"`
OrderID string `json:"orderid"`
PayerAccountName string `json:"payer_account_name"`
OrderMoney string `json:"order_money"`
PayeeAccountName string `json:"payee_account_name"`
PayeeBankName string `json:"payee_bank_name"`
PayMoney string `json:"pay_money"`
PayTime string `json:"pay_time"`
PayeeCardNo string `json:"payee_card_no"`
PayStatus string `json:"pay_status"`
AddTime string `json:"add_time"`
}

@ -10,23 +10,25 @@ import (
func h5RouteInit(r *gin.Engine) {
h5Group := r.Group("/h5")
h5Group.Use(middleware.CorsMiddleware("h5"))
h5Group.POST("/login", result.Json(h5.Login))
h5Group.POST("/register", result.Json(h5.Register))
h5Group.GET("/get-product-info", result.Json(h5.GetProductInfo))
h5Group.Match([]string{"POST", "OPTIONS"}, "/login", result.Json(h5.Login))
h5Group.Match([]string{"POST", "OPTIONS"}, "/register", result.Json(h5.Register))
h5Group.Match([]string{"GET", "OPTIONS"}, "/get-product-info", result.Json(h5.GetProductInfo))
h5Group.Match([]string{"POST", "OPTIONS"}, "/transfer-pay-notify", h5.TransferPayNotify)
authGroup := h5Group.Group("")
authGroup.Use(middleware.JwtMiddleware("user"))
{
authGroup.GET("/ping", result.Json(h5.Index))
authGroup.GET("/error", result.Json(h5.Error))
authGroup.GET("/get-user-info", result.Json(h5.GetUserInfo))
authGroup.POST("/order", result.Json(h5.Order))
authGroup.POST("/modify-password", result.Json(h5.ModifyPassword))
authGroup.POST("/payment", result.Json(h5.Payment))
authGroup.GET("/get-wx-open-id", result.Json(h5.GetWxOpenId))
authGroup.GET("/get-wx-auth-url", result.Json(h5.GetWxAuthUrl))
authGroup.GET("/get-orders", result.Json(h5.GetOrders))
authGroup.GET("/get-payments", result.Json(h5.GetPayments))
authGroup.GET("/get-user-data", result.Json(h5.GetUserData))
authGroup.Match([]string{"GET", "OPTIONS"}, "/ping", result.Json(h5.Index))
authGroup.Match([]string{"GET", "OPTIONS"}, "/error", result.Json(h5.Error))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-user-info", result.Json(h5.GetUserInfo))
authGroup.Match([]string{"POST", "OPTIONS"}, "/order", result.Json(h5.Order))
authGroup.Match([]string{"POST", "OPTIONS"}, "/modify-password", result.Json(h5.ModifyPassword))
authGroup.Match([]string{"POST", "OPTIONS"}, "/payment", result.Json(h5.Payment))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-wx-open-id", result.Json(h5.GetWxOpenId))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-wx-auth-url", result.Json(h5.GetWxAuthUrl))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-orders", result.Json(h5.GetOrders))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-payments", result.Json(h5.GetPayments))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-user-data", result.Json(h5.GetUserData))
authGroup.Match([]string{"POST", "OPTIONS"}, "/save-alipay-account", result.Json(h5.SaveAlipayAccount))
}
}

@ -11,6 +11,7 @@ func adminRouteInit(r *gin.Engine) {
manageGroup := r.Group("/manage")
manageGroup.Use(middleware.CorsMiddleware("manage"))
manageGroup.Match([]string{"POST", "OPTIONS"}, "/login", result.Json(manage.Login))
manageGroup.GET("/download", manage.DownloadUsers)
authGroup := manageGroup.Group("")
authGroup.Use(middleware.JwtMiddleware("admin"))
@ -18,5 +19,11 @@ func adminRouteInit(r *gin.Engine) {
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-admin-info", result.Json(manage.GetAdminInfo))
authGroup.Match([]string{"POST", "OPTIONS"}, "/logout", result.Json(manage.Logout))
authGroup.Match([]string{"POST", "OPTIONS"}, "/add-admin", result.Json(manage.AddAdmin))
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-users", result.Json(manage.GetUsers))
authGroup.Match([]string{"GET", "OPTIONS"}, "/download-users", manage.DownloadUsers)
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-orders", result.Json(manage.GetOrders))
authGroup.Match([]string{"GET", "OPTIONS"}, "/download-orders", manage.DownloadOrders)
authGroup.Match([]string{"GET", "OPTIONS"}, "/get-payments", result.Json(manage.GetPayments))
authGroup.Match([]string{"GET", "OPTIONS"}, "/download-payments", manage.DownloadPayments)
}
}

@ -2,12 +2,16 @@ package service
import (
e "errors"
"github.com/xuri/excelize/v2"
"gold-shop/errors"
"gold-shop/global"
"gold-shop/model"
"gold-shop/request"
"gold-shop/request/manage"
"gold-shop/utils"
"gold-shop/utils/excel"
"gorm.io/gorm"
"time"
)
var OrderService = orderService{}
@ -57,7 +61,7 @@ func (orderService) Order(orderRequest request.OrderRequest, user *model.User) (
return &order, nil
}
func (orderService) GetOrders(userID, page, pageSize int) ([]model.Order, int64) {
func (orderService) GetUserOrders(userID, page, pageSize int) ([]model.Order, int64) {
orders := make([]model.Order, pageSize)
offset := (page - 1) * pageSize
var total int64
@ -65,3 +69,68 @@ func (orderService) GetOrders(userID, page, pageSize int) ([]model.Order, int64)
global.DB.Model(&model.Order{}).Where("user_id", userID).Count(&total)
return orders, total
}
func (s *orderService) buildQuery(req manage.OrderQueryRequest) *gorm.DB {
tx := global.DB
if req.Mobile != "" {
var userIds []int
global.DB.Model(&model.User{}).Where("mobile", req.Mobile).Pluck("id", &userIds)
tx = tx.Where("user_id", userIds)
}
if req.OrderNo != "" {
tx = tx.Where("order_no", req.OrderNo)
}
if req.UserID != 0 {
tx = tx.Where("user_id", req.UserID)
}
return tx
}
func (s *orderService) GetOrders(req manage.OrderQueryRequest) ([]model.Order, int64) {
orders := make([]model.Order, req.PageSize)
offset := (req.Page - 1) * req.PageSize
var total int64
tx := s.buildQuery(req)
tx.Preload("OrderProducts").Preload("User").Order("id desc").Offset(offset).Limit(req.PageSize).Find(&orders)
tx.Model(&model.Order{}).Count(&total)
return orders, total
}
func (s *orderService) GenerateOrdersExcel(req manage.OrderQueryRequest) *excelize.File {
pageSize := 200
lastID := 0
tx := s.buildQuery(req)
f := excel.NewFile()
headers := []string{"订单号", "用户手机号", "购买份数", "订单总金额", "下单时间"}
excel.SetSimpleHeaders(headers, "Sheet1", f)
for {
orders := make([]model.Order, pageSize)
tx.Preload("OrderProducts").Preload("User").Where("id > ?", lastID).Limit(pageSize).Find(&orders)
count := len(orders)
if count == 0 {
break
}
s.buildOrdersExcel(orders, "Sheet1", f)
lastIndex := count - 1
lastID = orders[lastIndex].ID
}
return f
}
func (orderService) buildOrdersExcel(orders []model.Order, sheet string, f *excelize.File) {
row := 2
for _, order := range orders {
col := 0
num := 0
for _, orderProduct := range order.OrderProducts {
num += orderProduct.Num
}
f.SetCellValue(sheet, excel.CellKey(row, &col), order.OrderNo)
f.SetCellValue(sheet, excel.CellKey(row, &col), order.User.Mobile)
f.SetCellValue(sheet, excel.CellKey(row, &col), num)
f.SetCellValue(sheet, excel.CellKey(row, &col), order.Amount)
f.SetCellValue(sheet, excel.CellKey(row, &col), order.CreatedAt.Format(time.DateTime))
row++
}
}

@ -1,13 +1,19 @@
package service
import (
e "errors"
"github.com/xuri/excelize/v2"
"gold-shop/errors"
"gold-shop/global"
"gold-shop/model"
"gold-shop/request"
"gold-shop/request/manage"
"gold-shop/utils"
"gold-shop/utils/excel"
"gold-shop/utils/payment"
"gold-shop/utils/result"
"gorm.io/gorm"
"time"
)
var PaymentService = paymentService{}
@ -15,7 +21,7 @@ var PaymentService = paymentService{}
type paymentService struct {
}
func (paymentService) GetPayments(userID, page, pageSize int) ([]model.Payment, int64) {
func (paymentService) GetUserPayments(userID, page, pageSize int) ([]model.Payment, int64) {
payments := make([]model.Payment, pageSize)
offset := (page - 1) * pageSize
var total int64
@ -25,7 +31,33 @@ func (paymentService) GetPayments(userID, page, pageSize int) ([]model.Payment,
}
func (s paymentService) Payment(userID int, paymentRequest request.PaymentRequest) (result.Data, error) {
p, err := s.createPayment(userID, paymentRequest.OpenID, paymentRequest.Amount)
p, err := s.createPayment(userID, paymentRequest)
if err != nil {
return nil, err
}
data := result.Data{}
if paymentRequest.PayType == "wxOfficial" {
data, err = s.wxPayment(paymentRequest, p)
} else if paymentRequest.PayType == "transfer" {
data, err = s.transferPayment(paymentRequest, p)
} else {
err = errors.NewBusinessError("payType参数错误")
}
if err != nil {
p.Status = 2
p.ErrorMessage = err.Error()
global.DB.Save(p)
return nil, err
}
p.Status = 1
global.DB.Save(p)
return data, nil
}
func (s paymentService) wxPayment(paymentRequest request.PaymentRequest, p *model.Payment) (result.Data, error) {
param := payment.WxPayParam{}
param.Remark = "payment"
param.OrderId = utils.GenerateNo("payment")
@ -36,17 +68,11 @@ func (s paymentService) Payment(userID int, paymentRequest request.PaymentReques
if err != nil {
return nil, err
}
if res.Status != payment.Success {
p.Status = 2
p.ErrorMessage = res.Message
global.DB.Save(p)
return nil, errors.NewBusinessError(res.Message)
}
p.Status = 1
p.ErrorMessage = res.Message
global.DB.Save(p)
data := result.Data{
"paySign": res.PaySign,
"package": res.Package,
@ -58,11 +84,37 @@ func (s paymentService) Payment(userID int, paymentRequest request.PaymentReques
return data, nil
}
func (paymentService) createPayment(userID int, openID string, amount float64) (*model.Payment, error) {
func (s paymentService) transferPayment(paymentRequest request.PaymentRequest, p *model.Payment) (result.Data, error) {
param := payment.TransferPayParam{}
param.Remark = "payment"
param.OrderId = utils.GenerateNo("payment")
param.Amount = paymentRequest.Amount
param.NotifyUrl = ""
res, err := payment.PayApi.TransferPay(param)
if err != nil {
return nil, err
}
if res.Status != payment.Success {
return nil, errors.NewBusinessError(res.Message)
}
data := result.Data{
"payeeAccountName": res.PayeeAccountName,
"payeeBankName": res.PayeeBankName,
"payeeCardNo": res.PayeeCardNo,
"orderID": res.OrderID,
"outOrderID": res.OutOrderID,
}
return data, nil
}
func (paymentService) createPayment(userID int, paymentRequest request.PaymentRequest) (*model.Payment, error) {
p := model.Payment{}
p.PaymentNo = utils.GenerateNo("payment")
p.Amount = amount
p.OpenID = openID
p.Amount = paymentRequest.Amount
p.OpenID = paymentRequest.OpenID
p.PayType = paymentRequest.PayType
p.Status = 0
p.UserID = userID
err := global.DB.Save(&p).Error
@ -71,3 +123,86 @@ func (paymentService) createPayment(userID int, openID string, amount float64) (
}
return &p, nil
}
func (s *paymentService) buildQuery(req manage.PaymentQueryRequest) *gorm.DB {
tx := global.DB
if req.Mobile != "" {
var userIds []int
global.DB.Model(&model.User{}).Where("mobile", req.Mobile).Pluck("id", &userIds)
tx = tx.Where("user_id", userIds)
}
if req.PaymentNo != "" {
tx = tx.Where("payment_no", req.PaymentNo)
}
if req.Status != "" {
tx = tx.Where("status", req.Status)
}
if req.UserID != 0 {
tx = tx.Where("user_id", req.UserID)
}
return tx
}
func (s *paymentService) GetPayments(req manage.PaymentQueryRequest) ([]model.Payment, int64) {
payments := make([]model.Payment, req.PageSize)
offset := (req.Page - 1) * req.PageSize
var total int64
tx := s.buildQuery(req)
tx.Preload("User").Order("id desc").Offset(offset).Limit(req.PageSize).Find(&payments)
tx.Model(&model.Order{}).Count(&total)
return payments, total
}
func (s *paymentService) GeneratePaymentsExcel(req manage.PaymentQueryRequest) *excelize.File {
pageSize := 200
lastID := 0
tx := s.buildQuery(req)
f := excel.NewFile()
headers := []string{"支付订单号", "用户手机号", "金额", "支付状态", "支付时间"}
excel.SetSimpleHeaders(headers, "Sheet1", f)
for {
payments := make([]model.Payment, pageSize)
tx.Preload("User").Where("id > ?", lastID).Limit(pageSize).Find(&payments)
count := len(payments)
if count == 0 {
break
}
s.buildPaymentsExcel(payments, "Sheet1", f)
lastIndex := count - 1
lastID = payments[lastIndex].ID
}
return f
}
func (paymentService) buildPaymentsExcel(payments []model.Payment, sheet string, f *excelize.File) {
row := 2
for _, p := range payments {
col := 0
f.SetCellValue(sheet, excel.CellKey(row, &col), p.PaymentNo)
f.SetCellValue(sheet, excel.CellKey(row, &col), p.User.Mobile)
f.SetCellValue(sheet, excel.CellKey(row, &col), p.Amount)
f.SetCellValue(sheet, excel.CellKey(row, &col), p.GetStatusText())
f.SetCellValue(sheet, excel.CellKey(row, &col), p.CreatedAt.Format(time.DateTime))
row++
}
}
func (s paymentService) AfterTransferPayNotify(req request.TransferPayNotifyRequest) error {
pm := &model.Payment{}
err := global.DB.Where("payment_no", req.OutOrderID).First(&pm).Error
if err != nil && e.Is(err, gorm.ErrRecordNotFound) {
return errors.NewBusinessError("记录不存在")
}
if req.PayStatus == "1" {
pm.Status = 1
pm.PayerCardNo = req.PayerCardNo
pm.PayerAccountName = req.PayerAccountName
} else {
pm.Status = 2
}
err = global.DB.Save(&pm).Error
return err
}

@ -2,12 +2,16 @@ package service
import (
e "errors"
"github.com/xuri/excelize/v2"
"gold-shop/errors"
"gold-shop/global"
"gold-shop/model"
"gold-shop/request/manage"
"gold-shop/utils"
"gold-shop/utils/excel"
"gold-shop/utils/result"
"gorm.io/gorm"
"time"
)
var UserService = userService{}
@ -36,6 +40,7 @@ func (userService) Register(mobile string, password string) error {
user.Mobile = mobile
passwordHash, _ := utils.PasswordHash(password)
user.PasswordHash = passwordHash
user.Status = 1
return global.DB.Save(user).Error
}
@ -62,3 +67,64 @@ func (userService) GetUserData(user *model.User) result.Data {
}
return data
}
func (s *userService) GetUsers(req manage.UserQueryRequest) ([]model.User, int64) {
users := make([]model.User, req.PageSize)
offset := (req.Page - 1) * req.PageSize
var total int64
tx := s.buildQuery(req)
tx.Order("id desc").Offset(offset).Limit(req.PageSize).Find(&users)
tx.Model(&model.User{}).Count(&total)
return users, total
}
func (userService) SaveAlipayAccount(alipayAccount string, user *model.User) error {
err := global.DB.Model(&model.User{}).Where("id", user.ID).Update("alipay_account", alipayAccount).Error
return err
}
func (s *userService) buildQuery(req manage.UserQueryRequest) *gorm.DB {
tx := global.DB
if req.Mobile != "" {
tx = tx.Where("mobile", req.Mobile)
}
if req.Status != "" {
tx = tx.Where("status", req.Status)
}
return tx
}
func (s *userService) GenerateUsersExcel(req manage.UserQueryRequest) *excelize.File {
pageSize := 200
lastID := 0
tx := s.buildQuery(req)
f := excel.NewFile()
headers := []string{"用户ID", "手机号", "支付宝账号", "账户余额", "用户状态", "注册时间"}
excel.SetSimpleHeaders(headers, "Sheet1", f)
for {
users := make([]model.User, pageSize)
tx.Where("id > ?", lastID).Limit(pageSize).Find(&users)
count := len(users)
if count == 0 {
break
}
s.buildUserListExcel(users, "Sheet1", f)
lastIndex := count - 1
lastID = users[lastIndex].ID
}
return f
}
func (userService) buildUserListExcel(users []model.User, sheet string, f *excelize.File) {
row := 2
for _, user := range users {
col := 0
f.SetCellValue(sheet, excel.CellKey(row, &col), user.ID)
f.SetCellValue(sheet, excel.CellKey(row, &col), user.Mobile)
f.SetCellValue(sheet, excel.CellKey(row, &col), user.AlipayAccount)
f.SetCellValue(sheet, excel.CellKey(row, &col), user.Balance)
f.SetCellValue(sheet, excel.CellKey(row, &col), user.GetStatusText())
f.SetCellValue(sheet, excel.CellKey(row, &col), user.CreatedAt.Format(time.DateTime))
row++
}
}

@ -0,0 +1,46 @@
package excel
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/xuri/excelize/v2"
"net/http"
"strconv"
)
func NewFile() *excelize.File {
f := excelize.NewFile()
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
return f
}
func Download(f *excelize.File, fileName string, c *gin.Context) {
c.Header("Content-Disposition", "attachment; filename="+fileName)
c.Header("Content-Type", "application/vnd.ms-excel")
c.Status(http.StatusOK)
err := f.Write(c.Writer)
if err != nil {
fmt.Println(err.Error())
}
}
func SetSimpleHeaders(headers []string, sheet string, f *excelize.File) {
for i, header := range headers {
f.SetCellValue(sheet, ColKey(i)+"1", header)
}
}
func ColKey(i int) string {
rowKeys := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}
return rowKeys[i]
}
func CellKey(row int, col *int) string {
cellKey := ColKey(*col) + strconv.Itoa(row)
*col++
return cellKey
}

@ -44,6 +44,32 @@ func (api *payApi) WxPay(param WxPayParam) (*WxPayResult, error) {
return &result, nil
}
func (api *payApi) TransferPay(param TransferPayParam) (*TransferPayResult, error) {
payment := global.Config.Payment
data := url.Values{}
data.Set("service", "pay.heli.large_query")
data.Set("apikey", payment.ApiKey)
data.Set("order_money", fmt.Sprintf("%.2f", param.Amount))
data.Set("nonce_str", utils.GenerateRandomString(32))
data.Set("out_orderid", param.OrderId)
//data.Set("notify_url", param.NotifyUrl)
//data.Set("remark", param.Remark)
sign := api.sign(data, payment.SignKey)
data.Set("sign", sign)
fmt.Println(data.Encode())
fmt.Println("url: " + payment.BaseUrl + "/payapi/pay/large_create")
res, err := api.post(payment.BaseUrl+"/payapi/pay/large_create", data)
if err != nil {
return nil, err
}
result := TransferPayResult{}
err = json.Unmarshal(res, &result)
if err != nil {
return nil, errors.NewBusinessError("结果解析错误")
}
return &result, nil
}
func (payApi) sign(params url.Values, signKey string) string {
fmt.Println(params.Encode() + "&signkey=" + signKey)
return utils.Md5(params.Encode() + "&signkey=" + signKey)

@ -0,0 +1,9 @@
package payment
type TransferPayParam struct {
OpenId string
Amount float64
OrderId string
NotifyUrl string
Remark string
}

@ -0,0 +1,16 @@
package payment
type TransferPayResult struct {
Service string `json:"service"`
OrderID string `json:"orderid"`
OutOrderID string `json:"out_orderid"`
OrderMoney string `json:"order_money"`
PayeeAccountName string `json:"payee_account_name"`
PayeeCardNo string `json:"payee_card_no"`
PayeeBankName string `json:"payee_bank_name"`
Version string `json:"version"`
Message string `json:"message"`
Status string `json:"status"`
SignType string `json:"sign_ype"`
Sign string `json:"sign"`
}
Loading…
Cancel
Save