diff --git a/app/admin/apis/line_coinnetwork.go b/app/admin/apis/line_coinnetwork.go index 1a85256..c004d1b 100644 --- a/app/admin/apis/line_coinnetwork.go +++ b/app/admin/apis/line_coinnetwork.go @@ -1,9 +1,10 @@ package apis import ( - "fmt" + "fmt" "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" "github.com/go-admin-team/go-admin-core/sdk/api" "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" _ "github.com/go-admin-team/go-admin-core/sdk/pkg/response" @@ -28,18 +29,18 @@ type LineCoinnetwork struct { // @Router /api/v1/line-coinnetwork [get] // @Security Bearer func (e LineCoinnetwork) GetPage(c *gin.Context) { - req := dto.LineCoinnetworkGetPageReq{} - s := service.LineCoinnetwork{} - err := e.MakeContext(c). - MakeOrm(). - Bind(&req). - MakeService(&s.Service). - Errors - if err != nil { - e.Logger.Error(err) - e.Error(500, err, err.Error()) - return - } + req := dto.LineCoinnetworkGetPageReq{} + s := service.LineCoinnetwork{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.Form, binding.Query). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } p := actions.GetPermissionFromContext(c) list := make([]models.LineCoinnetwork, 0) @@ -48,7 +49,7 @@ func (e LineCoinnetwork) GetPage(c *gin.Context) { err = s.GetPage(&req, p, &list, &count) if err != nil { e.Error(500, err, fmt.Sprintf("获取【币种网络】失败,\r\n失败信息 %s", err.Error())) - return + return } e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") @@ -65,7 +66,7 @@ func (e LineCoinnetwork) GetPage(c *gin.Context) { func (e LineCoinnetwork) Get(c *gin.Context) { req := dto.LineCoinnetworkGetReq{} s := service.LineCoinnetwork{} - err := e.MakeContext(c). + err := e.MakeContext(c). MakeOrm(). Bind(&req). MakeService(&s.Service). @@ -81,10 +82,10 @@ func (e LineCoinnetwork) Get(c *gin.Context) { err = s.Get(&req, p, &object) if err != nil { e.Error(500, err, fmt.Sprintf("获取【币种网络】失败,\r\n失败信息 %s", err.Error())) - return + return } - e.OK( object, "查询成功") + e.OK(object, "查询成功") } // Insert 创建【币种网络】 @@ -98,25 +99,25 @@ func (e LineCoinnetwork) Get(c *gin.Context) { // @Router /api/v1/line-coinnetwork [post] // @Security Bearer func (e LineCoinnetwork) Insert(c *gin.Context) { - req := dto.LineCoinnetworkInsertReq{} - s := service.LineCoinnetwork{} - err := e.MakeContext(c). - MakeOrm(). - Bind(&req). - MakeService(&s.Service). - Errors - if err != nil { - e.Logger.Error(err) - e.Error(500, err, err.Error()) - return - } + req := dto.LineCoinnetworkInsertReq{} + s := service.LineCoinnetwork{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } // 设置创建人 req.SetCreateBy(user.GetUserId(c)) err = s.Insert(&req) if err != nil { e.Error(500, err, fmt.Sprintf("创建【币种网络】失败,\r\n失败信息 %s", err.Error())) - return + return } e.OK(req.GetId(), "创建成功") @@ -134,27 +135,27 @@ func (e LineCoinnetwork) Insert(c *gin.Context) { // @Router /api/v1/line-coinnetwork/{id} [put] // @Security Bearer func (e LineCoinnetwork) Update(c *gin.Context) { - req := dto.LineCoinnetworkUpdateReq{} - s := service.LineCoinnetwork{} - err := e.MakeContext(c). - MakeOrm(). - Bind(&req). - MakeService(&s.Service). - Errors - if err != nil { - e.Logger.Error(err) - e.Error(500, err, err.Error()) - return - } + req := dto.LineCoinnetworkUpdateReq{} + s := service.LineCoinnetwork{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } req.SetUpdateBy(user.GetUserId(c)) p := actions.GetPermissionFromContext(c) err = s.Update(&req, p) if err != nil { e.Error(500, err, fmt.Sprintf("修改【币种网络】失败,\r\n失败信息 %s", err.Error())) - return + return } - e.OK( req.GetId(), "修改成功") + e.OK(req.GetId(), "修改成功") } // Delete 删除【币种网络】 @@ -166,18 +167,18 @@ func (e LineCoinnetwork) Update(c *gin.Context) { // @Router /api/v1/line-coinnetwork [delete] // @Security Bearer func (e LineCoinnetwork) Delete(c *gin.Context) { - s := service.LineCoinnetwork{} - req := dto.LineCoinnetworkDeleteReq{} - err := e.MakeContext(c). - MakeOrm(). - Bind(&req). - MakeService(&s.Service). - Errors - if err != nil { - e.Logger.Error(err) - e.Error(500, err, err.Error()) - return - } + s := service.LineCoinnetwork{} + req := dto.LineCoinnetworkDeleteReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } // req.SetUpdateBy(user.GetUserId(c)) p := actions.GetPermissionFromContext(c) @@ -185,7 +186,7 @@ func (e LineCoinnetwork) Delete(c *gin.Context) { err = s.Remove(&req, p) if err != nil { e.Error(500, err, fmt.Sprintf("删除【币种网络】失败,\r\n失败信息 %s", err.Error())) - return + return } - e.OK( req.GetId(), "删除成功") + e.OK(req.GetId(), "删除成功") } diff --git a/app/admin/apis/line_pre_order.go b/app/admin/apis/line_pre_order.go index 145687a..40a2c1f 100644 --- a/app/admin/apis/line_pre_order.go +++ b/app/admin/apis/line_pre_order.go @@ -113,11 +113,7 @@ func (e LinePreOrder) GetChildOrderList(c *gin.Context) { } p := actions.GetPermissionFromContext(c) list := make([]models.LinePreOrder, 0) - if err != nil { - e.Logger.Error(err) - e.Error(500, err, err.Error()) - return - } + err = s.GetChildList(&req, p, &list) if err != nil { e.Error(500, err, fmt.Sprintf("获取子订单信息失败,\r\n失败信息 %s", err.Error())) @@ -310,6 +306,35 @@ func (e LinePreOrder) AddPreOrder(c *gin.Context) { e.OK(nil, "操作成功") } +// 手动加仓 +func (e LinePreOrder) AddPosition(c *gin.Context) { + s := service.LinePreOrder{} + req := dto.LinePreOrderAddPositionReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + if err := req.Valid(); err != nil { + e.Error(500, err, err.Error()) + return + } + + err = s.AddPosition(&req) + + if err != nil { + e.Error(500, nil, err.Error()) + return + } + e.OK(nil, "操作成功") +} + // BatchAddOrder 批量添加 func (e LinePreOrder) BatchAddOrder(c *gin.Context) { s := service.LinePreOrder{} diff --git a/app/admin/apis/member_withdrawal_log.go b/app/admin/apis/member_withdrawal_log.go new file mode 100644 index 0000000..9ded828 --- /dev/null +++ b/app/admin/apis/member_withdrawal_log.go @@ -0,0 +1,193 @@ +package apis + +import ( + "fmt" + + "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/sdk/api" + "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" + _ "github.com/go-admin-team/go-admin-core/sdk/pkg/response" + + "go-admin/app/admin/models" + "go-admin/app/admin/service" + "go-admin/app/admin/service/dto" + "go-admin/common/actions" +) + +type MemberWithdrawalLog struct { + api.Api +} + +// GetPage 获取用户提现记录列表 +// @Summary 获取用户提现记录列表 +// @Description 获取用户提现记录列表 +// @Tags 用户提现记录 +// @Param networkName query string false "网络名称" +// @Param status query string false "提现状态(member_withdrawal_status)" +// @Param pageSize query int false "页条数" +// @Param pageIndex query int false "页码" +// @Success 200 {object} response.Response{data=response.Page{list=[]models.MemberWithdrawalLog}} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-withdrawal-log [get] +// @Security Bearer +func (e MemberWithdrawalLog) GetPage(c *gin.Context) { + req := dto.MemberWithdrawalLogGetPageReq{} + s := service.MemberWithdrawalLog{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + p := actions.GetPermissionFromContext(c) + list := make([]models.MemberWithdrawalLog, 0) + var count int64 + + err = s.GetPage(&req, p, &list, &count) + if err != nil { + e.Error(500, err, fmt.Sprintf("获取用户提现记录失败,\r\n失败信息 %s", err.Error())) + return + } + + e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") +} + +// Get 获取用户提现记录 +// @Summary 获取用户提现记录 +// @Description 获取用户提现记录 +// @Tags 用户提现记录 +// @Param id path int false "id" +// @Success 200 {object} response.Response{data=models.MemberWithdrawalLog} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-withdrawal-log/{id} [get] +// @Security Bearer +func (e MemberWithdrawalLog) Get(c *gin.Context) { + req := dto.MemberWithdrawalLogGetReq{} + s := service.MemberWithdrawalLog{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + var object models.MemberWithdrawalLog + + p := actions.GetPermissionFromContext(c) + err = s.Get(&req, p, &object) + if err != nil { + e.Error(500, err, fmt.Sprintf("获取用户提现记录失败,\r\n失败信息 %s", err.Error())) + return + } + + e.OK( object, "查询成功") +} + +// Insert 创建用户提现记录 +// @Summary 创建用户提现记录 +// @Description 创建用户提现记录 +// @Tags 用户提现记录 +// @Accept application/json +// @Product application/json +// @Param data body dto.MemberWithdrawalLogInsertReq true "data" +// @Success 200 {object} response.Response "{"code": 200, "message": "添加成功"}" +// @Router /api/v1/member-withdrawal-log [post] +// @Security Bearer +func (e MemberWithdrawalLog) Insert(c *gin.Context) { + req := dto.MemberWithdrawalLogInsertReq{} + s := service.MemberWithdrawalLog{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + // 设置创建人 + req.SetCreateBy(user.GetUserId(c)) + + err = s.Insert(&req) + if err != nil { + e.Error(500, err, fmt.Sprintf("创建用户提现记录失败,\r\n失败信息 %s", err.Error())) + return + } + + e.OK(req.GetId(), "创建成功") +} + +// Update 修改用户提现记录 +// @Summary 修改用户提现记录 +// @Description 修改用户提现记录 +// @Tags 用户提现记录 +// @Accept application/json +// @Product application/json +// @Param id path int true "id" +// @Param data body dto.MemberWithdrawalLogUpdateReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}" +// @Router /api/v1/member-withdrawal-log/{id} [put] +// @Security Bearer +func (e MemberWithdrawalLog) Update(c *gin.Context) { + req := dto.MemberWithdrawalLogUpdateReq{} + s := service.MemberWithdrawalLog{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + req.SetUpdateBy(user.GetUserId(c)) + p := actions.GetPermissionFromContext(c) + + err = s.Update(&req, p) + if err != nil { + e.Error(500, err, fmt.Sprintf("修改用户提现记录失败,\r\n失败信息 %s", err.Error())) + return + } + e.OK( req.GetId(), "修改成功") +} + +// Delete 删除用户提现记录 +// @Summary 删除用户提现记录 +// @Description 删除用户提现记录 +// @Tags 用户提现记录 +// @Param data body dto.MemberWithdrawalLogDeleteReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}" +// @Router /api/v1/member-withdrawal-log [delete] +// @Security Bearer +func (e MemberWithdrawalLog) Delete(c *gin.Context) { + s := service.MemberWithdrawalLog{} + req := dto.MemberWithdrawalLogDeleteReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + // req.SetUpdateBy(user.GetUserId(c)) + p := actions.GetPermissionFromContext(c) + + err = s.Remove(&req, p) + if err != nil { + e.Error(500, err, fmt.Sprintf("删除用户提现记录失败,\r\n失败信息 %s", err.Error())) + return + } + e.OK( req.GetId(), "删除成功") +} diff --git a/app/admin/fronted/invite_log.go b/app/admin/fronted/invite_log.go new file mode 100644 index 0000000..c049969 --- /dev/null +++ b/app/admin/fronted/invite_log.go @@ -0,0 +1,46 @@ +package fronted + +import ( + "go-admin/app/admin/service/appservice" + "go-admin/app/admin/service/common" + "go-admin/app/admin/service/dto" + + "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/sdk/api" +) + +type InviteLog struct { + api.Api +} + +// GetPage 获取InviteLog列表 +func (e InviteLog) GetPersonnalPage(c *gin.Context) { + s := appservice.InviteLog{} + req := dto.PersonnalInviteLogPageReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + datas := make([]dto.InviteLogResp, 0) + req.UserId = common.GetUserId(c) + + if req.UserId == 0 { + req.UserId = -1 + } + var count int64 + err = s.GetPage(&req, &datas, &count) + + if err != nil { + e.Error(500, err, err.Error()) + return + } + + e.PageOK(datas, int(count), req.PageIndex, req.PageSize, "success") +} diff --git a/app/admin/fronted/line_user.go b/app/admin/fronted/line_user.go index 8cc610a..e15e0c3 100644 --- a/app/admin/fronted/line_user.go +++ b/app/admin/fronted/line_user.go @@ -7,6 +7,7 @@ import ( "go-admin/app/admin/models/sysmodel" "go-admin/app/admin/service" "go-admin/app/admin/service/aduserdb" + "go-admin/app/admin/service/appservice" "go-admin/app/admin/service/common" "go-admin/app/admin/service/dto" "go-admin/common/const/rediskey" @@ -23,6 +24,7 @@ import ( "github.com/bytedance/sonic" "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/logger" "github.com/go-admin-team/go-admin-core/sdk/api" "github.com/shopspring/decimal" "gorm.io/gorm" @@ -35,11 +37,15 @@ type LineUserApi struct { // Register 用户注册 func (e LineUserApi) Register(c *gin.Context) { s := service.LineUser{} + userAppService := appservice.LineUser{} + balanceService := service.MemberBalance{} req := sysmodel.FrontedUserRegisterReq{} err := e.MakeContext(c). MakeOrm(). Bind(&req). MakeService(&s.Service). + MakeService(&userAppService.Service). + MakeService(&balanceService.Service). Errors if err != nil { e.Logger.Error(err) @@ -66,6 +72,10 @@ func (e LineUserApi) Register(c *gin.Context) { e.Error(ok, nil, sysstatuscode.GetStatusCodeDescription(c, ok)) return } + + userAppService.SetDefaultRenwal(user) + balanceService.CreateDefaultBalance(user) + resp := map[string]interface{}{ "email": req.Email, "mobile": req.Phone, @@ -579,3 +589,36 @@ func (e LineUserApi) CallBack(c *gin.Context) { e.OK(nil, "") } + +// 退出登录 +func (e LineUserApi) Logout(c *gin.Context) { + err := e.MakeContext(c). + MakeOrm(). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + userId := common.GetUserId(c) + err = authservice.Logout(userId, 1) + + if err != nil { + logger.Error("退出登录失败:", err.Error()) + e.Error(statuscode.ServerError, nil, "") + } + + e.OK(nil, "success") +} + +// 查询个人资产 +func (e LineUserApi) GetProperty(c *gin.Context) { + err := e.MakeContext(c). + MakeOrm(). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(statuscode.ServerError, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.ServerError)) + } +} diff --git a/app/admin/fronted/member_balance_log.go b/app/admin/fronted/member_balance_log.go new file mode 100644 index 0000000..76fa1a3 --- /dev/null +++ b/app/admin/fronted/member_balance_log.go @@ -0,0 +1,42 @@ +package fronted + +import ( + "go-admin/app/admin/service/appservice" + "go-admin/app/admin/service/common" + "go-admin/app/admin/service/dto" + "go-admin/common/service/sysservice/sysstatuscode" + statuscode "go-admin/common/status_code" + + "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/sdk/api" +) + +type MemberBalanceLog struct { + api.Api +} + +// 分页查询 +func (e MemberBalanceLog) GetPage(c *gin.Context) { + s := appservice.MemberBalanceLog{} + req := dto.MemberBalanceLogPageAppReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, "server error") + return + } + req.UserId = common.GetUserId(c) + data := make([]dto.MemberBalanceLogAppResp, 0) + var count int64 + code := s.GetPage(&req, &data, &count) + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + } + + e.PageOK(data, int(count), req.PageIndex, req.PageSize, "success") +} diff --git a/app/admin/fronted/member_renwal_log.go b/app/admin/fronted/member_renwal_log.go index c9fe881..5b78d62 100644 --- a/app/admin/fronted/member_renwal_log.go +++ b/app/admin/fronted/member_renwal_log.go @@ -19,14 +19,50 @@ type MemberRenwalLog struct { func (e MemberRenwalLog) GetPage(c *gin.Context) { s := appservice.MemberRenwalLog{} req := dto.MemberRenwalLogPageAppReq{} - + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, "server error") + return + } userId := common.GetUserId(c) data := make([]dto.MemberRenwalLogResp, 0) - code := s.GetPage(userId, &req, &data) + var count int64 + code := s.GetPage(userId, &req, &data, &count) if code != statuscode.OK { e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) } + e.PageOK(data, int(count), req.PageIndex, req.PageSize, "success") +} + +func (e MemberRenwalLog) Apply(c *gin.Context) { + s := appservice.MemberRenwalLog{} + req := dto.MemberRenwalCreateAppReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, "server error") + return + } + + req.UserId = common.GetUserId(c) + data := dto.MemberRenwalCreateAppResp{} + code := s.Renwal(&req, &data) + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + return + } + e.OK(data, "success") } diff --git a/app/admin/fronted/member_withdrawal_log.go b/app/admin/fronted/member_withdrawal_log.go new file mode 100644 index 0000000..3542270 --- /dev/null +++ b/app/admin/fronted/member_withdrawal_log.go @@ -0,0 +1,106 @@ +package fronted + +import ( + "go-admin/app/admin/service/appservice" + "go-admin/app/admin/service/common" + "go-admin/app/admin/service/dto" + "go-admin/common/service/sysservice/sysstatuscode" + statuscode "go-admin/common/status_code" + + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" + "github.com/go-admin-team/go-admin-core/sdk/api" +) + +type MemberWithdrawalLog struct { + api.Api +} + +// 分页查询 +func (e MemberWithdrawalLog) GetPage(c *gin.Context) { + s := appservice.MemberWithdrawalLog{} + req := dto.MemberWithdrawalLogGetPageAppReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req, binding.Form, binding.Query). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + var count int64 + var list []dto.MemberWithdrawalLogResp + + code := s.GetPage(&req, &list, &count) + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + } + + e.PageOK(list, int(count), req.PageIndex, req.PageSize, "success") +} + +// 用户提现申请 +func (e MemberWithdrawalLog) Apply(c *gin.Context) { + s := appservice.MemberWithdrawalLog{} + req := dto.MemberWithdrawalLogApplyReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + if code := req.Valid(); code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + return + } + + req.UserId = common.GetUserId(c) + code := s.Apply(&req) + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + return + } + + e.OK(nil, "success") +} + +// 用户取消提现 +func (e MemberWithdrawalLog) Cancel(c *gin.Context) { + s := appservice.MemberWithdrawalLog{} + req := dto.MemberWithdrawalLogCancelReq{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + if code := req.Valid(); code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + return + } + + userId := common.GetUserId(c) + code := s.Canceled(&req, userId) + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + return + } + + e.OK(nil, "success") +} diff --git a/app/admin/models/line_coinnetwork.go b/app/admin/models/line_coinnetwork.go index 124cff6..e9c4116 100644 --- a/app/admin/models/line_coinnetwork.go +++ b/app/admin/models/line_coinnetwork.go @@ -16,6 +16,7 @@ type LineCoinnetwork struct { UnlockTime int64 `json:"unlockTime" gorm:"type:int;comment:提现确认平均时间,单位分钟"` Fee decimal.Decimal `json:"fee" gorm:"type:decimal(32,6);comment:网络手续费(百分比)"` MinWithdrawal decimal.Decimal `json:"minWithdrawal" gorm:"type:decimal(32,6);comment:最小提现金额"` + Status int `json:"status" gorm:"type:int;comment:状态 1 启用 2 禁用"` models.ModelTime models.ControlBy } diff --git a/app/admin/models/line_user.go b/app/admin/models/line_user.go index 66e7e1a..e1e9492 100644 --- a/app/admin/models/line_user.go +++ b/app/admin/models/line_user.go @@ -39,6 +39,7 @@ type LineUser struct { Status string `json:"status" gorm:"type:varchar(30);comment:状态"` Verification string `json:"verification" gorm:"type:varchar(255);comment:验证"` LoginTime time.Time `json:"loginTime" gorm:"type:timestamp;comment:登录时间"` + ExpirationTime *time.Time `json:"expirationTime" gorm:"type:timestamp;comment:过期时间"` OpenStatus int `json:"open_status" gorm:"-"` models.ModelTime models.ControlBy diff --git a/app/admin/models/member_balance.go b/app/admin/models/member_balance.go index 964cc67..0a53119 100644 --- a/app/admin/models/member_balance.go +++ b/app/admin/models/member_balance.go @@ -9,6 +9,7 @@ import ( type MemberBalance struct { models.Model + UserId int `json:"userId" gorm:"type:bigint;comment:用户id"` TotalAmont decimal.Decimal `json:"totalAmont" gorm:"type:decimal(18,6);comment:总余额"` FreeAmount decimal.Decimal `json:"freeAmount" gorm:"type:decimal(18,6);comment:可用余额"` FrozenAmount decimal.Decimal `json:"frozenAmount" gorm:"type:decimal(18,6);comment:冻结金额"` diff --git a/app/admin/models/member_balance_log.go b/app/admin/models/member_balance_log.go index 5a30605..c74f41f 100644 --- a/app/admin/models/member_balance_log.go +++ b/app/admin/models/member_balance_log.go @@ -1,27 +1,27 @@ package models import ( - "go-admin/common/models" + "github.com/shopspring/decimal" ) type MemberBalanceLog struct { - models.Model - - UserId int `json:"userId" gorm:"type:bigint;comment:用户id"` - ChangeSource string `json:"changeSource" gorm:"type:varchar(50);comment:变更来源 (member_change_source)"` - ChangeType string `json:"changeType" gorm:"type:tinyint;comment:变更类别 1-收入 2-支出"` - Amount string `json:"amount" gorm:"type:decimal(18,6);comment:变更金额"` - BalanceBefore string `json:"balanceBefore" gorm:"type:decimal(18,6);comment:变更前余额"` - BalanceAfter string `json:"balanceAfter" gorm:"type:decimal(18,6);comment:变更后余额"` - Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"` - models.ModelTime - models.ControlBy + models.Model + + UserId int `json:"userId" gorm:"type:bigint;comment:用户id"` + ChangeSource string `json:"changeSource" gorm:"type:varchar(50);comment:变更来源 (member_change_source)"` + ChangeType int `json:"changeType" gorm:"type:tinyint;comment:变更类别 1-收入 2-支出"` + Amount decimal.Decimal `json:"amount" gorm:"type:decimal(18,6);comment:变更金额"` + BalanceBefore decimal.Decimal `json:"balanceBefore" gorm:"type:decimal(18,6);comment:变更前余额"` + BalanceAfter decimal.Decimal `json:"balanceAfter" gorm:"type:decimal(18,6);comment:变更后余额"` + Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"` + models.ModelTime + models.ControlBy } func (MemberBalanceLog) TableName() string { - return "member_balance_log" + return "member_balance_log" } func (e *MemberBalanceLog) Generate() models.ActiveRecord { @@ -31,4 +31,4 @@ func (e *MemberBalanceLog) Generate() models.ActiveRecord { func (e *MemberBalanceLog) GetId() interface{} { return e.Id -} \ No newline at end of file +} diff --git a/app/admin/models/member_renwa_log.go b/app/admin/models/member_renwa_log.go index fcc2b63..b4b20d7 100644 --- a/app/admin/models/member_renwa_log.go +++ b/app/admin/models/member_renwa_log.go @@ -1,30 +1,34 @@ package models import ( - "time" + "time" "go-admin/common/models" + "github.com/shopspring/decimal" ) type MemberRenwaLog struct { - models.Model - - RenwalId string `json:"renwalId" gorm:"type:bigint;comment:套餐id"` - RenwalName string `json:"renwalName" gorm:"type:varchar(255);comment:续期套餐名称"` - RenwalDuration string `json:"renwalDuration" gorm:"type:int;comment:续期时长(天数)"` - Status string `json:"status" gorm:"type:varchar(255);comment:订单状态(member_renwal_log_status)"` - PayableAmount string `json:"payableAmount" gorm:"type:decimal(18,6);comment:应付金额"` - ActualPaymentAmount string `json:"actualPaymentAmount" gorm:"type:decimal(18,6);comment:实付金额"` - FromAddress string `json:"fromAddress" gorm:"type:varchar(255);comment:付款地址"` - Coin string `json:"coin" gorm:"type:varchar(255);comment:代币"` - PaymentTime time.Time `json:"paymentTime" gorm:"type:datetime;comment:支付时间"` - models.ModelTime - models.ControlBy + models.Model + + RenwalId int `json:"renwalId" gorm:"type:bigint;comment:套餐id"` + UserId int `json:"userId" gorm:"type:bigint;comment:用户id"` + RenwalName string `json:"renwalName" gorm:"type:varchar(255);comment:续期套餐名称"` + RenwalDuration int `json:"renwalDuration" gorm:"type:int;comment:续期时长(天数)"` + Status string `json:"status" gorm:"type:varchar(255);comment:订单状态(member_renwal_log_status)"` + PayableAmount decimal.Decimal `json:"payableAmount" gorm:"type:decimal(18,6);comment:应付金额"` + ActualPaymentAmount decimal.Decimal `json:"actualPaymentAmount" gorm:"type:decimal(18,6);comment:实付金额"` + FromAddress string `json:"fromAddress" gorm:"type:varchar(255);comment:付款地址"` + Coin string `json:"coin" gorm:"type:varchar(255);comment:代币"` + PaymentTime *time.Time `json:"paymentTime" gorm:"type:datetime;comment:支付时间"` + Hash string `json:"hash" gorm:"type:varchar(255);comment:交易hash"` + ExpirationTime time.Time `json:"expirationTime" gorm:"type:datetime;comment:到期时间"` + models.ModelTime + models.ControlBy } func (MemberRenwaLog) TableName() string { - return "member_renwa_log" + return "member_renwa_log" } func (e *MemberRenwaLog) Generate() models.ActiveRecord { @@ -34,4 +38,4 @@ func (e *MemberRenwaLog) Generate() models.ActiveRecord { func (e *MemberRenwaLog) GetId() interface{} { return e.Id -} \ No newline at end of file +} diff --git a/app/admin/models/member_withdrawal_log.go b/app/admin/models/member_withdrawal_log.go new file mode 100644 index 0000000..3165ef5 --- /dev/null +++ b/app/admin/models/member_withdrawal_log.go @@ -0,0 +1,40 @@ +package models + +import ( + "time" + + "go-admin/common/models" + + "github.com/shopspring/decimal" +) + +type MemberWithdrawalLog struct { + models.Model + + NetworkId int `json:"networkId" gorm:"type:int;comment:网络id"` + NetworkName string `json:"networkName" gorm:"type:varchar(50);comment:网络名称"` + Coin string `json:"coin" gorm:"type:varchar(50);comment:提现币种"` + ToAddress string `json:"toAddress" gorm:"type:varchar(255);comment:提现地址"` + Hash string `json:"hash" gorm:"type:varchar(255);comment:提现hash"` + UserId int `json:"userId" gorm:"type:bigint;comment:用户id"` + Amount decimal.Decimal `json:"amount" gorm:"type:decimal(32,6);comment:提现金额(U)"` + Status string `json:"status" gorm:"type:varchar(20);comment:提现状态(member_withdrawal_status)"` + ConfirmTime *time.Time `json:"confirmTime" gorm:"type:datetime;comment:确认时间"` + Fee decimal.Decimal `json:"fee" gorm:"type:decimal(10,2);comment:手续费比例"` + Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"` + models.ModelTime + models.ControlBy +} + +func (MemberWithdrawalLog) TableName() string { + return "member_withdrawal_log" +} + +func (e *MemberWithdrawalLog) Generate() models.ActiveRecord { + o := *e + return &o +} + +func (e *MemberWithdrawalLog) GetId() interface{} { + return e.Id +} diff --git a/app/admin/router/invite_log.go b/app/admin/router/invite_log.go new file mode 100644 index 0000000..6c522d7 --- /dev/null +++ b/app/admin/router/invite_log.go @@ -0,0 +1,21 @@ +package router + +import ( + "go-admin/app/admin/fronted" + "go-admin/common/middleware" + + "github.com/gin-gonic/gin" +) + +func init() { + routerFrontedCheckRole = append(routerFrontedCheckRole, registerInviteLogFrontedRouter) +} + +// registerLineApiGroupRouter +func registerInviteLogFrontedRouter(v1 *gin.RouterGroup) { + api := fronted.InviteLog{} + r := v1.Group("/invite-log") + { + r.GET("", middleware.FrontedAuth, api.GetPersonnalPage) + } +} diff --git a/app/admin/router/line_pre_order.go b/app/admin/router/line_pre_order.go index 0dfca73..d1c759f 100644 --- a/app/admin/router/line_pre_order.go +++ b/app/admin/router/line_pre_order.go @@ -26,6 +26,7 @@ func registerLinePreOrderRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTM r.DELETE("", api.Delete) r.POST("addOrder", actions.PermissionAction(), api.AddPreOrder) //添加订单 + r.POST("position", actions.PermissionAction(), api.AddPosition) //手动加仓 r.POST("batchAddOrder", actions.PermissionAction(), api.BatchAddOrder) //批量添加订单 r.POST("quickAddPreOrder", actions.PermissionAction(), api.QuickAddPreOrder) //快捷下单 r.POST("lever", actions.PermissionAction(), api.Lever) //设置杠杆 diff --git a/app/admin/router/line_user.go b/app/admin/router/line_user.go index 35cafa0..bd02ff3 100644 --- a/app/admin/router/line_user.go +++ b/app/admin/router/line_user.go @@ -1,9 +1,10 @@ package router import ( + "go-admin/app/admin/fronted" + "github.com/gin-gonic/gin" jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" - "go-admin/app/admin/fronted" "go-admin/app/admin/apis" "go-admin/common/actions" @@ -45,6 +46,7 @@ func frontedRegisterLinUserRouter(v1 *gin.RouterGroup) { r.POST("/addApiAuth", middleware.FrontedAuth, api.AddApiKey) //用户手动添加Apikey r.POST("/updateApiAuth", middleware.FrontedAuth, api.UpdateApiKey) //用户手动修改Apikey r.POST("/opStatus", middleware.FrontedAuth, api.OpenStatus) //开启或者关闭状态 + r.DELETE("/logout", middleware.FrontedAuth, api.Logout) //退出登录 //充值 r.POST("/notify", api.Notify) //uDun回调 diff --git a/app/admin/router/member_balance_log.go b/app/admin/router/member_balance_log.go index a07ca64..6bf2a15 100644 --- a/app/admin/router/member_balance_log.go +++ b/app/admin/router/member_balance_log.go @@ -5,12 +5,14 @@ import ( jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" "go-admin/app/admin/apis" - "go-admin/common/middleware" + "go-admin/app/admin/fronted" "go-admin/common/actions" + "go-admin/common/middleware" ) func init() { routerCheckRole = append(routerCheckRole, registerMemberBalanceLogRouter) + routerFrontedCheckRole = append(routerFrontedCheckRole, registerMemberBalanceLogFrontedRouter) } // registerMemberBalanceLogRouter @@ -24,4 +26,13 @@ func registerMemberBalanceLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.Gin r.PUT("/:id", actions.PermissionAction(), api.Update) r.DELETE("", api.Delete) } -} \ No newline at end of file +} + +func registerMemberBalanceLogFrontedRouter(v1 *gin.RouterGroup) { + api := fronted.MemberBalanceLog{} + + r := v1.Group("/member-balance-log", middleware.FrontedAuth) + { + r.GET("/personal", api.GetPage) //app 个人余额明细 + } +} diff --git a/app/admin/router/member_renwa_log.go b/app/admin/router/member_renwa_log.go index b582086..10064ab 100644 --- a/app/admin/router/member_renwa_log.go +++ b/app/admin/router/member_renwa_log.go @@ -5,12 +5,14 @@ import ( jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" "go-admin/app/admin/apis" - "go-admin/common/middleware" + "go-admin/app/admin/fronted" "go-admin/common/actions" + "go-admin/common/middleware" ) func init() { routerCheckRole = append(routerCheckRole, registerMemberRenwaLogRouter) + routerFrontedCheckRole = append(routerFrontedCheckRole, registerMemberRenwaLogFrontedRouter) } // registerMemberRenwaLogRouter @@ -24,4 +26,14 @@ func registerMemberRenwaLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJW r.PUT("/:id", actions.PermissionAction(), api.Update) r.DELETE("", api.Delete) } -} \ No newline at end of file +} + +func registerMemberRenwaLogFrontedRouter(v1 *gin.RouterGroup) { + api := fronted.MemberRenwalLog{} + + f := v1.Group("/member-renwal", middleware.FrontedAuth) + { + f.GET("/list", api.GetPage) + f.POST("/apply", api.Apply) + } +} diff --git a/app/admin/router/member_withdrawal_log.go b/app/admin/router/member_withdrawal_log.go new file mode 100644 index 0000000..c5bfde8 --- /dev/null +++ b/app/admin/router/member_withdrawal_log.go @@ -0,0 +1,43 @@ +package router + +import ( + "github.com/gin-gonic/gin" + jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" + + "go-admin/app/admin/apis" + "go-admin/app/admin/fronted" + "go-admin/common/actions" + "go-admin/common/middleware" +) + +func init() { + routerCheckRole = append(routerCheckRole, registerMemberWithdrawalLogRouter) + routerFrontedCheckRole = append(routerFrontedCheckRole, registerMemberWidthdrawalLogFrontedRouter) +} + +// registerMemberWithdrawalLogRouter +func registerMemberWithdrawalLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + api := apis.MemberWithdrawalLog{} + r := v1.Group("/member-withdrawal-log").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) + { + r.GET("", actions.PermissionAction(), api.GetPage) + r.GET("/:id", actions.PermissionAction(), api.Get) + r.POST("", api.Insert) + r.PUT("/:id", actions.PermissionAction(), api.Update) + r.DELETE("", api.Delete) + } +} + +func registerMemberWidthdrawalLogFrontedRouter(v1 *gin.RouterGroup) { + api := fronted.MemberWithdrawalLog{} + + r := v1.Group("/member-withdrawal", middleware.FrontedAuth) + { + r.GET("", api.GetPage) + // r.GET("/:id", api.Get) + r.POST("", api.Apply) + r.PUT("/cancel", api.Cancel) + // r.PUT("/:id", api.Update) + // r.DELETE("", api.Delete) + } +} diff --git a/app/admin/service/appservice/invite_log.go b/app/admin/service/appservice/invite_log.go new file mode 100644 index 0000000..2eb8935 --- /dev/null +++ b/app/admin/service/appservice/invite_log.go @@ -0,0 +1,55 @@ +package appservice + +import ( + "go-admin/app/admin/models" + "go-admin/app/admin/service/dto" + cDto "go-admin/common/dto" + "time" + + "github.com/go-admin-team/go-admin-core/logger" + "github.com/go-admin-team/go-admin-core/sdk/service" +) + +type InviteLog struct { + service.Service +} + +// 分页查询 +func (e *InviteLog) GetPage(req *dto.PersonnalInviteLogPageReq, list *[]dto.InviteLogResp, count *int64) error { + var datas []models.LineUser + var childs []models.LineUser + pids := make([]int, 0) + + if err := e.Orm.Model(&models.LineUser{}).Where("pid = ?", req.UserId).Scopes(cDto.Paginate(req.GetPageSize(), req.GetPageIndex())).Find(&datas).Count(count).Error; err != nil { + return err + } + + for _, v := range datas { + pids = append(pids, v.Pid) + } + if err := e.Orm.Model(&models.LineUser{}).Where("pid in (?)", pids).Find(&childs).Error; err != nil { + logger.Error("查询子邀请失败", err) + } + + for _, v := range datas { + item := dto.InviteLogResp{ + UserId: v.Id, + NickName: v.Username, + RegisterTime: v.CreatedAt.UnixNano() / int64(time.Millisecond), + } + + for _, v2 := range childs { + if v2.Pid == v.Id { + item.Childs = append(item.Childs, dto.InviteLogResp{ + UserId: v2.Id, + NickName: v2.Nickname, + RegisterTime: v2.CreatedAt.UnixNano() / int64(time.Millisecond), + }) + } + } + + *list = append(*list, item) + } + + return nil +} diff --git a/app/admin/service/appservice/line_user.go b/app/admin/service/appservice/line_user.go new file mode 100644 index 0000000..7f2b0f8 --- /dev/null +++ b/app/admin/service/appservice/line_user.go @@ -0,0 +1,205 @@ +package appservice + +import ( + "errors" + "fmt" + "go-admin/app/admin/models" + adminservice "go-admin/app/admin/service" + "go-admin/app/admin/service/dto" + memberbalancechangesource "go-admin/common/const/dicts/member_balance_change_source" + memberrenwalconfigstatus "go-admin/common/const/dicts/member_renwal_config_status" + memberrenwallogstatus "go-admin/common/const/dicts/member_renwal_log_status" + "go-admin/common/const/rediskey" + "go-admin/common/helper" + "go-admin/pkg/utility" + "time" + + "github.com/go-admin-team/go-admin-core/logger" + "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/shopspring/decimal" + "gorm.io/gorm" +) + +type LineUser struct { + service.Service +} + +// 注册赠送默认套餐 +func (e *LineUser) SetDefaultRenwal(user *models.LineUser) error { + var defaultRenwalConfig models.MemberRenwalConfig + + if err := e.Orm.Model(&defaultRenwalConfig).Where("is_default =1 AND status =?", memberrenwalconfigstatus.ENABLE).First(&defaultRenwalConfig).Error; err != nil { + + logger.Error("没有默认续费配置 err", err) + return nil + } + + now := time.Now() + //续费时长 + if defaultRenwalConfig.DurationDay > 0 { + renwalLog := models.MemberRenwaLog{ + RenwalId: defaultRenwalConfig.Id, + RenwalName: defaultRenwalConfig.PackageName, + UserId: user.Id, + RenwalDuration: defaultRenwalConfig.DurationDay, + Status: memberrenwallogstatus.PENDING, + PayableAmount: defaultRenwalConfig.OriginalPrice, + ActualPaymentAmount: decimal.Zero, + PaymentTime: &now, + } + + err := e.Orm.Transaction(func(tx *gorm.DB) error { + expirationTime := time.Now().Add(time.Hour * 24 * time.Duration(defaultRenwalConfig.DurationDay)) + user.ExpirationTime = &expirationTime + + if err := tx.Model(&user).Update("expiration_time", expirationTime).Error; err != nil { + logger.Errorf("默认套餐修改过期时间失败 userid:%v err:%v", user.Id, err) + return err + } + + if err := tx.Create(&renwalLog).Error; err != nil { + logger.Errorf("新增续费记录失败 userid:%v err:%v", user.Id, err) + return err + } + + return nil + }) + + if err != nil { + logger.Error("续费失败 err", err) + } + } + + return nil +} + +// 处理过期账户 +func (e *LineUser) Expire() error { + err := e.Orm.Model(&models.LineUser{}).Where("expiration_time ? AND status =?", data.PayableAmount, startTime, memberrenwallogstatus.PENDING).First(&log).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + // 如果记录未找到,跳过该项 + logger.Warnf("续费记录未找到 hash:%v amount:%v", data.Hash, data.PayableAmount) + continue + } + logger.Errorf("续费记录查询失败 hash:%v amount:%v err:%v", data.Hash, data.PayableAmount, err) + continue + } + + log.Status = memberrenwallogstatus.PAID + log.PaymentTime = &now + log.FromAddress = data.FromAddress + log.Hash = data.Hash + // 查询用户信息 + user := models.LineUser{} + if err := e.Orm.Model(&user).Where("id =?", log.UserId).First(&user).Error; err != nil { + logger.Errorf("用户查询失败 hash:%v amount:%v err:%v", data.Hash, data.PayableAmount, err) + continue + } + + // 更新 ExpirationTime + if user.ExpirationTime != nil && user.ExpirationTime.After(now) { + expirationTime := user.ExpirationTime.AddDate(0, 0, log.RenwalDuration) + user.ExpirationTime = &expirationTime + } else { + expirationTime := now.AddDate(0, 0, log.RenwalDuration) + user.ExpirationTime = &expirationTime + } + + // 计算返现记录 + balanceLogs := make([]models.MemberBalanceLog, 0) + if user.Pid > 0 { + if set, ok := configs["member_invitation_rate1"]; ok { + rate1 := utility.StrToDecimal(set.ConfigValue) + if rate1.Cmp(decimal.Zero) > 0 { + balanceLogs = append(balanceLogs, calculateBalance(user.Pid, data.PayableAmount, rate1)) + } + } + } + + if user.TopReferrerId > 0 { + if set, ok := configs["member_invitation_rate2"]; ok { + rate1 := utility.StrToDecimal(set.ConfigValue) + if rate1.Cmp(decimal.Zero) > 0 { + balanceLogs = append(balanceLogs, calculateBalance(user.TopReferrerId, data.PayableAmount, rate1)) + } + } + } + + // 修改续期订单记录 + if err := e.Orm.Model(log).Save(&log).Error; err != nil { + logger.Errorf("续费更新订单失败 userid:%v hash:%v amount:%v err:%v", user.Id, data.Hash, data.PayableAmount, err) + continue + } + // 更新用户信息 + if err := e.Orm.Model(&user).Updates(user).Error; err != nil { + logger.Errorf("续费更新失败 userid:%v hash:%v amount:%v err:%v", user.Id, data.Hash, data.PayableAmount, err) + continue + } + + // 事务操作,保存返现记录及更新余额 + err := e.Orm.Transaction(func(tx *gorm.DB) error { + // 保存返现记录 + if err := e.Orm.Model(&models.MemberBalanceLog{}).Create(&balanceLogs).Error; err != nil { + logger.Errorf("续费保存返现记录失败 userid:%v hash:%v amount:%v err:%v", user.Id, data.Hash, data.PayableAmount, err) + return err + } + + // 更新用户余额 + for _, item := range balanceLogs { + if err := e.Orm.Exec("update member_balance set total_amount=total_amount+?,free_amount=free_amount +? where user_id=?", item.Amount, item.UserId).Error; err != nil { + logger.Errorf("续费更新余额失败 userid:%v 返现userid:%v hash:%v amount:%v err:%v", user.Id, item.UserId, data.Hash, data.PayableAmount, err) + return err + } + } + + return nil + }) + + // 事务失败处理 + if err != nil { + logger.Errorf("续费成功,返现失败:续费userid:%v,hash:%s,err:%v", user.Id, data.Hash, err) + continue + } + + if err := helper.DefaultRedis.SetString(hashKey, "1"); err != nil { + logger.Errorf("续费成功,写入hash缓存失败 :续费userid:%v,hash:%s,err:%v", user.Id, data.Hash, err) + } + } + + return nil +} + +// 计算返现的函数 +func calculateBalance(userId int, amount decimal.Decimal, rate decimal.Decimal) models.MemberBalanceLog { + return models.MemberBalanceLog{ + UserId: userId, + ChangeSource: memberbalancechangesource.WITH_DRAW, + ChangeType: 1, + Amount: amount.Mul(rate.Div(decimal.NewFromInt(100))).Truncate(2), + } +} diff --git a/app/admin/service/appservice/member_balance_log.go b/app/admin/service/appservice/member_balance_log.go new file mode 100644 index 0000000..1f60f5a --- /dev/null +++ b/app/admin/service/appservice/member_balance_log.go @@ -0,0 +1,44 @@ +package appservice + +import ( + "go-admin/app/admin/models" + "go-admin/app/admin/service/dto" + cDto "go-admin/common/dto" + statuscode "go-admin/common/status_code" + "time" + + "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/jinzhu/copier" +) + +type MemberBalanceLog struct { + service.Service +} + +// 分页查询个人资金记录 +func (e *MemberBalanceLog) GetPage(req *dto.MemberBalanceLogPageAppReq, list *[]dto.MemberBalanceLogAppResp, count *int64) int { + var data models.MemberBalanceLog + var datas []models.MemberBalanceLog + item := dto.MemberBalanceLogAppResp{} + + err := e.Orm.Model(&data). + Where("user_id = ?", req.UserId). + Scopes( + cDto.Paginate(req.GetPageSize(), req.GetPageIndex()), + ). + Find(&datas).Limit(-1).Offset(-1). + Count(count).Error + + if err != nil { + return statuscode.ServerError + } + + for _, v := range datas { + copier.Copy(&item, v) + + item.CreateTimeUnix = v.CreatedAt.UnixNano() / int64(time.Millisecond) + *list = append(*list, item) + } + + return statuscode.OK +} diff --git a/app/admin/service/appservice/member_renwal_log.go b/app/admin/service/appservice/member_renwal_log.go index 52111b1..5b8ab3f 100644 --- a/app/admin/service/appservice/member_renwal_log.go +++ b/app/admin/service/appservice/member_renwal_log.go @@ -1,13 +1,26 @@ package appservice import ( + "errors" + "fmt" "go-admin/app/admin/models" + adminservice "go-admin/app/admin/service" "go-admin/app/admin/service/dto" + memberrenwalconfigstatus "go-admin/common/const/dicts/member_renwal_config_status" + memberrenwallogstatus "go-admin/common/const/dicts/member_renwal_log_status" + "go-admin/common/const/rediskey" cDto "go-admin/common/dto" + "go-admin/common/helper" statuscode "go-admin/common/status_code" + "go-admin/pkg/utility" + "math/rand" + "time" + "github.com/go-admin-team/go-admin-core/logger" "github.com/go-admin-team/go-admin-core/sdk/service" "github.com/jinzhu/copier" + "github.com/shopspring/decimal" + "gorm.io/gorm" ) type MemberRenwalLog struct { @@ -15,9 +28,9 @@ type MemberRenwalLog struct { } // 分页查询续期记录 -func (e *MemberRenwalLog) GetPage(userId int, req *dto.MemberRenwalLogPageAppReq, list *[]dto.MemberRenwalLogResp) int { - var count int64 +func (e *MemberRenwalLog) GetPage(userId int, req *dto.MemberRenwalLogPageAppReq, list *[]dto.MemberRenwalLogResp, count *int64) int { var data models.MemberRenwaLog + var datas []models.MemberRenwaLog resp := dto.MemberRenwalLogResp{} err := e.Orm.Model(&data). @@ -25,18 +38,138 @@ func (e *MemberRenwalLog) GetPage(userId int, req *dto.MemberRenwalLogPageAppReq Scopes( cDto.Paginate(req.GetPageSize(), req.GetPageIndex()), ). - Find(list).Limit(-1).Offset(-1). - Count(&count).Error + Find(&datas).Limit(-1).Offset(-1). + Count(count).Error if err != nil { return statuscode.ServerError } - for _, item := range *list { + for _, item := range datas { copier.Copy(&resp, item) + if item.PaymentTime != nil { + resp.PaymentTimeUnix = item.PaymentTime.UnixNano() / int64(time.Millisecond) + } + + resp.ExpirationTimeUnix = item.ExpirationTime.UnixNano() / int64(time.Millisecond) + *list = append(*list, resp) } return statuscode.OK } + +// 续期订单 +func (e *MemberRenwalLog) Renwal(req *dto.MemberRenwalCreateAppReq, data *dto.MemberRenwalCreateAppResp) int { + var renwalConfig models.MemberRenwalConfig + renwalLog := models.MemberRenwaLog{} + now := time.Now() + configService := adminservice.SysConfig{Service: e.Service} + configDict := map[string]dto.GetSysConfigByKEYForServiceResp{} + expirationVal := 30 + var toAddress string + + configService.GetWithKeys(&[]string{"member_renwal_expiration_val", "member_receive_address"}, &configDict) + + if dict, ok := configDict["member_renwal_expiration_val"]; ok && dict.ConfigValue != "" { + expirationVal = utility.ToInt(dict.ConfigValue) + } + + if dict, ok := configDict["member_receive_address"]; !ok || dict.ConfigValue == "" { + logger.Errorf("钱包收款地址不存在") + return statuscode.ServerError + } else if dict.ConfigValue != "" { + toAddress = dict.ConfigValue + } + + if err := e.Orm.Model(&renwalConfig).Where("id =?", req.ConfigId).First(&renwalConfig).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return statuscode.DataError + } + + logger.Errorf("查询套餐详情失败,err:", err) + return statuscode.ServerError + } + + if renwalConfig.Status != memberrenwalconfigstatus.ENABLE { + return statuscode.RenwalConfigDisabled + } + + price := renwalConfig.OriginalPrice + + if renwalConfig.DiscountPrice.Cmp(decimal.Zero) > 0 { + price = renwalConfig.DiscountPrice + } + + amount, err := generateUniqueAmount(price, 3, 5, expirationVal) + + if err != nil { + logger.Errorf("生成唯一金额失败,userId:%v err:%v", req.UserId, err) + return statuscode.ServerError + } + renwalLog.RenwalId = req.ConfigId + renwalLog.UserId = req.UserId + renwalLog.RenwalName = renwalConfig.PackageName + renwalLog.RenwalDuration = renwalConfig.DurationDay + renwalLog.Status = memberrenwallogstatus.PENDING + renwalLog.ExpirationTime = now.Add(time.Minute * time.Duration(expirationVal)) + renwalLog.Coin = "USDT" + renwalLog.PayableAmount = amount + + if err := e.Orm.Model(&models.MemberRenwaLog{}).Create(&renwalLog).Error; err != nil { + logger.Errorf("创建续费记录失败,userId:%v err:%v", req.UserId, err) + return statuscode.ServerError + } + data.Amount = renwalLog.PayableAmount + data.ExpirationTimeUnix = renwalLog.ExpirationTime.UnixNano() / int64(time.Millisecond) + data.NetworkName = "TRC20" + data.ToAddress = toAddress + + return statuscode.OK +} + +// 生成唯一的金额 +// base: 基础金额 +// decimalPlaces: 小数位数 +// maxRetries: 最大尝试次数 +// expirationVal: 过期时间(分钟) +func generateUniqueAmount(base decimal.Decimal, decimalPlaces int, maxRetries int, expirationVal int) (decimal.Decimal, error) { + // 尝试生成最大次数为 maxRetries + for i := 0; i < maxRetries; i++ { + amount := GenerateRandomDecimal(base, decimalPlaces) + + // 如果没有重复,返回生成的金额 + err := helper.DefaultRedis.SetAdd(fmt.Sprintf(rediskey.OrderAmount, amount), "1", time.Duration(expirationVal)) + if err == nil { + // 插入成功,返回该金额 + return amount, nil + } + + // key 已存在,继续尝试 + if err.Error() == "key已存在" { + fmt.Println("金额已存在,重试生成...") + continue + } + // 成功,返回生成的金额 + return amount, nil + } + + // 超过最大重试次数,增加小数位数并递归 + return generateUniqueAmount(base, decimalPlaces+1, maxRetries, expirationVal) +} + +func GenerateRandomDecimal(base decimal.Decimal, decimalPlaces int) decimal.Decimal { + // 生成一个随机的小数部分,最大为 1,但小数位数不超过指定的位数 + rand.Seed(time.Now().UnixNano()) + randomFraction := rand.Float64() + + // 将随机小数调整到指定的小数位数 + randomDecimal := decimal.NewFromFloat(randomFraction).Round(int32(decimalPlaces)) + + // 将原始的 decimal 加上随机小数部分 + result := base.Add(randomDecimal) + + // 返回最终结果,确保精确到指定的小数位数 + return result.Round(int32(decimalPlaces)) +} diff --git a/app/admin/service/appservice/member_withdrawal_log.go b/app/admin/service/appservice/member_withdrawal_log.go new file mode 100644 index 0000000..cc01615 --- /dev/null +++ b/app/admin/service/appservice/member_withdrawal_log.go @@ -0,0 +1,185 @@ +package appservice + +import ( + "errors" + "go-admin/app/admin/models" + "go-admin/app/admin/service/dto" + "go-admin/pkg/utility" + "time" + + memberwithdrawallogstatus "go-admin/common/const/dicts/member_withdrawal_log_status" + cDto "go-admin/common/dto" + statuscode "go-admin/common/status_code" + + "github.com/go-admin-team/go-admin-core/logger" + "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/jinzhu/copier" + "github.com/shopspring/decimal" + "gorm.io/gorm" +) + +type MemberWithdrawalLog struct { + service.Service +} + +// 分页查询 +func (e *MemberWithdrawalLog) GetPage(req *dto.MemberWithdrawalLogGetPageAppReq, list *[]dto.MemberWithdrawalLogResp, count *int64) int { + var err error + var data models.MemberWithdrawalLog + var datas []models.MemberWithdrawalLog + userIds := make([]int, 0) + + err = e.Orm.Model(&data). + Scopes( + cDto.MakeCondition(req.GetNeedSearch()), + cDto.Paginate(req.GetPageSize(), req.GetPageIndex()), + ). + Find(&datas).Limit(-1).Offset(-1). + Count(count).Error + if err != nil { + e.Log.Errorf("MemberWithdrawalLogService GetPage error:%s \r\n", err) + return statuscode.ServerError + } + + for _, user := range datas { + if !utility.ContainsInt(userIds, user.UserId) { + userIds = append(userIds, user.UserId) + } + } + + userNames := make([]models.LineUser, 0) + e.Orm.Model(&models.LineUser{}).Where("id in (?)", userIds).Select("id,nickname").Find(&userNames) + + for _, v := range datas { + item := dto.MemberWithdrawalLogResp{} + copier.Copy(&item, &v) + + for _, user := range userNames { + if v.UserId == user.Id { + item.NickName = user.Nickname + } + } + + item.CreateTimeUnix = v.CreatedAt.UnixNano() / int64(time.Millisecond) + + if v.ConfirmTime != nil { + item.ConfirmTimeUnix = v.ConfirmTime.UnixNano() / int64(time.Millisecond) + } + + *list = append(*list, item) + } + + return statuscode.OK +} + +// 用户提现申请 +// return statuscode +func (e *MemberWithdrawalLog) Apply(req *dto.MemberWithdrawalLogApplyReq) int { + // config:=adminservice.SysConfig{} + var network models.LineCoinnetwork + + if err := e.Orm.Model(&network).Where("id =?", req.NetworkId).First(&network).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return statuscode.NetworkNotExist + } + + logger.Errorf("查询网络失败 网络id:%v err:%v", req.NetworkId, err) + return statuscode.ServerError + } + + if network.Status != 1 { + return statuscode.NetworkUnAvailable + } + + //小于最小提现金额 + if req.Amount.Cmp(network.MinWithdrawal) < 0 { + return statuscode.BelowMinimum + } + + fee := req.Amount.Mul(network.Fee.Div(decimal.NewFromInt(100))).Truncate(2) + code := statuscode.OK + log := models.MemberWithdrawalLog{ + UserId: req.UserId, + NetworkId: req.NetworkId, + NetworkName: network.NetworkName, + Amount: req.Amount, + ToAddress: req.ToAddress, + Status: memberwithdrawallogstatus.PENDING, + Fee: fee, + } + + //事务 + e.Orm.Transaction(func(tx *gorm.DB) error { + balance := models.MemberBalance{} + + if err := tx.Model(&balance).Where("user_id = ?", req.UserId).First(&balance).Error; err != nil { + code = statuscode.InsufficientFunds + return err + } + + frozenAmount := fee.Add(req.Amount) + if frozenAmount.Cmp(balance.FreeAmount) > 0 { + code = statuscode.InsufficientFunds + return errors.New("余额不足") + } + + balance.FreeAmount = balance.FreeAmount.Sub(frozenAmount) + balance.FrozenAmount = balance.FrozenAmount.Add(frozenAmount) + + if err := tx.Create(&log).Error; err != nil { + code = statuscode.ServerError + logger.Errorf("创建提现记录失败 userid:%d, err:%v", req.UserId, err) + + return err + } + + if err := tx.Model(&balance).Updates(map[string]interface{}{ + "free_amount": balance.FreeAmount, + "frozen_amount": balance.FrozenAmount, + }).Error; err != nil { + code = statuscode.ServerError + logger.Errorf("更新余额失败 userid:%v err:%v", req.UserId, err) + return err + } + + return nil + }) + + return code +} + +// 取消提现 +func (e *MemberWithdrawalLog) Canceled(req *dto.MemberWithdrawalLogCancelReq, userId int) int { + code := statuscode.OK + + e.Orm.Transaction(func(tx *gorm.DB) error { + var log models.MemberWithdrawalLog + if err := tx.Model(&log).Where("id = ? AND user_id =?", req.Id, userId).First(&log).Error; err != nil { + code = statuscode.DataError + return err + } + + if log.Status != memberwithdrawallogstatus.PENDING { + code = statuscode.CanNotCancel + return errors.New("提现记录状态错误") + } + + log.Status = memberwithdrawallogstatus.CANCELED + totalAmount := log.Amount.Add(log.Fee) + + if err := tx.Exec("UPDATE member_balance SET free_amount=free_amount+?,frozen_amount=frozen_amount-? WHERE user_id =?", totalAmount, totalAmount, log.UserId).Error; err != nil { + code = statuscode.ServerError + logger.Errorf("更新余额失败 提现订单:id userid:%v err:%v", req.Id, userId, err) + return err + } + + if err := tx.Model(&log).Update("status", log.Status).Error; err != nil { + code = statuscode.ServerError + logger.Errorf("更新提现订单状态失败 提现订单:id userid:%v err:%v", req.Id, userId, err) + return err + } + return nil + }) + + return code +} diff --git a/app/admin/service/dto/line_coinnetwork.go b/app/admin/service/dto/line_coinnetwork.go index 86dfda0..e063852 100644 --- a/app/admin/service/dto/line_coinnetwork.go +++ b/app/admin/service/dto/line_coinnetwork.go @@ -48,6 +48,7 @@ type LineCoinnetworkInsertReq struct { UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"` Fee decimal.Decimal `json:"fee" comment:"网络手续费百分比"` MinWithdrawal decimal.Decimal `json:"minWithdrawal" comment:"最小提现金额"` + Status int `json:"status" comment:"状态"` common.ControlBy } @@ -62,6 +63,7 @@ func (s *LineCoinnetworkInsertReq) Generate(model *models.LineCoinnetwork) { model.UnlockTime = s.UnlockTime model.Fee = s.Fee model.MinWithdrawal = s.MinWithdrawal + model.Status = s.Status model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 } @@ -78,6 +80,7 @@ type LineCoinnetworkUpdateReq struct { UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"` Fee decimal.Decimal `json:"fee" comment:"网络手续费百分比"` MinWithdrawal decimal.Decimal `json:"minWithdrawal" comment:"最小提现金额"` + Status int `json:"status" comment:"状态"` common.ControlBy } @@ -92,6 +95,7 @@ func (s *LineCoinnetworkUpdateReq) Generate(model *models.LineCoinnetwork) { model.UnlockTime = s.UnlockTime model.Fee = s.Fee model.MinWithdrawal = s.MinWithdrawal + model.Status = s.Status model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 } diff --git a/app/admin/service/dto/line_pre_order.go b/app/admin/service/dto/line_pre_order.go index 0d43269..a4e3801 100644 --- a/app/admin/service/dto/line_pre_order.go +++ b/app/admin/service/dto/line_pre_order.go @@ -208,6 +208,63 @@ type LineAddPreOrderReq struct { Ext []LineAddPreOrderExtReq `json:"ext" ` //拓展字段 } +type LinePreOrderAddPositionReq struct { + ExchangeType string `json:"exchangeType" vd:"len($)>0"` //交易所类型 + OrderType int `json:"orderType"` //订单类型 + Symbol string `json:"symbol"` //交易对 + ApiUserId int `json:"apiId" ` //下单用户 + Site string `json:"site" ` //购买方向 + BuyPrice decimal.Decimal `json:"buyPrice" vd:"$>0"` //购买金额 U + PricePattern string `json:"pricePattern"` //价格模式 + Price decimal.Decimal `json:"price" vd:"$>0"` //下单价百分比 + Profit decimal.Decimal `json:"profit" vd:"$>0"` //止盈价 + // StopPrice string `json:"stop_price"` //止损价 + AddPositionOrderType string `json:"addPositionOrderType" comment:"加仓订单类型 LIMIT-限价 MARKET-市价"` + PriceType string `json:"priceType"` //价格类型 + ReTakeProfitRatio decimal.Decimal `json:"reTakeProfitRatio" comment:"亏损回本止盈百分比"` + ReducePriceRatio decimal.Decimal `json:"reducePriceRatio" comment:"减仓价格百分比" ` + ReduceNumRatio decimal.Decimal `json:"reduceNumRatio" comment:"减仓数量百分比" ` + ReduceTakeProfitRatio decimal.Decimal `json:"reduceTakeProfitRatio" comment:"减仓后止盈百分比" ` + ReduceStopLossRatio decimal.Decimal `json:"reduceStopLossRatio" comment:"减仓后止损百分比"` +} + +// 校验 +func (req *LinePreOrderAddPositionReq) Valid() error { + if req.ExchangeType == "" { + return errors.New("交易所类型不能为空") + } + + if req.OrderType <= 0 || req.OrderType > 2 { + return errors.New("订单类型错误") + } + + if req.Symbol == "" { + return errors.New("交易对不能为空") + } + + if req.AddPositionOrderType == "" { + return errors.New("加仓订单类型不能为空") + } + + if req.PriceType == "" { + return errors.New("价格类型不能为空") + } + + if req.ReducePriceRatio.IsZero() { + return errors.New("主单减仓价格百分比不能为空") + } + + if req.ReduceNumRatio.IsZero() { + return errors.New("主单减仓数量百分比不能为空") + } + + if req.ReduceTakeProfitRatio.IsZero() { + return errors.New("减仓后止盈百分比不能为空") + } + + return nil +} + func (req LineAddPreOrderReq) Valid() error { if req.ReducePriceRatio.IsZero() { return errors.New("主单减仓价格百分比不能为空") diff --git a/app/admin/service/dto/line_user.go b/app/admin/service/dto/line_user.go index 24f0c9b..6422b22 100644 --- a/app/admin/service/dto/line_user.go +++ b/app/admin/service/dto/line_user.go @@ -1,12 +1,13 @@ package dto import ( - "github.com/shopspring/decimal" statuscode "go-admin/common/status_code" "go-admin/pkg/emailhelper" "go-admin/pkg/utility" "time" + "github.com/shopspring/decimal" + "go-admin/app/admin/models" "go-admin/common/dto" common "go-admin/common/models" @@ -330,3 +331,16 @@ type VtsRechargePreOrderResp struct { PriceAmount string `json:"priceAmount"` PriceCurrency string `json:"priceCurrency"` } + +type PersonnalInviteLogPageReq struct { + dto.Pagination `search:"-"` + UserId int `json:"userId" form:"userId"` +} + +type InviteLogResp struct { + Id int `json:"id"` + UserId int `json:"userId"` + RegisterTime int64 `json:"registerTime"` + NickName string `json:"nickName"` + Childs []InviteLogResp `json:"childs"` +} diff --git a/app/admin/service/dto/member_balance_log.go b/app/admin/service/dto/member_balance_log.go index d2e5923..7e1ce3c 100644 --- a/app/admin/service/dto/member_balance_log.go +++ b/app/admin/service/dto/member_balance_log.go @@ -1,34 +1,34 @@ package dto import ( - "go-admin/app/admin/models" "go-admin/common/dto" common "go-admin/common/models" + + "github.com/shopspring/decimal" ) type MemberBalanceLogGetPageReq struct { - dto.Pagination `search:"-"` - ChangeSource string `form:"changeSource" search:"type:exact;column:change_source;table:member_balance_log" comment:"变更来源 (member_change_source)"` - ChangeType string `form:"changeType" search:"type:exact;column:change_type;table:member_balance_log" comment:"变更类别 1-收入 2-支出"` - MemberBalanceLogOrder + dto.Pagination `search:"-"` + ChangeSource string `form:"changeSource" search:"type:exact;column:change_source;table:member_balance_log" comment:"变更来源 (member_change_source)"` + ChangeType string `form:"changeType" search:"type:exact;column:change_type;table:member_balance_log" comment:"变更类别 1-收入 2-支出"` + MemberBalanceLogOrder } type MemberBalanceLogOrder struct { - Id string `form:"idOrder" search:"type:order;column:id;table:member_balance_log"` - UserId string `form:"userIdOrder" search:"type:order;column:user_id;table:member_balance_log"` - ChangeSource string `form:"changeSourceOrder" search:"type:order;column:change_source;table:member_balance_log"` - ChangeType string `form:"changeTypeOrder" search:"type:order;column:change_type;table:member_balance_log"` - Amount string `form:"amountOrder" search:"type:order;column:amount;table:member_balance_log"` - BalanceBefore string `form:"balanceBeforeOrder" search:"type:order;column:balance_before;table:member_balance_log"` - BalanceAfter string `form:"balanceAfterOrder" search:"type:order;column:balance_after;table:member_balance_log"` - Remark string `form:"remarkOrder" search:"type:order;column:remark;table:member_balance_log"` - CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:member_balance_log"` - UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:member_balance_log"` - DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:member_balance_log"` - CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:member_balance_log"` - UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:member_balance_log"` - + Id string `form:"idOrder" search:"type:order;column:id;table:member_balance_log"` + UserId string `form:"userIdOrder" search:"type:order;column:user_id;table:member_balance_log"` + ChangeSource string `form:"changeSourceOrder" search:"type:order;column:change_source;table:member_balance_log"` + ChangeType string `form:"changeTypeOrder" search:"type:order;column:change_type;table:member_balance_log"` + Amount string `form:"amountOrder" search:"type:order;column:amount;table:member_balance_log"` + BalanceBefore string `form:"balanceBeforeOrder" search:"type:order;column:balance_before;table:member_balance_log"` + BalanceAfter string `form:"balanceAfterOrder" search:"type:order;column:balance_after;table:member_balance_log"` + Remark string `form:"remarkOrder" search:"type:order;column:remark;table:member_balance_log"` + CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:member_balance_log"` + UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:member_balance_log"` + DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:member_balance_log"` + CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:member_balance_log"` + UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:member_balance_log"` } func (m *MemberBalanceLogGetPageReq) GetNeedSearch() interface{} { @@ -36,29 +36,29 @@ func (m *MemberBalanceLogGetPageReq) GetNeedSearch() interface{} { } type MemberBalanceLogInsertReq struct { - Id int `json:"-" comment:"主键"` // 主键 - UserId int `json:"userId" comment:"用户id"` - ChangeSource string `json:"changeSource" comment:"变更来源 (member_change_source)"` - ChangeType string `json:"changeType" comment:"变更类别 1-收入 2-支出"` - Amount string `json:"amount" comment:"变更金额"` - BalanceBefore string `json:"balanceBefore" comment:"变更前余额"` - BalanceAfter string `json:"balanceAfter" comment:"变更后余额"` - Remark string `json:"remark" comment:"备注"` - common.ControlBy + Id int `json:"-" comment:"主键"` // 主键 + UserId int `json:"userId" comment:"用户id"` + ChangeSource string `json:"changeSource" comment:"变更来源 (member_change_source)"` + ChangeType int `json:"changeType" comment:"变更类别 1-收入 2-支出"` + Amount decimal.Decimal `json:"amount" comment:"变更金额"` + BalanceBefore decimal.Decimal `json:"balanceBefore" comment:"变更前余额"` + BalanceAfter decimal.Decimal `json:"balanceAfter" comment:"变更后余额"` + Remark string `json:"remark" comment:"备注"` + common.ControlBy } -func (s *MemberBalanceLogInsertReq) Generate(model *models.MemberBalanceLog) { - if s.Id == 0 { - model.Model = common.Model{ Id: s.Id } - } - model.UserId = s.UserId - model.ChangeSource = s.ChangeSource - model.ChangeType = s.ChangeType - model.Amount = s.Amount - model.BalanceBefore = s.BalanceBefore - model.BalanceAfter = s.BalanceAfter - model.Remark = s.Remark - model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 +func (s *MemberBalanceLogInsertReq) Generate(model *models.MemberBalanceLog) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.UserId = s.UserId + model.ChangeSource = s.ChangeSource + model.ChangeType = s.ChangeType + model.Amount = s.Amount + model.BalanceBefore = s.BalanceBefore + model.BalanceAfter = s.BalanceAfter + model.Remark = s.Remark + model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 } func (s *MemberBalanceLogInsertReq) GetId() interface{} { @@ -66,29 +66,29 @@ func (s *MemberBalanceLogInsertReq) GetId() interface{} { } type MemberBalanceLogUpdateReq struct { - Id int `uri:"id" comment:"主键"` // 主键 - UserId int `json:"userId" comment:"用户id"` - ChangeSource string `json:"changeSource" comment:"变更来源 (member_change_source)"` - ChangeType string `json:"changeType" comment:"变更类别 1-收入 2-支出"` - Amount string `json:"amount" comment:"变更金额"` - BalanceBefore string `json:"balanceBefore" comment:"变更前余额"` - BalanceAfter string `json:"balanceAfter" comment:"变更后余额"` - Remark string `json:"remark" comment:"备注"` - common.ControlBy + Id int `uri:"id" comment:"主键"` // 主键 + UserId int `json:"userId" comment:"用户id"` + ChangeSource string `json:"changeSource" comment:"变更来源 (member_change_source)"` + ChangeType int `json:"changeType" comment:"变更类别 1-收入 2-支出"` + Amount decimal.Decimal `json:"amount" comment:"变更金额"` + BalanceBefore decimal.Decimal `json:"balanceBefore" comment:"变更前余额"` + BalanceAfter decimal.Decimal `json:"balanceAfter" comment:"变更后余额"` + Remark string `json:"remark" comment:"备注"` + common.ControlBy } -func (s *MemberBalanceLogUpdateReq) Generate(model *models.MemberBalanceLog) { - if s.Id == 0 { - model.Model = common.Model{ Id: s.Id } - } - model.UserId = s.UserId - model.ChangeSource = s.ChangeSource - model.ChangeType = s.ChangeType - model.Amount = s.Amount - model.BalanceBefore = s.BalanceBefore - model.BalanceAfter = s.BalanceAfter - model.Remark = s.Remark - model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 +func (s *MemberBalanceLogUpdateReq) Generate(model *models.MemberBalanceLog) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.UserId = s.UserId + model.ChangeSource = s.ChangeSource + model.ChangeType = s.ChangeType + model.Amount = s.Amount + model.BalanceBefore = s.BalanceBefore + model.BalanceAfter = s.BalanceAfter + model.Remark = s.Remark + model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 } func (s *MemberBalanceLogUpdateReq) GetId() interface{} { @@ -97,8 +97,9 @@ func (s *MemberBalanceLogUpdateReq) GetId() interface{} { // MemberBalanceLogGetReq 功能获取请求参数 type MemberBalanceLogGetReq struct { - Id int `uri:"id"` + Id int `uri:"id"` } + func (s *MemberBalanceLogGetReq) GetId() interface{} { return s.Id } @@ -111,3 +112,22 @@ type MemberBalanceLogDeleteReq struct { func (s *MemberBalanceLogDeleteReq) GetId() interface{} { return s.Ids } + +type MemberBalanceLogPageAppReq struct { + dto.Pagination `search:"-"` + ChangeSource string `form:"changeSource" search:"type:exact;column:change_source;table:member_balance_log" comment:"变更来源 (member_change_source)"` + ChangeType string `form:"changeType" search:"type:exact;column:change_type;table:member_balance_log" comment:"变更类别 1-收入 2-支出"` + UserId int `json:"userId"` + MemberBalanceLogOrder +} + +type MemberBalanceLogAppResp struct { + Id int `json:"-" comment:"主键"` // 主键 + UserId int `json:"userId" comment:"用户id"` + UserName string `json:"userName" comment:"用户名"` + ChangeSource string `json:"changeSource" comment:"变更来源 (member_change_source)"` + ChangeType int `json:"changeType" comment:"变更类别 1-收入 2-支出"` + Amount decimal.Decimal `json:"amount" comment:"变更金额"` + Remark string `json:"remark" comment:"备注"` + CreateTimeUnix int64 `json:"createTime" comment:"创建时间"` +} diff --git a/app/admin/service/dto/member_renwa_log.go b/app/admin/service/dto/member_renwa_log.go index 2c8fa22..4d85684 100644 --- a/app/admin/service/dto/member_renwa_log.go +++ b/app/admin/service/dto/member_renwa_log.go @@ -6,6 +6,8 @@ import ( "go-admin/app/admin/models" "go-admin/common/dto" common "go-admin/common/models" + + "github.com/shopspring/decimal" ) type MemberRenwaLogGetPageReq struct { @@ -18,15 +20,16 @@ type MemberRenwalLogPageAppReq struct { } type MemberRenwalLogResp struct { - Id int `json:"id"` - RenwalName string `json:"renwalName" comment:"续期套餐名称"` - RenwalDuration string `json:"renwalDuration" comment:"续期时长(天数)"` - Status string `json:"status" comment:"订单状态(member_renwal_log_status)"` - PayableAmount string `json:"payableAmount" comment:"应付金额"` - ActualPaymentAmount string `json:"actualPaymentAmount" comment:"实付金额"` - FromAddress string `json:"fromAddress" comment:"付款地址"` - Coin string `json:"coin" comment:"代币"` - PaymentTime time.Time `json:"paymentTime" comment:"支付时间"` + Id int `json:"id"` + RenwalName string `json:"renwalName" comment:"续期套餐名称"` + RenwalDuration int `json:"renwalDuration" comment:"续期时长(天数)"` + Status string `json:"status" comment:"订单状态(member_renwal_log_status)"` + PayableAmount decimal.Decimal `json:"payableAmount" comment:"应付金额"` + ActualPaymentAmount decimal.Decimal `json:"actualPaymentAmount" comment:"实付金额"` + FromAddress string `json:"fromAddress" comment:"付款地址"` + Coin string `json:"coin" comment:"代币"` + PaymentTimeUnix int64 `json:"paymentTimeUnix" comment:"支付时间"` + ExpirationTimeUnix int64 `json:"expirationTimeUnix" comment:"过期时间"` } type MemberRenwaLogOrder struct { @@ -52,16 +55,16 @@ func (m *MemberRenwaLogGetPageReq) GetNeedSearch() interface{} { } type MemberRenwaLogInsertReq struct { - Id int `json:"-" comment:"主键"` // 主键 - RenwalId string `json:"renwalId" comment:"套餐id"` - RenwalName string `json:"renwalName" comment:"续期套餐名称"` - RenwalDuration string `json:"renwalDuration" comment:"续期时长(天数)"` - Status string `json:"status" comment:"订单状态(member_renwal_log_status)"` - PayableAmount string `json:"payableAmount" comment:"应付金额"` - ActualPaymentAmount string `json:"actualPaymentAmount" comment:"实付金额"` - FromAddress string `json:"fromAddress" comment:"付款地址"` - Coin string `json:"coin" comment:"代币"` - PaymentTime time.Time `json:"paymentTime" comment:"支付时间"` + Id int `json:"-" comment:"主键"` // 主键 + RenwalId int `json:"renwalId" comment:"套餐id"` + RenwalName string `json:"renwalName" comment:"续期套餐名称"` + RenwalDuration int `json:"renwalDuration" comment:"续期时长(天数)"` + Status string `json:"status" comment:"订单状态(member_renwal_log_status)"` + PayableAmount decimal.Decimal `json:"payableAmount" comment:"应付金额"` + ActualPaymentAmount decimal.Decimal `json:"actualPaymentAmount" comment:"实付金额"` + FromAddress string `json:"fromAddress" comment:"付款地址"` + Coin string `json:"coin" comment:"代币"` + PaymentTime time.Time `json:"paymentTime" comment:"支付时间"` common.ControlBy } @@ -77,7 +80,7 @@ func (s *MemberRenwaLogInsertReq) Generate(model *models.MemberRenwaLog) { model.ActualPaymentAmount = s.ActualPaymentAmount model.FromAddress = s.FromAddress model.Coin = s.Coin - model.PaymentTime = s.PaymentTime + // model.PaymentTime = s.PaymentTime model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 } @@ -86,16 +89,16 @@ func (s *MemberRenwaLogInsertReq) GetId() interface{} { } type MemberRenwaLogUpdateReq struct { - Id int `uri:"id" comment:"主键"` // 主键 - RenwalId string `json:"renwalId" comment:"套餐id"` - RenwalName string `json:"renwalName" comment:"续期套餐名称"` - RenwalDuration string `json:"renwalDuration" comment:"续期时长(天数)"` - Status string `json:"status" comment:"订单状态(member_renwal_log_status)"` - PayableAmount string `json:"payableAmount" comment:"应付金额"` - ActualPaymentAmount string `json:"actualPaymentAmount" comment:"实付金额"` - FromAddress string `json:"fromAddress" comment:"付款地址"` - Coin string `json:"coin" comment:"代币"` - PaymentTime time.Time `json:"paymentTime" comment:"支付时间"` + Id int `uri:"id" comment:"主键"` // 主键 + RenwalId int `json:"renwalId" comment:"套餐id"` + RenwalName string `json:"renwalName" comment:"续期套餐名称"` + RenwalDuration int `json:"renwalDuration" comment:"续期时长(天数)"` + Status string `json:"status" comment:"订单状态(member_renwal_log_status)"` + PayableAmount decimal.Decimal `json:"payableAmount" comment:"应付金额"` + ActualPaymentAmount decimal.Decimal `json:"actualPaymentAmount" comment:"实付金额"` + FromAddress string `json:"fromAddress" comment:"付款地址"` + Coin string `json:"coin" comment:"代币"` + // PaymentTime time.Time `json:"paymentTime" comment:"支付时间"` common.ControlBy } @@ -111,7 +114,7 @@ func (s *MemberRenwaLogUpdateReq) Generate(model *models.MemberRenwaLog) { model.ActualPaymentAmount = s.ActualPaymentAmount model.FromAddress = s.FromAddress model.Coin = s.Coin - model.PaymentTime = s.PaymentTime + // model.PaymentTime = s.PaymentTime model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 } @@ -136,3 +139,15 @@ type MemberRenwaLogDeleteReq struct { func (s *MemberRenwaLogDeleteReq) GetId() interface{} { return s.Ids } + +type MemberRenwalCreateAppReq struct { + ConfigId int `json:"configId"` + UserId int `json:"-"` +} + +type MemberRenwalCreateAppResp struct { + NetworkName string `json:"networkName"` //网络名称 + Amount decimal.Decimal `json:"amount"` + ToAddress string `json:"toAddress"` //收款地址 + ExpirationTimeUnix int64 `json:"expirationTimeUnix"` //过期时间 +} diff --git a/app/admin/service/dto/member_withdrawal_log.go b/app/admin/service/dto/member_withdrawal_log.go new file mode 100644 index 0000000..ad4bac4 --- /dev/null +++ b/app/admin/service/dto/member_withdrawal_log.go @@ -0,0 +1,183 @@ +package dto + +import ( + "time" + + "go-admin/app/admin/models" + "go-admin/common/dto" + common "go-admin/common/models" + statuscode "go-admin/common/status_code" + + "github.com/shopspring/decimal" +) + +type MemberWithdrawalLogGetPageReq struct { + dto.Pagination `search:"-"` + NetworkName string `form:"networkName" search:"type:contains;column:network_name;table:member_withdrawal_log" comment:"网络名称"` + Status string `form:"status" search:"type:exact;column:status;table:member_withdrawal_log" comment:"提现状态(member_withdrawal_status)"` + MemberWithdrawalLogOrder +} + +type MemberWithdrawalLogGetPageAppReq struct { + dto.Pagination `search:"-"` + NetworkName string `form:"networkName" search:"type:contains;column:network_name;table:member_withdrawal_log" comment:"网络名称"` + Status string `form:"status" search:"type:exact;column:status;table:member_withdrawal_log" comment:"提现状态(member_withdrawal_status)"` + UserId int `form:"userId" search:"type:exact;column:user_id;table:member_withdrawal_log" comment:"用户id"` + + MemberWithdrawalLogOrder +} + +func (m *MemberWithdrawalLogGetPageAppReq) GetNeedSearch() interface{} { + return *m +} + +type MemberWithdrawalLogOrder struct { + Id string `form:"idOrder" search:"type:order;column:id;table:member_withdrawal_log"` + NetworkId string `form:"networkIdOrder" search:"type:order;column:network_id;table:member_withdrawal_log"` + NetworkName string `form:"networkNameOrder" search:"type:order;column:network_name;table:member_withdrawal_log"` + UserId string `form:"userIdOrder" search:"type:order;column:user_id;table:member_withdrawal_log"` + Amount string `form:"amountOrder" search:"type:order;column:amount;table:member_withdrawal_log"` + Status string `form:"statusOrder" search:"type:order;column:status;table:member_withdrawal_log"` + ConfirmTime string `form:"confirmTimeOrder" search:"type:order;column:confirm_time;table:member_withdrawal_log"` + Fee string `form:"feeOrder" search:"type:order;column:fee;table:member_withdrawal_log"` + Remark string `form:"remarkOrder" search:"type:order;column:remark;table:member_withdrawal_log"` + CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:member_withdrawal_log"` + UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:member_withdrawal_log"` + DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:member_withdrawal_log"` + CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:member_withdrawal_log"` + UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:member_withdrawal_log"` +} + +func (m *MemberWithdrawalLogGetPageReq) GetNeedSearch() interface{} { + return *m +} + +type MemberWithdrawalLogInsertReq struct { + Id int `json:"-" comment:"主键"` // 主键 + NetworkId int `json:"networkId" comment:"网络id"` + NetworkName string `json:"networkName" comment:"网络名称"` + UserId int `json:"userId" comment:"用户id"` + Amount decimal.Decimal `json:"amount" comment:"提现金额(U)"` + Status string `json:"status" comment:"提现状态(member_withdrawal_status)"` + ConfirmTime *time.Time `json:"confirmTime" comment:"确认时间"` + Fee decimal.Decimal `json:"fee" comment:"手续费比例"` + Remark string `json:"remark" comment:"备注"` + common.ControlBy +} + +func (s *MemberWithdrawalLogInsertReq) Generate(model *models.MemberWithdrawalLog) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.NetworkId = s.NetworkId + model.NetworkName = s.NetworkName + model.UserId = s.UserId + model.Amount = s.Amount + model.Status = s.Status + model.ConfirmTime = s.ConfirmTime + model.Fee = s.Fee + model.Remark = s.Remark + model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 +} + +func (s *MemberWithdrawalLogInsertReq) GetId() interface{} { + return s.Id +} + +type MemberWithdrawalLogUpdateReq struct { + Id int `uri:"id" comment:"主键"` // 主键 + NetworkId int `json:"networkId" comment:"网络id"` + NetworkName string `json:"networkName" comment:"网络名称"` + UserId int `json:"userId" comment:"用户id"` + Amount decimal.Decimal `json:"amount" comment:"提现金额(U)"` + Status string `json:"status" comment:"提现状态(member_withdrawal_status)"` + ConfirmTime *time.Time `json:"confirmTime" comment:"确认时间"` + Fee decimal.Decimal `json:"fee" comment:"手续费比例"` + Remark string `json:"remark" comment:"备注"` + common.ControlBy +} + +func (s *MemberWithdrawalLogUpdateReq) Generate(model *models.MemberWithdrawalLog) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.NetworkId = s.NetworkId + model.NetworkName = s.NetworkName + model.UserId = s.UserId + model.Amount = s.Amount + model.Status = s.Status + model.ConfirmTime = s.ConfirmTime + model.Fee = s.Fee + model.Remark = s.Remark + model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 +} + +func (s *MemberWithdrawalLogUpdateReq) GetId() interface{} { + return s.Id +} + +// MemberWithdrawalLogGetReq 功能获取请求参数 +type MemberWithdrawalLogGetReq struct { + Id int `uri:"id"` +} + +func (s *MemberWithdrawalLogGetReq) GetId() interface{} { + return s.Id +} + +// MemberWithdrawalLogDeleteReq 功能删除请求参数 +type MemberWithdrawalLogDeleteReq struct { + Ids []int `json:"ids"` +} + +func (s *MemberWithdrawalLogDeleteReq) GetId() interface{} { + return s.Ids +} + +type MemberWithdrawalLogCancelReq struct { + Id int `json:"id"` +} + +func (s *MemberWithdrawalLogCancelReq) Valid() int { + if s.Id <= 0 { + return statuscode.ParamErr + } + + return statuscode.OK +} + +type MemberWithdrawalLogApplyReq struct { + NetworkId int `json:"networkId" comment:"网络ID"` + UserId int `json:"userId" comment:"用户ID"` + Amount decimal.Decimal `json:"amount" comment:"提现金额"` + ToAddress string `json:"toAddress" comment:"提现地址"` +} + +func (e *MemberWithdrawalLogApplyReq) Valid() int { + if e.NetworkId <= 0 { + return statuscode.ParamErr + } + + if e.Amount.Cmp(decimal.Zero) <= 0 { + return statuscode.ParamErr + } + + if e.ToAddress == "" { + return statuscode.ParamErr + } + return statuscode.OK +} + +type MemberWithdrawalLogResp struct { + Id int `json:"id"` + NetworkId int `json:"networkId"` + UserId int `json:"userId"` + NickName string `json:"nickName"` + Amount decimal.Decimal `json:"amount"` + Fee decimal.Decimal `json:"fee"` + ToAddress string `json:"toAddress"` + Hash string `json:"hash"` + Status string `json:"status"` + CreateTimeUnix int64 `json:"createTime"` + ConfirmTimeUnix int64 `json:"confirmTime"` +} diff --git a/app/admin/service/line_coinnetwork.go b/app/admin/service/line_coinnetwork.go index 852fe90..00de61e 100644 --- a/app/admin/service/line_coinnetwork.go +++ b/app/admin/service/line_coinnetwork.go @@ -64,6 +64,13 @@ func (e *LineCoinnetwork) Insert(c *dto.LineCoinnetworkInsertReq) error { var err error var data models.LineCoinnetwork c.Generate(&data) + var count int64 + e.Orm.Model(&data).Where("network_name =?").Count(&count) + + if count > 0 { + return errors.New("网络已存在") + } + err = e.Orm.Create(&data).Error if err != nil { e.Log.Errorf("LineCoinnetworkService Insert error:%s \r\n", err) @@ -76,6 +83,13 @@ func (e *LineCoinnetwork) Insert(c *dto.LineCoinnetworkInsertReq) error { func (e *LineCoinnetwork) Update(c *dto.LineCoinnetworkUpdateReq, p *actions.DataPermission) error { var err error var data = models.LineCoinnetwork{} + var count int64 + e.Orm.Model(&data).Where("network_name =? AND id !=?", c.NetworkName, c.Id).Count(&count) + + if count > 0 { + return errors.New("网络已存在") + } + e.Orm.Scopes( actions.Permission(data.TableName(), p), ).First(&data, c.GetId()) diff --git a/app/admin/service/line_pre_order.go b/app/admin/service/line_pre_order.go index 2d7a214..7f689e4 100644 --- a/app/admin/service/line_pre_order.go +++ b/app/admin/service/line_pre_order.go @@ -509,14 +509,6 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP //加仓、减仓状态 tx.Model(&models.LinePreOrderStatus{}).Create(&preOrderStatus) - // for index := range preOrderExts { - // if index == 0 { - // preOrderExts[index].OrderId = AddOrder.Id - // } - - // preOrderExts[index].MainOrderId = AddOrder.Id - // } - list := dto.PreOrderRedisList{ Id: AddOrder.Id, Symbol: AddOrder.Symbol, @@ -1749,5 +1741,165 @@ func (e *LinePreOrder) CalculateBreakEvenRatio(req *dto.CalculateBreakEevenRatio } return nil - +} + +// 手动加仓 +func (e *LinePreOrder) AddPosition(req *dto.LinePreOrderAddPositionReq) error { + lastPositionOrder := models.LinePreOrder{} + var tradeSet models2.TradeSet + + if req.OrderType == 1 { + tradeSet, _ = binanceservice.GetTradeSet(req.Symbol, 0) + } else if req.OrderType == 2 { + tradeSet, _ = binanceservice.GetTradeSet(req.Symbol, 1) + } else { + return fmt.Errorf("交易对:%s 订单类型错误", req.Symbol) + } + + if tradeSet.LastPrice == "" { + return fmt.Errorf("交易对:%s 交易对配置错误", req.Symbol) + } + + if err := e.Orm.Model(&lastPositionOrder).Where("symbol =? AND status = 6 AND site =? AND api_id =? AND symbol_type =? AND exchange_type=?", + req.Symbol, req.Site, req.ApiUserId, req.OrderType, req.ExchangeType).Error; err != nil { + logger.Errorf("交易对:%s查询已开仓订单失败", req.Symbol) + return fmt.Errorf("交易对:%s 没有已开仓的订单", req.Symbol) + } + + ext := models.LinePreOrderExt{ + MainOrderId: lastPositionOrder.Id, + TakeProfitRatio: req.Profit, + ReducePriceRatio: req.ReducePriceRatio, + ReduceNumRatio: req.ReduceNumRatio, + ReduceTakeProfitRatio: req.ReduceTakeProfitRatio, + ReduceStopLossRatio: req.ReduceStopLossRatio, + AddPositionOrderType: req.AddPositionOrderType, + AddPositionType: 2, + AddPositionVal: req.BuyPrice, + } + + addPosition := models.LinePreOrder{ + SignPrice: tradeSet.LastPrice, + Pid: lastPositionOrder.Id, + MainId: lastPositionOrder.Id, + Symbol: req.Symbol, + QuoteSymbol: tradeSet.Currency, + SignPriceU: utility.StrToDecimal(tradeSet.LastPrice), + ApiId: req.ApiUserId, + Site: req.Site, + ExchangeType: req.ExchangeType, + OrderType: 0, + OrderCategory: 3, + BuyPrice: req.BuyPrice.String(), + Status: 0, + SymbolType: req.OrderType, + MainOrderType: req.AddPositionOrderType, + ExpireTime: time.Now().Add(4), + OrderSn: utility.Int64ToString(snowflakehelper.GetOrderId()), + } + + tickerPrice := utility.StrToDecimal(tradeSet.LastPrice) + if req.PricePattern == "percentage" { + addPosition.Rate = req.Price.String() + priceRate := req.Price.Div(decimal.NewFromInt(100)) //下单价除100 =0.1 + + if strings.ToUpper(req.Site) == "BUY" { //购买方向 + //实际下单价格 + truncate := tickerPrice.Mul(decimal.NewFromInt(1).Sub(priceRate)).Truncate(int32(tradeSet.PriceDigit)) + addPosition.Price = truncate.String() + } else { + truncate := tickerPrice.Mul(decimal.NewFromInt(1).Add(priceRate)).Truncate(int32(tradeSet.PriceDigit)) + addPosition.Price = truncate.String() + } + + } else { //实际价格下单 + addPosition.Price = req.Price.Truncate(int32(tradeSet.PriceDigit)).String() + addPosition.SignPriceType = req.PricePattern + addPosition.Rate = "0" + } + if tradeSet.Currency != "USDT" { //不是U本位 + //获取币本位兑换u的价格 + ticker2 := models2.TradeSet{} + tickerVal, _ := helper.DefaultRedis.GetString(fmt.Sprintf(global.TICKER_SPOT, req.ExchangeType, strings.ToUpper(tradeSet.Coin+"USDT"))) + + if tickerVal == "" { + logger.Error("查询行情失败") + return fmt.Errorf("交易对:%s 获取u本位行情失败", req.Symbol) + } + + err := sonic.Unmarshal([]byte(tickerVal), &ticker2) + + if ticker2.LastPrice == "" { + logger.Errorf("查询行情失败 %s err:%v", strings.ToUpper(tradeSet.Coin+"USDT"), err) + return fmt.Errorf("交易对:%s 获取u本位行情 反序列化失败", req.Symbol) + } + //LTCBTC --> LTCUSDT + uTickerPrice := utility.StrToDecimal(ticker2.LastPrice) //94069 + //换算成U + //div := decimal.NewFromInt(1).Div(uTickerPrice) //0.0000106365 + //在换算成对应交易对对应的价值 + //LTCBTC --> LTCUSDT == LTCUSDT -- 100.502 + div := tickerPrice.Div(decimal.NewFromInt(1).Div(uTickerPrice)) + //计算下单数量 + addPosition.Num = req.BuyPrice.Div(div).Truncate(int32(tradeSet.AmountDigit)).String() + } else { + fromString, _ := decimal.NewFromString(addPosition.Price) + addPosition.Num = req.BuyPrice.Div(fromString).Truncate(int32(tradeSet.AmountDigit)).String() + } + //事务保存 + err := e.Orm.Transaction(func(tx *gorm.DB) error { + //添加加仓单 + if err := tx.Create(&addPosition).Error; err != nil { + return err + } + + //止盈、减仓 + orders, err := makeFuturesTakeAndReduce(&addPosition, ext, tradeSet) + + if err != nil { + logger.Error("构造加仓单止盈、减仓失败") + return err + } + + if err := e.Orm.Create(&orders).Error; err != nil { + logger.Error("保存加仓单止盈、减仓失败") + return err + } + + //处理减仓单 + for index := range orders { + //减仓单且 减仓比例大于0 小于100 就冲下止盈止损 + if orders[index].OrderType == 4 && ext.ReduceNumRatio.Cmp(decimal.Zero) > 0 && ext.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) < 0 { + reduceChildOrders, err := makeReduceTakeAndStoploss(&(orders[index]), ext, tradeSet) + + if err != nil { + logger.Error("生产加仓单止盈、减仓失败") + return err + } + + if len(reduceChildOrders) == 0 { + continue + } + + if err := e.Orm.Create(&reduceChildOrders).Error; err != nil { + logger.Error("报错减仓后止盈止损失败") + return err + } + } + } + + ext.OrderId = addPosition.Id + if err := tx.Create(&ext).Error; err != nil { + return err + } + + return nil + }) + + if err != nil { + logger.Errorf("交易对:%s 添加加仓订单失败", req.Symbol) + return fmt.Errorf("交易对:%s 添加加仓订单失败", req.Symbol) + } + + return nil } diff --git a/app/admin/service/member_balance.go b/app/admin/service/member_balance.go index 61e1bb0..1f59e3e 100644 --- a/app/admin/service/member_balance.go +++ b/app/admin/service/member_balance.go @@ -3,7 +3,7 @@ package service import ( "errors" - "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/go-admin-team/go-admin-core/sdk/service" "gorm.io/gorm" "go-admin/app/admin/models" @@ -59,9 +59,9 @@ func (e *MemberBalance) Get(d *dto.MemberBalanceGetReq, p *actions.DataPermissio // Insert 创建MemberBalance对象 func (e *MemberBalance) Insert(c *dto.MemberBalanceInsertReq) error { - var err error - var data models.MemberBalance - c.Generate(&data) + var err error + var data models.MemberBalance + c.Generate(&data) err = e.Orm.Create(&data).Error if err != nil { e.Log.Errorf("MemberBalanceService Insert error:%s \r\n", err) @@ -72,22 +72,22 @@ func (e *MemberBalance) Insert(c *dto.MemberBalanceInsertReq) error { // Update 修改MemberBalance对象 func (e *MemberBalance) Update(c *dto.MemberBalanceUpdateReq, p *actions.DataPermission) error { - var err error - var data = models.MemberBalance{} - e.Orm.Scopes( - actions.Permission(data.TableName(), p), - ).First(&data, c.GetId()) - c.Generate(&data) + var err error + var data = models.MemberBalance{} + e.Orm.Scopes( + actions.Permission(data.TableName(), p), + ).First(&data, c.GetId()) + c.Generate(&data) - db := e.Orm.Save(&data) - if err = db.Error; err != nil { - e.Log.Errorf("MemberBalanceService Save error:%s \r\n", err) - return err - } - if db.RowsAffected == 0 { - return errors.New("无权更新该数据") - } - return nil + db := e.Orm.Save(&data) + if err = db.Error; err != nil { + e.Log.Errorf("MemberBalanceService Save error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权更新该数据") + } + return nil } // Remove 删除MemberBalance @@ -99,11 +99,23 @@ func (e *MemberBalance) Remove(d *dto.MemberBalanceDeleteReq, p *actions.DataPer actions.Permission(data.TableName(), p), ).Delete(&data, d.GetId()) if err := db.Error; err != nil { - e.Log.Errorf("Service RemoveMemberBalance error:%s \r\n", err) - return err - } - if db.RowsAffected == 0 { - return errors.New("无权删除该数据") - } + e.Log.Errorf("Service RemoveMemberBalance error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权删除该数据") + } + return nil +} + +// 添加默认余额 +func (e *MemberBalance) CreateDefaultBalance(user *models.LineUser) error { + data := models.MemberBalance{ + UserId: user.Id, + } + + if err := e.Orm.Create(&data).Error; err != nil { + return err + } return nil } diff --git a/app/admin/service/member_renwa_log.go b/app/admin/service/member_renwa_log.go index 1449a4f..0087f33 100644 --- a/app/admin/service/member_renwa_log.go +++ b/app/admin/service/member_renwa_log.go @@ -3,12 +3,13 @@ package service import ( "errors" - "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/go-admin-team/go-admin-core/sdk/service" "gorm.io/gorm" "go-admin/app/admin/models" "go-admin/app/admin/service/dto" "go-admin/common/actions" + memberrenwallogstatus "go-admin/common/const/dicts/member_renwal_log_status" cDto "go-admin/common/dto" ) @@ -59,9 +60,9 @@ func (e *MemberRenwaLog) Get(d *dto.MemberRenwaLogGetReq, p *actions.DataPermiss // Insert 创建MemberRenwaLog对象 func (e *MemberRenwaLog) Insert(c *dto.MemberRenwaLogInsertReq) error { - var err error - var data models.MemberRenwaLog - c.Generate(&data) + var err error + var data models.MemberRenwaLog + c.Generate(&data) err = e.Orm.Create(&data).Error if err != nil { e.Log.Errorf("MemberRenwaLogService Insert error:%s \r\n", err) @@ -72,22 +73,22 @@ func (e *MemberRenwaLog) Insert(c *dto.MemberRenwaLogInsertReq) error { // Update 修改MemberRenwaLog对象 func (e *MemberRenwaLog) Update(c *dto.MemberRenwaLogUpdateReq, p *actions.DataPermission) error { - var err error - var data = models.MemberRenwaLog{} - e.Orm.Scopes( - actions.Permission(data.TableName(), p), - ).First(&data, c.GetId()) - c.Generate(&data) + var err error + var data = models.MemberRenwaLog{} + e.Orm.Scopes( + actions.Permission(data.TableName(), p), + ).First(&data, c.GetId()) + c.Generate(&data) - db := e.Orm.Save(&data) - if err = db.Error; err != nil { - e.Log.Errorf("MemberRenwaLogService Save error:%s \r\n", err) - return err - } - if db.RowsAffected == 0 { - return errors.New("无权更新该数据") - } - return nil + db := e.Orm.Save(&data) + if err = db.Error; err != nil { + e.Log.Errorf("MemberRenwaLogService Save error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权更新该数据") + } + return nil } // Remove 删除MemberRenwaLog @@ -99,11 +100,20 @@ func (e *MemberRenwaLog) Remove(d *dto.MemberRenwaLogDeleteReq, p *actions.DataP actions.Permission(data.TableName(), p), ).Delete(&data, d.GetId()) if err := db.Error; err != nil { - e.Log.Errorf("Service RemoveMemberRenwaLog error:%s \r\n", err) - return err - } - if db.RowsAffected == 0 { - return errors.New("无权删除该数据") - } + e.Log.Errorf("Service RemoveMemberRenwaLog error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权删除该数据") + } return nil } + +// 订单过期作废 +func (e *MemberRenwaLog) OrderExpirated() { + if err := e.Orm.Model(&models.MemberRenwaLog{}). + Where("status = ? AND expiration_time