diff --git a/app/admin/apis/line_pre_order.go b/app/admin/apis/line_pre_order.go index 6139aed..145687a 100644 --- a/app/admin/apis/line_pre_order.go +++ b/app/admin/apis/line_pre_order.go @@ -625,6 +625,10 @@ func (e LinePreOrder) CalculateBreakEevenRatio(c *gin.Context) { return } + if req.Symbol == "" { + return + } + // data := dto.CalculateBreakEvenRatioResp{} _, err = s.GenerateOrder(&req) if err != nil { diff --git a/app/admin/apis/line_symbol.go b/app/admin/apis/line_symbol.go index d0c43ae..f4ca283 100644 --- a/app/admin/apis/line_symbol.go +++ b/app/admin/apis/line_symbol.go @@ -70,6 +70,60 @@ func (e LineSymbol) GetPage(c *gin.Context) { e.PageOK(list, int(count), req.GetPageIndex(), req.GetPageSize(), "查询成功") } +// Export 导出交易对列表 +// @Summary 导出交易对列表 +// @Description 导出交易对列表 +// @Tags 交易对列表 +// @Param type query string false "类型:1=现货,2=合约" +// @Success 200 {object} response.Response "{"code": 200, "data": [...]}" +// @Router /api/v1/line-symbol-group/export [get] +func (e LineSymbol) Export(c *gin.Context) { + req := dto.LineSymbolGetPageReq{} + s := service.LineSymbol{} + 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) + err = s.ExportExcel(c, p, &req) + + if err != nil { + e.Error(500, err, fmt.Sprintf("导出交易对列表失败,\r\n失败信息 %s", err.Error())) + return + } +} + +// GetAll 获取所有交易对名 +func (e LineSymbol) GetAll(c *gin.Context) { + req := dto.LineSymbolGetListReq{} + s := service.LineSymbol{} + 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, err := s.GetAll(&req) + + if err != nil { + e.Error(500, err, err.Error()) + return + } + e.OK(datas, "查询成功") +} + // Get 获取交易对管理 // @Summary 获取交易对管理 // @Description 获取交易对管理 diff --git a/app/admin/apis/member_balance.go b/app/admin/apis/member_balance.go new file mode 100644 index 0000000..71516af --- /dev/null +++ b/app/admin/apis/member_balance.go @@ -0,0 +1,191 @@ +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 MemberBalance struct { + api.Api +} + +// GetPage 获取用户余额列表 +// @Summary 获取用户余额列表 +// @Description 获取用户余额列表 +// @Tags 用户余额 +// @Param pageSize query int false "页条数" +// @Param pageIndex query int false "页码" +// @Success 200 {object} response.Response{data=response.Page{list=[]models.MemberBalance}} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-balance [get] +// @Security Bearer +func (e MemberBalance) GetPage(c *gin.Context) { + req := dto.MemberBalanceGetPageReq{} + s := service.MemberBalance{} + 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.MemberBalance, 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.MemberBalance} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-balance/{id} [get] +// @Security Bearer +func (e MemberBalance) Get(c *gin.Context) { + req := dto.MemberBalanceGetReq{} + s := service.MemberBalance{} + 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.MemberBalance + + 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.MemberBalanceInsertReq true "data" +// @Success 200 {object} response.Response "{"code": 200, "message": "添加成功"}" +// @Router /api/v1/member-balance [post] +// @Security Bearer +func (e MemberBalance) Insert(c *gin.Context) { + req := dto.MemberBalanceInsertReq{} + s := service.MemberBalance{} + 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.MemberBalanceUpdateReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}" +// @Router /api/v1/member-balance/{id} [put] +// @Security Bearer +func (e MemberBalance) Update(c *gin.Context) { + req := dto.MemberBalanceUpdateReq{} + s := service.MemberBalance{} + 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.MemberBalanceDeleteReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}" +// @Router /api/v1/member-balance [delete] +// @Security Bearer +func (e MemberBalance) Delete(c *gin.Context) { + s := service.MemberBalance{} + req := dto.MemberBalanceDeleteReq{} + 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/apis/member_balance_log.go b/app/admin/apis/member_balance_log.go new file mode 100644 index 0000000..43c71b0 --- /dev/null +++ b/app/admin/apis/member_balance_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 MemberBalanceLog struct { + api.Api +} + +// GetPage 获取用户余额变更记录列表 +// @Summary 获取用户余额变更记录列表 +// @Description 获取用户余额变更记录列表 +// @Tags 用户余额变更记录 +// @Param changeSource query string false "变更来源 (member_change_source)" +// @Param changeType query string false "变更类别 1-收入 2-支出" +// @Param pageSize query int false "页条数" +// @Param pageIndex query int false "页码" +// @Success 200 {object} response.Response{data=response.Page{list=[]models.MemberBalanceLog}} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-balance-log [get] +// @Security Bearer +func (e MemberBalanceLog) GetPage(c *gin.Context) { + req := dto.MemberBalanceLogGetPageReq{} + s := service.MemberBalanceLog{} + 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.MemberBalanceLog, 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.MemberBalanceLog} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-balance-log/{id} [get] +// @Security Bearer +func (e MemberBalanceLog) Get(c *gin.Context) { + req := dto.MemberBalanceLogGetReq{} + s := service.MemberBalanceLog{} + 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.MemberBalanceLog + + 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.MemberBalanceLogInsertReq true "data" +// @Success 200 {object} response.Response "{"code": 200, "message": "添加成功"}" +// @Router /api/v1/member-balance-log [post] +// @Security Bearer +func (e MemberBalanceLog) Insert(c *gin.Context) { + req := dto.MemberBalanceLogInsertReq{} + s := service.MemberBalanceLog{} + 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.MemberBalanceLogUpdateReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}" +// @Router /api/v1/member-balance-log/{id} [put] +// @Security Bearer +func (e MemberBalanceLog) Update(c *gin.Context) { + req := dto.MemberBalanceLogUpdateReq{} + s := service.MemberBalanceLog{} + 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.MemberBalanceLogDeleteReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}" +// @Router /api/v1/member-balance-log [delete] +// @Security Bearer +func (e MemberBalanceLog) Delete(c *gin.Context) { + s := service.MemberBalanceLog{} + req := dto.MemberBalanceLogDeleteReq{} + 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/apis/member_renwa_log.go b/app/admin/apis/member_renwa_log.go new file mode 100644 index 0000000..31821b9 --- /dev/null +++ b/app/admin/apis/member_renwa_log.go @@ -0,0 +1,191 @@ +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 MemberRenwaLog struct { + api.Api +} + +// GetPage 获取会员续期记录列表 +// @Summary 获取会员续期记录列表 +// @Description 获取会员续期记录列表 +// @Tags 会员续期记录 +// @Param pageSize query int false "页条数" +// @Param pageIndex query int false "页码" +// @Success 200 {object} response.Response{data=response.Page{list=[]models.MemberRenwaLog}} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-renwa-log [get] +// @Security Bearer +func (e MemberRenwaLog) GetPage(c *gin.Context) { + req := dto.MemberRenwaLogGetPageReq{} + s := service.MemberRenwaLog{} + 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.MemberRenwaLog, 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.MemberRenwaLog} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-renwa-log/{id} [get] +// @Security Bearer +func (e MemberRenwaLog) Get(c *gin.Context) { + req := dto.MemberRenwaLogGetReq{} + s := service.MemberRenwaLog{} + 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.MemberRenwaLog + + 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.MemberRenwaLogInsertReq true "data" +// @Success 200 {object} response.Response "{"code": 200, "message": "添加成功"}" +// @Router /api/v1/member-renwa-log [post] +// @Security Bearer +func (e MemberRenwaLog) Insert(c *gin.Context) { + req := dto.MemberRenwaLogInsertReq{} + s := service.MemberRenwaLog{} + 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.MemberRenwaLogUpdateReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}" +// @Router /api/v1/member-renwa-log/{id} [put] +// @Security Bearer +func (e MemberRenwaLog) Update(c *gin.Context) { + req := dto.MemberRenwaLogUpdateReq{} + s := service.MemberRenwaLog{} + 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.MemberRenwaLogDeleteReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}" +// @Router /api/v1/member-renwa-log [delete] +// @Security Bearer +func (e MemberRenwaLog) Delete(c *gin.Context) { + s := service.MemberRenwaLog{} + req := dto.MemberRenwaLogDeleteReq{} + 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/apis/member_renwal_config.go b/app/admin/apis/member_renwal_config.go new file mode 100644 index 0000000..aa3e7ab --- /dev/null +++ b/app/admin/apis/member_renwal_config.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 MemberRenwalConfig struct { + api.Api +} + +// GetPage 获取会员套餐管理列表 +// @Summary 获取会员套餐管理列表 +// @Description 获取会员套餐管理列表 +// @Tags 会员套餐管理 +// @Param packageName query string false "套餐名称" +// @Param status query string false "套餐状态(字典 rewal_status)" +// @Param pageSize query int false "页条数" +// @Param pageIndex query int false "页码" +// @Success 200 {object} response.Response{data=response.Page{list=[]models.MemberRenwalConfig}} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-renwal-config [get] +// @Security Bearer +func (e MemberRenwalConfig) GetPage(c *gin.Context) { + req := dto.MemberRenwalConfigGetPageReq{} + s := service.MemberRenwalConfig{} + 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.MemberRenwalConfig, 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.MemberRenwalConfig} "{"code": 200, "data": [...]}" +// @Router /api/v1/member-renwal-config/{id} [get] +// @Security Bearer +func (e MemberRenwalConfig) Get(c *gin.Context) { + req := dto.MemberRenwalConfigGetReq{} + s := service.MemberRenwalConfig{} + 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.MemberRenwalConfig + + 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.MemberRenwalConfigInsertReq true "data" +// @Success 200 {object} response.Response "{"code": 200, "message": "添加成功"}" +// @Router /api/v1/member-renwal-config [post] +// @Security Bearer +func (e MemberRenwalConfig) Insert(c *gin.Context) { + req := dto.MemberRenwalConfigInsertReq{} + s := service.MemberRenwalConfig{} + 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.MemberRenwalConfigUpdateReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "修改成功"}" +// @Router /api/v1/member-renwal-config/{id} [put] +// @Security Bearer +func (e MemberRenwalConfig) Update(c *gin.Context) { + req := dto.MemberRenwalConfigUpdateReq{} + s := service.MemberRenwalConfig{} + 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.MemberRenwalConfigDeleteReq true "body" +// @Success 200 {object} response.Response "{"code": 200, "message": "删除成功"}" +// @Router /api/v1/member-renwal-config [delete] +// @Security Bearer +func (e MemberRenwalConfig) Delete(c *gin.Context) { + s := service.MemberRenwalConfig{} + req := dto.MemberRenwalConfigDeleteReq{} + 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/apis/sys_dict_data.go b/app/admin/apis/sys_dict_data.go index 049fe99..7a0c9c4 100644 --- a/app/admin/apis/sys_dict_data.go +++ b/app/admin/apis/sys_dict_data.go @@ -1,12 +1,13 @@ package apis import ( + "go-admin/app/admin/models" + "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" - "go-admin/app/admin/models" "go-admin/app/admin/service" "go-admin/app/admin/service/dto" @@ -216,5 +217,5 @@ func (e SysDictData) GetAll(c *gin.Context) { l = append(l, d) } - e.OK(l,"查询成功") + e.OK(l, "查询成功") } diff --git a/app/admin/fronted/line_coin_network.go b/app/admin/fronted/line_coin_network.go new file mode 100644 index 0000000..6a6d88e --- /dev/null +++ b/app/admin/fronted/line_coin_network.go @@ -0,0 +1,39 @@ +package fronted + +import ( + "go-admin/app/admin/service" + "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 LineCoinnetwork struct { + api.Api +} + +// 获取区块链网络列表 +func (e LineCoinnetwork) GetList(c *gin.Context) { + s := service.LineCoinnetwork{} + err := e.MakeContext(c). + MakeOrm(). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + + data := make([]dto.LineCoinnetworkAppResp, 0) + code := s.GetOpenList(&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_renwal_config.go b/app/admin/fronted/member_renwal_config.go new file mode 100644 index 0000000..ebc48c4 --- /dev/null +++ b/app/admin/fronted/member_renwal_config.go @@ -0,0 +1,37 @@ +package fronted + +import ( + "go-admin/app/admin/service/appservice" + statuscode "go-admin/common/status_code" + + "go-admin/common/service/sysservice/sysstatuscode" + + "github.com/gin-gonic/gin" + "github.com/go-admin-team/go-admin-core/sdk/api" +) + +type MemberRenwalConfig struct { + api.Api +} + +// 获取已激活的续费套餐 +func (e MemberRenwalConfig) GetActiveList(c *gin.Context) { + s := appservice.MemberRenwalConfigAppService{} + + err := e.MakeContext(c). + MakeOrm(). + MakeService(&s.Service). + Errors + if err != nil { + e.Logger.Error(err) + e.Error(500, err, err.Error()) + return + } + data, code := s.GetList() + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + } + + e.OK(data, "success") +} diff --git a/app/admin/fronted/member_renwal_log.go b/app/admin/fronted/member_renwal_log.go new file mode 100644 index 0000000..c9fe881 --- /dev/null +++ b/app/admin/fronted/member_renwal_log.go @@ -0,0 +1,32 @@ +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 MemberRenwalLog struct { + api.Api +} + +// 分页查询 +func (e MemberRenwalLog) GetPage(c *gin.Context) { + s := appservice.MemberRenwalLog{} + req := dto.MemberRenwalLogPageAppReq{} + + userId := common.GetUserId(c) + data := make([]dto.MemberRenwalLogResp, 0) + code := s.GetPage(userId, &req, &data) + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + } + + e.OK(data, "success") +} diff --git a/app/admin/fronted/sys_dict.go b/app/admin/fronted/sys_dict.go new file mode 100644 index 0000000..321a8e4 --- /dev/null +++ b/app/admin/fronted/sys_dict.go @@ -0,0 +1,45 @@ +package fronted + +import ( + "go-admin/app/admin/service" + "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 SysDict struct { + api.Api +} + +// 获取详情 +func (e SysDict) Get(c *gin.Context) { + +} + +// 获取字典数据列表 +func (e SysDict) GetChild(c *gin.Context) { + req := dto.SysDictChildAppReq{} + s := service.SysDictType{} + err := e.MakeContext(c). + MakeOrm(). + Bind(&req). + MakeService(&s.Service). + Errors + + if err != nil { + e.Error(500, nil, err.Error()) + } + + list := make([]dto.SysDictDataResp, 0) + + code := s.GetChild(&req, &list) + + if code != statuscode.OK { + e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) + } + + e.OK(list, "success") +} diff --git a/app/admin/models/line_coinnetwork.go b/app/admin/models/line_coinnetwork.go index 041425c..124cff6 100644 --- a/app/admin/models/line_coinnetwork.go +++ b/app/admin/models/line_coinnetwork.go @@ -2,17 +2,20 @@ package models import ( "go-admin/common/models" + + "github.com/shopspring/decimal" ) type LineCoinnetwork struct { models.Model - NetworkName string `json:"networkName" gorm:"type:varchar(255);comment:网络名称"` - TokenName string `json:"tokenName" gorm:"type:varchar(255);comment:网络token名称"` - ArrivalNum int64 `json:"arrivalNum" gorm:"type:int;comment:充值区块确认数"` - UnlockNum int64 `json:"unlockNum" gorm:"type:int;comment:提现解锁确认数"` - UnlockTime int64 `json:"unlockTime" gorm:"type:int;comment:提现确认平均时间,单位分钟"` - Fee string `json:"fee" gorm:"type:decimal(32,6);comment:网络手续费,该字段是动态的,后面会有服务定时更新该字段"` + NetworkName string `json:"networkName" gorm:"type:varchar(255);comment:网络名称"` + TokenName string `json:"tokenName" gorm:"type:varchar(255);comment:网络token名称"` + ArrivalNum int64 `json:"arrivalNum" gorm:"type:int;comment:充值区块确认数"` + UnlockNum int64 `json:"unlockNum" gorm:"type:int;comment:提现解锁确认数"` + 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:最小提现金额"` models.ModelTime models.ControlBy } diff --git a/app/admin/models/line_pre_order.go b/app/admin/models/line_pre_order.go index f790c17..4e9caab 100644 --- a/app/admin/models/line_pre_order.go +++ b/app/admin/models/line_pre_order.go @@ -9,34 +9,37 @@ import ( type LinePreOrder struct { models.Model - ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 (字典 exchange_type)"` - Pid int `json:"pid" gorm:"type:int unsigned;omitempty;comment:pid"` - MainId int `json:"mainId" gorm:"type:int;comment:主单id"` - ApiId int `json:"apiId" gorm:"type:varchar(255);omitempty;comment:api用户"` - GroupId string `json:"groupId" gorm:"type:int unsigned;omitempty;comment:交易对组id"` - Symbol string `json:"symbol" gorm:"type:varchar(255);omitempty;comment:交易对"` - QuoteSymbol string `json:"quoteSymbol" gorm:"type:varchar(255);omitempty;comment:计较货币"` - SignPrice string `json:"signPrice" gorm:"type:decimal(18,8);omitempty;comment:对标价"` - SignPriceU decimal.Decimal `json:"signPriceU" gorm:"type:decimal(18,8);omitempty;comment:交易对对标U的行情价"` - SignPriceType string `json:"signPriceType" gorm:"type:enum('new','tall','low','mixture','entrust','add');omitempty;comment:对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"` - Rate string `json:"rate" gorm:"type:decimal(18,2);omitempty;comment:下单百分比"` - Price string `json:"price" gorm:"type:decimal(18,8);omitempty;comment:触发价格"` - Num string `json:"num" gorm:"type:decimal(18,8);omitempty;comment:购买数量"` - BuyPrice string `json:"buyPrice" gorm:"type:decimal(18,8);omitempty;comment:购买金额"` - SymbolType int `json:"symbolType" gorm:"type:int;comment:交易对类型:1=现货;2=合约"` - OrderCategory int `json:"orderCategory" gorm:"type:int;comment:订单类型: 1=主单 2=对冲单 3-加仓单"` - Site string `json:"site" gorm:"type:enum('BUY','SELL');omitempty;comment:购买方向:BUY=买;SELL=卖"` - OrderSn string `json:"orderSn" gorm:"type:varchar(255);omitempty;comment:订单号"` - OrderType int `json:"orderType" gorm:"type:int;omitempty;comment:订单类型:0=主单 1=止盈 2=止损 3=平仓 4=减仓"` - Desc string `json:"desc" gorm:"type:text;omitempty;comment:订单描述"` - Status int `json:"status" gorm:"type:int;omitempty;comment:是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"` - CoverType int `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"` - ExpireTime time.Time `json:"expireTime" gorm:"comment:过期时间"` - MainOrderType string `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价(LIMIT)市价(MARKET)"` - LossAmount decimal.Decimal `json:"lossAmount" gorm:"type:decimal(18,8);comment:亏损金额(U)"` - Child []LinePreOrder `json:"child" gorm:"-"` - ApiName string `json:"api_name" gorm:"->"` - ChildNum int64 `json:"child_num" gorm:"->"` + ExchangeType string `json:"exchangeType" gorm:"type:varchar(20);comment:交易所类型 (字典 exchange_type)"` + Pid int `json:"pid" gorm:"type:int unsigned;omitempty;comment:pid"` + MainId int `json:"mainId" gorm:"type:int;comment:主单id"` + ApiId int `json:"apiId" gorm:"type:varchar(255);omitempty;comment:api用户"` + GroupId string `json:"groupId" gorm:"type:int unsigned;omitempty;comment:交易对组id"` + Symbol string `json:"symbol" gorm:"type:varchar(255);omitempty;comment:交易对"` + QuoteSymbol string `json:"quoteSymbol" gorm:"type:varchar(255);omitempty;comment:计较货币"` + SignPrice string `json:"signPrice" gorm:"type:decimal(18,8);omitempty;comment:对标价"` + SignPriceU decimal.Decimal `json:"signPriceU" gorm:"type:decimal(18,8);omitempty;comment:交易对对标U的行情价"` + SignPriceType string `json:"signPriceType" gorm:"type:enum('new','tall','low','mixture','entrust','add');omitempty;comment:对标价类型: new=最新价格;tall=24小时最高;low=24小时最低;mixture=标记价;entrust=委托实价;add=补仓"` + Rate string `json:"rate" gorm:"type:decimal(18,2);omitempty;comment:下单百分比"` + Price string `json:"price" gorm:"type:decimal(18,8);omitempty;comment:触发价格"` + Num string `json:"num" gorm:"type:decimal(18,8);omitempty;comment:购买数量"` + BuyPrice string `json:"buyPrice" gorm:"type:decimal(18,8);omitempty;comment:购买金额"` + SymbolType int `json:"symbolType" gorm:"type:int;comment:交易对类型:1=现货;2=合约"` + OrderCategory int `json:"orderCategory" gorm:"type:int;comment:订单类型: 1=主单 2=对冲单 3-加仓单"` + Site string `json:"site" gorm:"type:enum('BUY','SELL');omitempty;comment:购买方向:BUY=买;SELL=卖"` + OrderSn string `json:"orderSn" gorm:"type:varchar(255);omitempty;comment:订单号"` + OrderType int `json:"orderType" gorm:"type:int;omitempty;comment:订单类型:0=主单 1=止盈 2=止损 3=平仓 4=减仓"` + Desc string `json:"desc" gorm:"type:text;omitempty;comment:订单描述"` + Status int `json:"status" gorm:"type:int;omitempty;comment:是否被触发:0=待触发;1=已触发;2=下单失败;4=已取消;5=委托中;6=已成交;9=已平仓"` + CoverType int `json:"coverType" gorm:"type:int unsigned;omitempty;comment:对冲类型 1= 现货对合约 2=合约对合约 3 合约对现货"` + ExpireTime time.Time `json:"expireTime" gorm:"comment:过期时间"` + MainOrderType string `json:"mainOrderType" gorm:"type:enum;comment:第一笔(主单类型) 限价(LIMIT)市价(MARKET)"` + LossAmount decimal.Decimal `json:"lossAmount" gorm:"type:decimal(18,8);comment:亏损金额(U)"` + TriggerTime *time.Time `json:"triggerTime" gorm:"type:datetime;comment:触发时间"` + Child []LinePreOrder `json:"child" gorm:"-"` + ApiName string `json:"api_name" gorm:"->"` + ChildNum int64 `json:"child_num" gorm:"->"` + AddPositionStatus int `json:"add_position_status" gorm:"->"` + ReduceStatus int `json:"reduce_status" gorm:"->"` // LinePreOrder 线上预埋单\ models.ModelTime models.ControlBy diff --git a/app/admin/models/line_user.go b/app/admin/models/line_user.go index 426b3eb..66e7e1a 100644 --- a/app/admin/models/line_user.go +++ b/app/admin/models/line_user.go @@ -1,9 +1,10 @@ package models import ( - "github.com/shopspring/decimal" "time" + "github.com/shopspring/decimal" + "go-admin/common/models" ) @@ -11,7 +12,8 @@ type LineUser struct { models.Model GroupId int `json:"groupId" gorm:"type:int unsigned;comment:组别ID"` - Pid int `json:"pid" gorm:"type:int unsigned;comment:推荐人ID"` + Pid int `json:"pid" gorm:"type:int unsigned;comment:直接推荐人ID"` + TopReferrerId int `json:"topReferrerId" gorm:"type:int unsigned;comment:父级推荐人ID"` Username string `json:"username" gorm:"type:varchar(32);comment:用户名"` Nickname string `json:"nickname" gorm:"type:varchar(50);comment:昵称"` Password string `json:"password" gorm:"type:varchar(32);comment:密码"` diff --git a/app/admin/models/member_balance.go b/app/admin/models/member_balance.go new file mode 100644 index 0000000..964cc67 --- /dev/null +++ b/app/admin/models/member_balance.go @@ -0,0 +1,30 @@ +package models + +import ( + "go-admin/common/models" + + "github.com/shopspring/decimal" +) + +type MemberBalance struct { + models.Model + + 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:冻结金额"` + models.ModelTime + models.ControlBy +} + +func (MemberBalance) TableName() string { + return "member_balance" +} + +func (e *MemberBalance) Generate() models.ActiveRecord { + o := *e + return &o +} + +func (e *MemberBalance) GetId() interface{} { + return e.Id +} diff --git a/app/admin/models/member_balance_log.go b/app/admin/models/member_balance_log.go new file mode 100644 index 0000000..5a30605 --- /dev/null +++ b/app/admin/models/member_balance_log.go @@ -0,0 +1,34 @@ +package models + +import ( + + "go-admin/common/models" + +) + +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 +} + +func (MemberBalanceLog) TableName() string { + return "member_balance_log" +} + +func (e *MemberBalanceLog) Generate() models.ActiveRecord { + o := *e + return &o +} + +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 new file mode 100644 index 0000000..fcc2b63 --- /dev/null +++ b/app/admin/models/member_renwa_log.go @@ -0,0 +1,37 @@ +package models + +import ( + "time" + + "go-admin/common/models" + +) + +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 +} + +func (MemberRenwaLog) TableName() string { + return "member_renwa_log" +} + +func (e *MemberRenwaLog) Generate() models.ActiveRecord { + o := *e + return &o +} + +func (e *MemberRenwaLog) GetId() interface{} { + return e.Id +} \ No newline at end of file diff --git a/app/admin/models/member_renwal_config.go b/app/admin/models/member_renwal_config.go new file mode 100644 index 0000000..cdd8ddc --- /dev/null +++ b/app/admin/models/member_renwal_config.go @@ -0,0 +1,36 @@ +package models + +import ( + "go-admin/common/models" + + "github.com/shopspring/decimal" +) + +type MemberRenwalConfig struct { + models.Model + + PackageName string `json:"packageName" gorm:"type:varchar(255);comment:套餐名称"` + DurationDay int `json:"durationDay" gorm:"type:int;comment:续期时间(天)"` + OriginalPrice decimal.Decimal `json:"originalPrice" gorm:"type:decimal(18,6);comment:原始单价"` + DiscountPrice decimal.Decimal `json:"discountPrice" gorm:"type:decimal(18,6);comment:折扣价格 -1为未设置"` + IsDefault int `json:"isDefault" gorm:"type:int;comment:是否默认套餐 0-无 1-是 2-否"` + Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"` + Status string `json:"status" gorm:"type:varchar(255);comment:套餐状态(字典 rewal_status)"` + IsVisible int `json:"isVisible" gorm:"type:int;comment:是否显示 2-否 1-是"` + Sort int `json:"sort" gorm:"type:int;comment:排序 顺序"` + models.ModelTime + models.ControlBy +} + +func (MemberRenwalConfig) TableName() string { + return "member_renwal_config" +} + +func (e *MemberRenwalConfig) Generate() models.ActiveRecord { + o := *e + return &o +} + +func (e *MemberRenwalConfig) GetId() interface{} { + return e.Id +} diff --git a/app/admin/router/line_coinnetwork.go b/app/admin/router/line_coinnetwork.go index 391f428..f376141 100644 --- a/app/admin/router/line_coinnetwork.go +++ b/app/admin/router/line_coinnetwork.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, registerLineCoinnetworkRouter) + routerFrontedCheckRole = append(routerFrontedCheckRole, registerLineCoinnetworkFrontedRouter) } // registerLineCoinnetworkRouter @@ -24,4 +26,12 @@ func registerLineCoinnetworkRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJ r.PUT("/:id", actions.PermissionAction(), api.Update) r.DELETE("", api.Delete) } -} \ No newline at end of file +} + +func registerLineCoinnetworkFrontedRouter(v1 *gin.RouterGroup) { + api := fronted.LineCoinnetwork{} + r := v1.Group("/line-coinnetwork") + { + r.GET("/list", api.GetList) + } +} diff --git a/app/admin/router/line_pre_order.go b/app/admin/router/line_pre_order.go index afc9f68..0dfca73 100644 --- a/app/admin/router/line_pre_order.go +++ b/app/admin/router/line_pre_order.go @@ -39,6 +39,7 @@ func registerLinePreOrderRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTM r.POST("aiCoinPrice", actions.PermissionAction(), api.QueryAiCoinPrice) //获取aiCoin买入点 r.POST("/calculate", api.CalculateBreakEevenRatio) //计算亏损后止盈百分比 + } } diff --git a/app/admin/router/line_symbol.go b/app/admin/router/line_symbol.go index fef0e5c..892f14b 100644 --- a/app/admin/router/line_symbol.go +++ b/app/admin/router/line_symbol.go @@ -28,5 +28,8 @@ func registerLineSymbolRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMid r.POST("syncSpotSymbol", api.SyncSpotSymbol) //同步现货交易对 r.POST("syncFutSymbol", api.SyncFutSymbol) //同步合约交易对 r.POST("getSymbol", api.GetSymbol) //获取现货和合约都有的交易对 + r.GET("/export", api.Export) //导出交易对 + + r.GET("/all", api.GetAll) //获取所有交易对 } } diff --git a/app/admin/router/member_balance.go b/app/admin/router/member_balance.go new file mode 100644 index 0000000..3737c07 --- /dev/null +++ b/app/admin/router/member_balance.go @@ -0,0 +1,27 @@ +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/common/middleware" + "go-admin/common/actions" +) + +func init() { + routerCheckRole = append(routerCheckRole, registerMemberBalanceRouter) +} + +// registerMemberBalanceRouter +func registerMemberBalanceRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + api := apis.MemberBalance{} + r := v1.Group("/member-balance").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) + } +} \ No newline at end of file diff --git a/app/admin/router/member_balance_log.go b/app/admin/router/member_balance_log.go new file mode 100644 index 0000000..a07ca64 --- /dev/null +++ b/app/admin/router/member_balance_log.go @@ -0,0 +1,27 @@ +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/common/middleware" + "go-admin/common/actions" +) + +func init() { + routerCheckRole = append(routerCheckRole, registerMemberBalanceLogRouter) +} + +// registerMemberBalanceLogRouter +func registerMemberBalanceLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + api := apis.MemberBalanceLog{} + r := v1.Group("/member-balance-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) + } +} \ No newline at end of file diff --git a/app/admin/router/member_renwa_log.go b/app/admin/router/member_renwa_log.go new file mode 100644 index 0000000..b582086 --- /dev/null +++ b/app/admin/router/member_renwa_log.go @@ -0,0 +1,27 @@ +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/common/middleware" + "go-admin/common/actions" +) + +func init() { + routerCheckRole = append(routerCheckRole, registerMemberRenwaLogRouter) +} + +// registerMemberRenwaLogRouter +func registerMemberRenwaLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + api := apis.MemberRenwaLog{} + r := v1.Group("/member-renwa-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) + } +} \ No newline at end of file diff --git a/app/admin/router/member_renwal_config.go b/app/admin/router/member_renwal_config.go new file mode 100644 index 0000000..a14fac0 --- /dev/null +++ b/app/admin/router/member_renwal_config.go @@ -0,0 +1,37 @@ +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() { + routerFrontedCheckRole = append(routerFrontedCheckRole, registerFrontedMemberRenwalConfigRouter) + routerCheckRole = append(routerCheckRole, registerMemberRenwalConfigRouter) +} + +// registerMemberRenwalConfigRouter +func registerMemberRenwalConfigRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { + api := apis.MemberRenwalConfig{} + r := v1.Group("/member-renwal-config").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 registerFrontedMemberRenwalConfigRouter(v1 *gin.RouterGroup) { + api := fronted.MemberRenwalConfig{} + r := v1.Group("/member-renwal-config") + { + r.GET("list", api.GetActiveList) + } +} diff --git a/app/admin/router/sys_dict.go b/app/admin/router/sys_dict.go index ae9e0c4..54ec9b8 100644 --- a/app/admin/router/sys_dict.go +++ b/app/admin/router/sys_dict.go @@ -1,14 +1,17 @@ package router import ( + "go-admin/app/admin/apis" + "go-admin/app/admin/fronted" + "go-admin/common/middleware" + "github.com/gin-gonic/gin" jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" - "go-admin/app/admin/apis" - "go-admin/common/middleware" ) func init() { routerCheckRole = append(routerCheckRole, registerDictRouter) + routerNoCheckRole = append(routerNoCheckRole, registerNoCheckDictRouter) } func registerDictRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { @@ -35,3 +38,12 @@ func registerDictRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddlewar opSelect.GET("/option-select", dataApi.GetAll) } } + +func registerNoCheckDictRouter(v1 *gin.RouterGroup) { + //dictApi := apis.SysDictType{} + dataApi := fronted.SysDict{} + dicts := v1.Group("/dict") + { + dicts.GET("/child", dataApi.GetChild) + } +} diff --git a/app/admin/service/appservice/member_renwal_config.go b/app/admin/service/appservice/member_renwal_config.go new file mode 100644 index 0000000..fc21044 --- /dev/null +++ b/app/admin/service/appservice/member_renwal_config.go @@ -0,0 +1,22 @@ +package appservice + +import ( + "go-admin/app/admin/models" + memberrenwalconfigstatus "go-admin/common/const/dicts/member_renwal_config_status" + memberrenwalisvisible "go-admin/common/const/dicts/member_renwal_isvisible" + statuscode "go-admin/common/status_code" + + "github.com/go-admin-team/go-admin-core/sdk/service" +) + +type MemberRenwalConfigAppService struct { + service.Service +} + +func (e *MemberRenwalConfigAppService) GetList() ([]models.MemberRenwalConfig, int) { + result := make([]models.MemberRenwalConfig, 0) + if err := e.Orm.Model(&models.MemberRenwalConfig{}).Where(" status =? AND is_visible =?", memberrenwalconfigstatus.ENABLE, memberrenwalisvisible.IsVisibleYes).Order("sort asc").Find(&result).Error; err != nil { + return result, statuscode.ServerError + } + return result, statuscode.OK +} diff --git a/app/admin/service/appservice/member_renwal_log.go b/app/admin/service/appservice/member_renwal_log.go new file mode 100644 index 0000000..52111b1 --- /dev/null +++ b/app/admin/service/appservice/member_renwal_log.go @@ -0,0 +1,42 @@ +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" + + "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/jinzhu/copier" +) + +type MemberRenwalLog struct { + service.Service +} + +// 分页查询续期记录 +func (e *MemberRenwalLog) GetPage(userId int, req *dto.MemberRenwalLogPageAppReq, list *[]dto.MemberRenwalLogResp) int { + var count int64 + var data models.MemberRenwaLog + resp := dto.MemberRenwalLogResp{} + + err := e.Orm.Model(&data). + Where("user_id = ?", userId). + Scopes( + cDto.Paginate(req.GetPageSize(), req.GetPageIndex()), + ). + Find(list).Limit(-1).Offset(-1). + Count(&count).Error + + if err != nil { + return statuscode.ServerError + } + + for _, item := range *list { + copier.Copy(&resp, item) + + *list = append(*list, resp) + } + + return statuscode.OK +} diff --git a/app/admin/service/dto/line_coinnetwork.go b/app/admin/service/dto/line_coinnetwork.go index 4d7b8ef..86dfda0 100644 --- a/app/admin/service/dto/line_coinnetwork.go +++ b/app/admin/service/dto/line_coinnetwork.go @@ -1,59 +1,68 @@ package dto import ( - "go-admin/app/admin/models" "go-admin/common/dto" common "go-admin/common/models" + + "github.com/shopspring/decimal" ) type LineCoinnetworkGetPageReq struct { - dto.Pagination `search:"-"` - LineCoinnetworkOrder + dto.Pagination `search:"-"` + LineCoinnetworkOrder } type LineCoinnetworkOrder struct { - Id string `form:"idOrder" search:"type:order;column:id;table:line_coinnetwork"` - NetworkName string `form:"networkNameOrder" search:"type:order;column:network_name;table:line_coinnetwork"` - TokenName string `form:"tokenNameOrder" search:"type:order;column:token_name;table:line_coinnetwork"` - ArrivalNum string `form:"arrivalNumOrder" search:"type:order;column:arrival_num;table:line_coinnetwork"` - UnlockNum string `form:"unlockNumOrder" search:"type:order;column:unlock_num;table:line_coinnetwork"` - UnlockTime string `form:"unlockTimeOrder" search:"type:order;column:unlock_time;table:line_coinnetwork"` - Fee string `form:"feeOrder" search:"type:order;column:fee;table:line_coinnetwork"` - CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_coinnetwork"` - UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_coinnetwork"` - CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_coinnetwork"` - UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_coinnetwork"` - DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_coinnetwork"` - + Id string `form:"idOrder" search:"type:order;column:id;table:line_coinnetwork"` + NetworkName string `form:"networkNameOrder" search:"type:order;column:network_name;table:line_coinnetwork"` + TokenName string `form:"tokenNameOrder" search:"type:order;column:token_name;table:line_coinnetwork"` + ArrivalNum string `form:"arrivalNumOrder" search:"type:order;column:arrival_num;table:line_coinnetwork"` + UnlockNum string `form:"unlockNumOrder" search:"type:order;column:unlock_num;table:line_coinnetwork"` + UnlockTime string `form:"unlockTimeOrder" search:"type:order;column:unlock_time;table:line_coinnetwork"` + Fee string `form:"feeOrder" search:"type:order;column:fee;table:line_coinnetwork"` + CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:line_coinnetwork"` + UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:line_coinnetwork"` + CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:line_coinnetwork"` + UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:line_coinnetwork"` + DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:line_coinnetwork"` } func (m *LineCoinnetworkGetPageReq) GetNeedSearch() interface{} { return *m } -type LineCoinnetworkInsertReq struct { - Id int `json:"-" comment:"主键ID"` // 主键ID - NetworkName string `json:"networkName" comment:"网络名称"` - TokenName string `json:"tokenName" comment:"网络token名称"` - ArrivalNum int64 `json:"arrivalNum" comment:"充值区块确认数"` - UnlockNum int64 `json:"unlockNum" comment:"提现解锁确认数"` - UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"` - Fee string `json:"fee" comment:"网络手续费,该字段是动态的,后面会有服务定时更新该字段"` - common.ControlBy +type LineCoinnetworkAppResp struct { + Id int `json:"id"` + NetworkName string `json:"networkName"` + MinWithdrawal decimal.Decimal `json:"minWithdrawal"` + Fee decimal.Decimal `json:"fee"` } -func (s *LineCoinnetworkInsertReq) Generate(model *models.LineCoinnetwork) { - if s.Id == 0 { - model.Model = common.Model{ Id: s.Id } - } - model.NetworkName = s.NetworkName - model.TokenName = s.TokenName - model.ArrivalNum = s.ArrivalNum - model.UnlockNum = s.UnlockNum - model.UnlockTime = s.UnlockTime - model.Fee = s.Fee - model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 +type LineCoinnetworkInsertReq struct { + Id int `json:"-" comment:"主键ID"` // 主键ID + NetworkName string `json:"networkName" comment:"网络名称"` + TokenName string `json:"tokenName" comment:"网络token名称"` + ArrivalNum int64 `json:"arrivalNum" comment:"充值区块确认数"` + UnlockNum int64 `json:"unlockNum" comment:"提现解锁确认数"` + UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"` + Fee decimal.Decimal `json:"fee" comment:"网络手续费百分比"` + MinWithdrawal decimal.Decimal `json:"minWithdrawal" comment:"最小提现金额"` + common.ControlBy +} + +func (s *LineCoinnetworkInsertReq) Generate(model *models.LineCoinnetwork) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.NetworkName = s.NetworkName + model.TokenName = s.TokenName + model.ArrivalNum = s.ArrivalNum + model.UnlockNum = s.UnlockNum + model.UnlockTime = s.UnlockTime + model.Fee = s.Fee + model.MinWithdrawal = s.MinWithdrawal + model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 } func (s *LineCoinnetworkInsertReq) GetId() interface{} { @@ -61,27 +70,29 @@ func (s *LineCoinnetworkInsertReq) GetId() interface{} { } type LineCoinnetworkUpdateReq struct { - Id int `uri:"id" comment:"主键ID"` // 主键ID - NetworkName string `json:"networkName" comment:"网络名称"` - TokenName string `json:"tokenName" comment:"网络token名称"` - ArrivalNum int64 `json:"arrivalNum" comment:"充值区块确认数"` - UnlockNum int64 `json:"unlockNum" comment:"提现解锁确认数"` - UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"` - Fee string `json:"fee" comment:"网络手续费,该字段是动态的,后面会有服务定时更新该字段"` - common.ControlBy + Id int `uri:"id" comment:"主键ID"` // 主键ID + NetworkName string `json:"networkName" comment:"网络名称"` + TokenName string `json:"tokenName" comment:"网络token名称"` + ArrivalNum int64 `json:"arrivalNum" comment:"充值区块确认数"` + UnlockNum int64 `json:"unlockNum" comment:"提现解锁确认数"` + UnlockTime int64 `json:"unlockTime" comment:"提现确认平均时间,单位分钟"` + Fee decimal.Decimal `json:"fee" comment:"网络手续费百分比"` + MinWithdrawal decimal.Decimal `json:"minWithdrawal" comment:"最小提现金额"` + common.ControlBy } -func (s *LineCoinnetworkUpdateReq) Generate(model *models.LineCoinnetwork) { - if s.Id == 0 { - model.Model = common.Model{ Id: s.Id } - } - model.NetworkName = s.NetworkName - model.TokenName = s.TokenName - model.ArrivalNum = s.ArrivalNum - model.UnlockNum = s.UnlockNum - model.UnlockTime = s.UnlockTime - model.Fee = s.Fee - model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 +func (s *LineCoinnetworkUpdateReq) Generate(model *models.LineCoinnetwork) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.NetworkName = s.NetworkName + model.TokenName = s.TokenName + model.ArrivalNum = s.ArrivalNum + model.UnlockNum = s.UnlockNum + model.UnlockTime = s.UnlockTime + model.Fee = s.Fee + model.MinWithdrawal = s.MinWithdrawal + model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 } func (s *LineCoinnetworkUpdateReq) GetId() interface{} { @@ -90,8 +101,9 @@ func (s *LineCoinnetworkUpdateReq) GetId() interface{} { // LineCoinnetworkGetReq 功能获取请求参数 type LineCoinnetworkGetReq struct { - Id int `uri:"id"` + Id int `uri:"id"` } + func (s *LineCoinnetworkGetReq) GetId() interface{} { return s.Id } diff --git a/app/admin/service/dto/line_pre_order.go b/app/admin/service/dto/line_pre_order.go index 24324dc..0d43269 100644 --- a/app/admin/service/dto/line_pre_order.go +++ b/app/admin/service/dto/line_pre_order.go @@ -13,7 +13,8 @@ import ( type LinePreOrderGetPageReq struct { dto.Pagination `search:"-"` - ExchangeType string `json:"exchangeType" search:"type:exact;column:exchange_type;table:line_pre_order" comment:"交易所类型 字典exchange_type"` + ExchangeType string `json:"exchangeType" form:"exchangeType" search:"type:exact;column:exchange_type;table:line_pre_order" comment:"交易所类型 字典exchange_type"` + SymbolType int `json:"symbolType" form:"symbolType" search:"type:exact;column:symbol_type;table:line_pre_order"` ApiId string `form:"apiId" search:"type:exact;column:api_id;table:line_pre_order" comment:"api用户"` Symbol string `form:"symbol" search:"type:exact;column:symbol;table:line_pre_order" comment:"交易对"` QuoteSymbol string `form:"quoteSymbol" search:"type:exact;column:quote_symbol;table:line_pre_order" comment:"计较货币"` @@ -183,7 +184,7 @@ func (s *LinePreOrderDeleteReq) GetId() interface{} { type LineAddPreOrderReq struct { ExchangeType string `json:"exchange_type" vd:"len($)>0"` //交易所类型 OrderType int `json:"order_type"` //订单类型 - Symbol string `json:"symbol" vd:"len($)>0"` //交易对 + Symbol string `json:"symbol"` //交易对 ApiUserId string `json:"api_id" ` //下单用户 Site string `json:"site" ` //购买方向 BuyPrice string `json:"buy_price" vd:"$>0"` //购买金额 U @@ -341,15 +342,15 @@ func (req LineBatchAddPreOrderReq) CheckParams() error { return errors.New("加仓单下跌价格不能为空") } - if v.ReduceNumRatio.IsZero() || v.ReduceNumRatio.Cmp(decimal.Zero) > 0 { + if v.ReduceNumRatio.IsZero() || v.ReduceNumRatio.Cmp(decimal.NewFromInt(100)) > 0 { return errors.New("减仓数量不正确") } - if v.ReducePriceRatio.IsZero() || v.ReducePriceRatio.Cmp(decimal.Zero) > 0 { + if v.ReducePriceRatio.IsZero() || v.ReducePriceRatio.Cmp(decimal.NewFromInt(100)) > 0 { return errors.New("减仓下跌价格不正确") } - if v.ReduceTakeProfitRatio.IsZero() || v.ReduceTakeProfitRatio.Cmp(decimal.Zero) > 0 { + if v.ReduceTakeProfitRatio.IsZero() || v.ReduceTakeProfitRatio.Cmp(decimal.NewFromInt(100)) > 0 { return errors.New("减仓后止盈价格不正确") } } @@ -371,8 +372,8 @@ type LeverReq struct { Symbol string `json:"symbol"` Leverage int `json:"leverage"` GroupId int `json:"group_id"` - IsAll int `json:"is_all"` // 1= 全部 0=不是全部 - ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type + IsAll int `json:"is_all"` // 1= 全部 0=不是全部 + ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type } func (c LeverReq) CheckParams() error { @@ -387,11 +388,11 @@ func (c LeverReq) CheckParams() error { type MarginTypeReq struct { ApiUserIds string `json:"api_user_ids"` - Symbol string `json:"symbol"` // 交易对 - MarginType string `json:"margin_type"` //全仓 CROSSED 逐仓 ISOLATED - GroupId int `json:"group_id"` // 交易对组id - IsAll int `json:"is_all"` // 1= 全部 0=不是全部 - ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type + Symbol string `json:"symbol"` // 交易对 + MarginType string `json:"margin_type"` //全仓 CROSSED 逐仓 ISOLATED + GroupId int `json:"group_id"` // 交易对组id + IsAll int `json:"is_all"` // 1= 全部 0=不是全部 + ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type } type CancelOpenOrderReq struct { @@ -399,7 +400,7 @@ type CancelOpenOrderReq struct { Symbol string `json:"symbol"` OrderSn string `json:"order_sn"` OrderType int `json:"order_type"` - ExchangeType string `json:"exchange_type"` //交易所类型 字典exchange_type + ExchangeType string `json:"exchangeType"` //交易所类型 字典exchange_type } type GetChildOrderReq struct { diff --git a/app/admin/service/dto/line_symbol.go b/app/admin/service/dto/line_symbol.go index e055299..22a8cf5 100644 --- a/app/admin/service/dto/line_symbol.go +++ b/app/admin/service/dto/line_symbol.go @@ -17,6 +17,13 @@ type LineSymbolGetPageReq struct { LineSymbolOrder } +type LineSymbolExportResp struct { + Symbol string `json:"symbol" excel:"交易对"` + Coin string `json:"coin" excel:"基础货币"` + Currency string `json:"currency" excel:"计价货币"` + SymbolType string `json:"symbolType" excel:"交易对类型"` +} + type LineSymbolOrder struct { Id string `form:"idOrder" search:"type:order;column:id;table:line_symbol"` ApiId string `form:"apiIdOrder" search:"type:order;column:api_id;table:line_symbol"` @@ -34,6 +41,7 @@ type LineSymbolOrder struct { type LineSymbolGetListReq struct { ExchangeType string `json:"exchangeType" form:"exchangeType"` + Type string `json:"type" form:"type"` } func (req *LineSymbolGetListReq) Valid() error { diff --git a/app/admin/service/dto/line_symbol_group.go b/app/admin/service/dto/line_symbol_group.go index 45b4161..a383c69 100644 --- a/app/admin/service/dto/line_symbol_group.go +++ b/app/admin/service/dto/line_symbol_group.go @@ -4,6 +4,7 @@ import ( "go-admin/app/admin/models" "go-admin/common/dto" common "go-admin/common/models" + "strings" ) type LineSymbolGroupGetPageReq struct { @@ -46,8 +47,11 @@ func (s *LineSymbolGroupInsertReq) Generate(model *models.LineSymbolGroup) { model.Model = common.Model{Id: s.Id} } // model.ExchangeType = s.ExchangeType + model.ExchangeType = s.ExchangeType model.GroupName = s.GroupName - model.Symbol = s.Symbol + model.Symbol = strings.ReplaceAll(strings.ReplaceAll(s.Symbol, ",", ","), " ", "") + model.Symbol = strings.ReplaceAll(model.Symbol, "\r\n", ",") + model.Symbol = strings.ReplaceAll(model.Symbol, "\n", ",") model.GroupType = s.GroupType model.Type = s.Type model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 @@ -73,8 +77,11 @@ func (s *LineSymbolGroupUpdateReq) Generate(model *models.LineSymbolGroup) { } // model.ExchangeType = s.ExchangeType model.GroupName = s.GroupName - model.Symbol = s.Symbol + model.Symbol = strings.ReplaceAll(strings.ReplaceAll(s.Symbol, ",", ","), " ", "") + model.Symbol = strings.ReplaceAll(model.Symbol, "\r\n", ",") + model.Symbol = strings.ReplaceAll(model.Symbol, "\n", ",") model.GroupType = s.GroupType + model.ExchangeType = s.ExchangeType model.Type = s.Type model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 } diff --git a/app/admin/service/dto/member_balance.go b/app/admin/service/dto/member_balance.go new file mode 100644 index 0000000..a571220 --- /dev/null +++ b/app/admin/service/dto/member_balance.go @@ -0,0 +1,92 @@ +package dto + +import ( + "go-admin/app/admin/models" + "go-admin/common/dto" + common "go-admin/common/models" + + "github.com/shopspring/decimal" +) + +type MemberBalanceGetPageReq struct { + dto.Pagination `search:"-"` + MemberBalanceOrder +} + +type MemberBalanceOrder struct { + Id string `form:"idOrder" search:"type:order;column:id;table:member_balance"` + TotalAmont string `form:"totalAmontOrder" search:"type:order;column:total_amont;table:member_balance"` + FreeAmount string `form:"freeAmountOrder" search:"type:order;column:free_amount;table:member_balance"` + FrozenAmount string `form:"frozenAmountOrder" search:"type:order;column:frozen_amount;table:member_balance"` + CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:member_balance"` + UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:member_balance"` + DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:member_balance"` + CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:member_balance"` + UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:member_balance"` +} + +func (m *MemberBalanceGetPageReq) GetNeedSearch() interface{} { + return *m +} + +type MemberBalanceInsertReq struct { + Id int `json:"-" comment:"主键"` // 主键 + TotalAmont decimal.Decimal `json:"totalAmont" comment:"总余额"` + FreeAmount decimal.Decimal `json:"freeAmount" comment:"可用余额"` + FrozenAmount decimal.Decimal `json:"frozenAmount" comment:"冻结金额"` + common.ControlBy +} + +func (s *MemberBalanceInsertReq) Generate(model *models.MemberBalance) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.TotalAmont = s.TotalAmont + model.FreeAmount = s.FreeAmount + model.FrozenAmount = s.FrozenAmount + model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 +} + +func (s *MemberBalanceInsertReq) GetId() interface{} { + return s.Id +} + +type MemberBalanceUpdateReq struct { + Id int `uri:"id" comment:"主键"` // 主键 + TotalAmont decimal.Decimal `json:"totalAmont" comment:"总余额"` + FreeAmount decimal.Decimal `json:"freeAmount" comment:"可用余额"` + FrozenAmount decimal.Decimal `json:"frozenAmount" comment:"冻结金额"` + common.ControlBy +} + +func (s *MemberBalanceUpdateReq) Generate(model *models.MemberBalance) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.TotalAmont = s.TotalAmont + model.FreeAmount = s.FreeAmount + model.FrozenAmount = s.FrozenAmount + model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 +} + +func (s *MemberBalanceUpdateReq) GetId() interface{} { + return s.Id +} + +// MemberBalanceGetReq 功能获取请求参数 +type MemberBalanceGetReq struct { + Id int `uri:"id"` +} + +func (s *MemberBalanceGetReq) GetId() interface{} { + return s.Id +} + +// MemberBalanceDeleteReq 功能删除请求参数 +type MemberBalanceDeleteReq struct { + Ids []int `json:"ids"` +} + +func (s *MemberBalanceDeleteReq) GetId() interface{} { + return s.Ids +} diff --git a/app/admin/service/dto/member_balance_log.go b/app/admin/service/dto/member_balance_log.go new file mode 100644 index 0000000..d2e5923 --- /dev/null +++ b/app/admin/service/dto/member_balance_log.go @@ -0,0 +1,113 @@ +package dto + +import ( + + "go-admin/app/admin/models" + "go-admin/common/dto" + common "go-admin/common/models" +) + +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 +} + +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"` + +} + +func (m *MemberBalanceLogGetPageReq) GetNeedSearch() interface{} { + return *m +} + +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 +} + +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{} { + return s.Id +} + +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 +} + +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{} { + return s.Id +} + +// MemberBalanceLogGetReq 功能获取请求参数 +type MemberBalanceLogGetReq struct { + Id int `uri:"id"` +} +func (s *MemberBalanceLogGetReq) GetId() interface{} { + return s.Id +} + +// MemberBalanceLogDeleteReq 功能删除请求参数 +type MemberBalanceLogDeleteReq struct { + Ids []int `json:"ids"` +} + +func (s *MemberBalanceLogDeleteReq) GetId() interface{} { + return s.Ids +} diff --git a/app/admin/service/dto/member_renwa_log.go b/app/admin/service/dto/member_renwa_log.go new file mode 100644 index 0000000..2c8fa22 --- /dev/null +++ b/app/admin/service/dto/member_renwa_log.go @@ -0,0 +1,138 @@ +package dto + +import ( + "time" + + "go-admin/app/admin/models" + "go-admin/common/dto" + common "go-admin/common/models" +) + +type MemberRenwaLogGetPageReq struct { + dto.Pagination `search:"-"` + MemberRenwaLogOrder +} + +type MemberRenwalLogPageAppReq struct { + dto.Pagination `search:"-"` +} + +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:"支付时间"` +} + +type MemberRenwaLogOrder struct { + Id string `form:"idOrder" search:"type:order;column:id;table:member_renwa_log"` + RenwalId string `form:"renwalIdOrder" search:"type:order;column:renwal_id;table:member_renwa_log"` + RenwalName string `form:"renwalNameOrder" search:"type:order;column:renwal_name;table:member_renwa_log"` + RenwalDuration string `form:"renwalDurationOrder" search:"type:order;column:renwal_duration;table:member_renwa_log"` + Status string `form:"statusOrder" search:"type:order;column:status;table:member_renwa_log"` + PayableAmount string `form:"payableAmountOrder" search:"type:order;column:payable_amount;table:member_renwa_log"` + ActualPaymentAmount string `form:"actualPaymentAmountOrder" search:"type:order;column:actual_payment_amount;table:member_renwa_log"` + FromAddress string `form:"fromAddressOrder" search:"type:order;column:from_address;table:member_renwa_log"` + Coin string `form:"coinOrder" search:"type:order;column:coin;table:member_renwa_log"` + PaymentTime string `form:"paymentTimeOrder" search:"type:order;column:payment_time;table:member_renwa_log"` + CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:member_renwa_log"` + UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:member_renwa_log"` + DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:member_renwa_log"` + CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:member_renwa_log"` + UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:member_renwa_log"` +} + +func (m *MemberRenwaLogGetPageReq) GetNeedSearch() interface{} { + return *m +} + +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:"支付时间"` + common.ControlBy +} + +func (s *MemberRenwaLogInsertReq) Generate(model *models.MemberRenwaLog) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.RenwalId = s.RenwalId + model.RenwalName = s.RenwalName + model.RenwalDuration = s.RenwalDuration + model.Status = s.Status + model.PayableAmount = s.PayableAmount + model.ActualPaymentAmount = s.ActualPaymentAmount + model.FromAddress = s.FromAddress + model.Coin = s.Coin + model.PaymentTime = s.PaymentTime + model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 +} + +func (s *MemberRenwaLogInsertReq) GetId() interface{} { + return s.Id +} + +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:"支付时间"` + common.ControlBy +} + +func (s *MemberRenwaLogUpdateReq) Generate(model *models.MemberRenwaLog) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.RenwalId = s.RenwalId + model.RenwalName = s.RenwalName + model.RenwalDuration = s.RenwalDuration + model.Status = s.Status + model.PayableAmount = s.PayableAmount + model.ActualPaymentAmount = s.ActualPaymentAmount + model.FromAddress = s.FromAddress + model.Coin = s.Coin + model.PaymentTime = s.PaymentTime + model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 +} + +func (s *MemberRenwaLogUpdateReq) GetId() interface{} { + return s.Id +} + +// MemberRenwaLogGetReq 功能获取请求参数 +type MemberRenwaLogGetReq struct { + Id int `uri:"id"` +} + +func (s *MemberRenwaLogGetReq) GetId() interface{} { + return s.Id +} + +// MemberRenwaLogDeleteReq 功能删除请求参数 +type MemberRenwaLogDeleteReq struct { + Ids []int `json:"ids"` +} + +func (s *MemberRenwaLogDeleteReq) GetId() interface{} { + return s.Ids +} diff --git a/app/admin/service/dto/member_renwal_config.go b/app/admin/service/dto/member_renwal_config.go new file mode 100644 index 0000000..0ca8704 --- /dev/null +++ b/app/admin/service/dto/member_renwal_config.go @@ -0,0 +1,132 @@ +package dto + +import ( + "go-admin/app/admin/models" + "go-admin/common/dto" + common "go-admin/common/models" + + "github.com/shopspring/decimal" +) + +type MemberRenwalConfigGetPageReq struct { + dto.Pagination `search:"-"` + PackageName string `form:"packageName" search:"type:contains;column:package_name;table:member_renwal_config" comment:"套餐名称"` + Status string `form:"status" search:"type:exact;column:status;table:member_renwal_config" comment:"套餐状态(字典 rewal_status)"` + MemberRenwalConfigOrder +} + +type MemberRenwalConfigOrder struct { + Id string `form:"idOrder" search:"type:order;column:id;table:member_renwal_config"` + Sort string `form:"sortOrder" search:"type:order;column:sort;table:member_renwal_config"` + PackageName string `form:"packageNameOrder" search:"type:order;column:package_name;table:member_renwal_config"` + DurationDay string `form:"durationDayOrder" search:"type:order;column:duration_day;table:member_renwal_config"` + OriginalPrice string `form:"originalPriceOrder" search:"type:order;column:original_price;table:member_renwal_config"` + DiscountPrice string `form:"discountPriceOrder" search:"type:order;column:discount_price;table:member_renwal_config"` + IsDefault string `form:"isDefaultOrder" search:"type:order;column:is_default;table:member_renwal_config"` + Status string `form:"statusOrder" search:"type:order;column:status;table:member_renwal_config"` + CreatedAt string `form:"createdAtOrder" search:"type:order;column:created_at;table:member_renwal_config"` + UpdatedAt string `form:"updatedAtOrder" search:"type:order;column:updated_at;table:member_renwal_config"` + DeletedAt string `form:"deletedAtOrder" search:"type:order;column:deleted_at;table:member_renwal_config"` + CreateBy string `form:"createByOrder" search:"type:order;column:create_by;table:member_renwal_config"` + UpdateBy string `form:"updateByOrder" search:"type:order;column:update_by;table:member_renwal_config"` +} + +func (m *MemberRenwalConfigGetPageReq) GetNeedSearch() interface{} { + return *m +} + +type MemberRenwalConfigInsertReq struct { + Id int `json:"-" comment:"主键"` // 主键 + PackageName string `json:"packageName" comment:"套餐名称"` + DurationDay int `json:"durationDay" comment:"续期时间(天)"` + OriginalPrice decimal.Decimal `json:"originalPrice" comment:"原始单价"` + DiscountPrice *decimal.Decimal `json:"discountPrice" comment:"折扣价格 -1为未设置"` + IsDefault int `json:"isDefault" comment:"是否默认套餐 0-无 1-是 2-否"` + Remark string `json:"remark" comment:"备注"` + Status string `json:"status" comment:"套餐状态(字典 rewal_status)"` + IsVisible int `json:"isVisible" comment:"是否可见 2-不可见 1-可见"` + Sort int `json:"sort" comment:"排序"` + common.ControlBy +} + +func (s *MemberRenwalConfigInsertReq) Generate(model *models.MemberRenwalConfig) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.PackageName = s.PackageName + model.DurationDay = s.DurationDay + model.OriginalPrice = s.OriginalPrice + + if s.DiscountPrice == nil { + model.DiscountPrice = decimal.NewFromInt(-1) + } else { + model.DiscountPrice = *s.DiscountPrice + } + model.IsDefault = s.IsDefault + model.Remark = s.Remark + model.Status = s.Status + model.IsVisible = s.IsVisible + model.Sort = s.Sort + model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 +} + +func (s *MemberRenwalConfigInsertReq) GetId() interface{} { + return s.Id +} + +type MemberRenwalConfigUpdateReq struct { + Id int `uri:"id" comment:"主键"` // 主键 + PackageName string `json:"packageName" comment:"套餐名称"` + DurationDay int `json:"durationDay" comment:"续期时间(天)"` + OriginalPrice decimal.Decimal `json:"originalPrice" comment:"原始单价"` + DiscountPrice *decimal.Decimal `json:"discountPrice" comment:"折扣价格 -1为未设置"` + IsDefault int `json:"isDefault" comment:"是否默认套餐 0-无 1-是 2-否"` + Remark string `json:"remark" comment:"备注"` + Status string `json:"status" comment:"套餐状态(字典 rewal_status)"` + IsVisible int `json:"isVisible" comment:"是否可见 2-不可见 1-可见"` + Sort int `json:"sort" comment:"排序"` + common.ControlBy +} + +func (s *MemberRenwalConfigUpdateReq) Generate(model *models.MemberRenwalConfig) { + if s.Id == 0 { + model.Model = common.Model{Id: s.Id} + } + model.PackageName = s.PackageName + model.DurationDay = s.DurationDay + model.OriginalPrice = s.OriginalPrice + + if s.DiscountPrice == nil { + model.DiscountPrice = decimal.NewFromInt(-1) + } else { + model.DiscountPrice = *s.DiscountPrice + } + model.IsDefault = s.IsDefault + model.Status = s.Status + model.Remark = s.Remark + model.IsVisible = s.IsVisible + model.Sort = s.Sort + model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 +} + +func (s *MemberRenwalConfigUpdateReq) GetId() interface{} { + return s.Id +} + +// MemberRenwalConfigGetReq 功能获取请求参数 +type MemberRenwalConfigGetReq struct { + Id int `uri:"id"` +} + +func (s *MemberRenwalConfigGetReq) GetId() interface{} { + return s.Id +} + +// MemberRenwalConfigDeleteReq 功能删除请求参数 +type MemberRenwalConfigDeleteReq struct { + Ids []int `json:"ids"` +} + +func (s *MemberRenwalConfigDeleteReq) GetId() interface{} { + return s.Ids +} diff --git a/app/admin/service/dto/spider_listen_symbol.go b/app/admin/service/dto/spider_listen_symbol.go index 34b579a..317f733 100644 --- a/app/admin/service/dto/spider_listen_symbol.go +++ b/app/admin/service/dto/spider_listen_symbol.go @@ -58,7 +58,7 @@ func (s *SpiderListenSymbolInsertReq) Generate(model *models.SpiderListenSymbol) model.Coin = strings.ToUpper(s.Coin) model.Currency = strings.ToUpper(s.Currency) - model.Symbol = s.Coin + s.Currency + model.Symbol = model.Coin + model.Currency model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 } @@ -94,7 +94,7 @@ func (s *SpiderListenSymbolUpdateReq) Generate(model *models.SpiderListenSymbol) // model.Symbol = s.Symbol model.Coin = strings.ToUpper(s.Coin) model.Currency = strings.ToUpper(s.Currency) - model.Symbol = s.Coin + s.Currency + model.Symbol = model.Coin + model.Currency model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 } diff --git a/app/admin/service/dto/sys_dict_data.go b/app/admin/service/dto/sys_dict_data.go index 842f418..64ea9c7 100644 --- a/app/admin/service/dto/sys_dict_data.go +++ b/app/admin/service/dto/sys_dict_data.go @@ -24,6 +24,18 @@ type SysDictDataGetAllResp struct { DictValue string `json:"value"` } +type SysDictDataResp struct { + DictSort int `json:"dictSort" comment:""` + DictLabel string `json:"dictLabel" comment:""` + DictValue string `json:"dictValue" comment:""` + DictType string `json:"dictType" comment:""` + CssClass string `json:"cssClass" comment:""` + ListClass string `json:"listClass" comment:""` + IsDefault string `json:"isDefault" comment:""` + Status int `json:"status" comment:""` + Default string `json:"default" comment:""` + Remark string `json:"remark" comment:""` +} type SysDictDataInsertReq struct { Id int `json:"-" comment:""` DictSort int `json:"dictSort" comment:""` diff --git a/app/admin/service/dto/sys_dict_type.go b/app/admin/service/dto/sys_dict_type.go index db66432..e18eb13 100644 --- a/app/admin/service/dto/sys_dict_type.go +++ b/app/admin/service/dto/sys_dict_type.go @@ -23,6 +23,23 @@ func (m *SysDictTypeGetPageReq) GetNeedSearch() interface{} { return *m } +type SysDictChildAppReq struct { + DictCode string `json:"dictCode" form:"dictCode"` + // DataCode string `json:"dataCode" form:"dataCode"` +} + +type SysDictDataAppReq struct { + DictCode string `json:"dictCode" form:"dictCode"` + DataCode string `json:"dataCode" form:"dataCode"` +} + +type SysDictTypeResp struct { + DictName string `json:"dictName"` + DictType string `json:"dictType"` + Status int `json:"status"` + Remark string `json:"remark"` +} + type SysDictTypeInsertReq struct { Id int `uri:"id"` DictName string `json:"dictName"` diff --git a/app/admin/service/line_coinnetwork.go b/app/admin/service/line_coinnetwork.go index c10c412..852fe90 100644 --- a/app/admin/service/line_coinnetwork.go +++ b/app/admin/service/line_coinnetwork.go @@ -3,13 +3,15 @@ package service import ( "errors" - "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/go-admin-team/go-admin-core/sdk/service" + "github.com/jinzhu/copier" "gorm.io/gorm" "go-admin/app/admin/models" "go-admin/app/admin/service/dto" "go-admin/common/actions" cDto "go-admin/common/dto" + statuscode "go-admin/common/status_code" ) type LineCoinnetwork struct { @@ -59,9 +61,9 @@ func (e *LineCoinnetwork) Get(d *dto.LineCoinnetworkGetReq, p *actions.DataPermi // Insert 创建LineCoinnetwork对象 func (e *LineCoinnetwork) Insert(c *dto.LineCoinnetworkInsertReq) error { - var err error - var data models.LineCoinnetwork - c.Generate(&data) + var err error + var data models.LineCoinnetwork + c.Generate(&data) err = e.Orm.Create(&data).Error if err != nil { e.Log.Errorf("LineCoinnetworkService Insert error:%s \r\n", err) @@ -72,22 +74,22 @@ func (e *LineCoinnetwork) Insert(c *dto.LineCoinnetworkInsertReq) error { // Update 修改LineCoinnetwork对象 func (e *LineCoinnetwork) Update(c *dto.LineCoinnetworkUpdateReq, p *actions.DataPermission) error { - var err error - var data = models.LineCoinnetwork{} - e.Orm.Scopes( - actions.Permission(data.TableName(), p), - ).First(&data, c.GetId()) - c.Generate(&data) + var err error + var data = models.LineCoinnetwork{} + 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("LineCoinnetworkService 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("LineCoinnetworkService Save error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权更新该数据") + } + return nil } // Remove 删除LineCoinnetwork @@ -99,11 +101,29 @@ func (e *LineCoinnetwork) Remove(d *dto.LineCoinnetworkDeleteReq, p *actions.Dat actions.Permission(data.TableName(), p), ).Delete(&data, d.GetId()) if err := db.Error; err != nil { - e.Log.Errorf("Service RemoveLineCoinnetwork error:%s \r\n", err) - return err - } - if db.RowsAffected == 0 { - return errors.New("无权删除该数据") - } + e.Log.Errorf("Service RemoveLineCoinnetwork error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权删除该数据") + } return nil } + +// 获取区块链列表 +// 状态码 +func (e *LineCoinnetwork) GetOpenList(list *[]dto.LineCoinnetworkAppResp) int { + var datas []models.LineCoinnetwork + item := dto.LineCoinnetworkAppResp{} + + if err := e.Orm.Model(&models.LineCoinnetwork{}).Find(&datas).Error; err != nil { + return statuscode.ServerError + } + + for _, v := range datas { + copier.Copy(&item, v) + + *list = append(*list, item) + } + return statuscode.OK +} diff --git a/app/admin/service/line_pre_order.go b/app/admin/service/line_pre_order.go index e5081a6..2d7a214 100644 --- a/app/admin/service/line_pre_order.go +++ b/app/admin/service/line_pre_order.go @@ -323,7 +323,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP //获取交易对 tradeSet, _ := helper.GetObjString[models2.TradeSet](helper.DefaultRedis, key) - orderCount := e.CheckRepeatOrder(req.OrderType, id, req.Site, tradeSet.Coin) + orderCount := e.CheckRepeatOrder(req.SymbolType, id, req.Site, tradeSet.Coin) if orderCount > 0 { *errs = append(*errs, fmt.Errorf("api_id:%s 获取交易对:%s 该交易对已存在,请勿重复下单", id, req.Symbol)) continue @@ -509,18 +509,14 @@ 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 - } + // for index := range preOrderExts { + // if index == 0 { + // preOrderExts[index].OrderId = AddOrder.Id + // } - preOrderExts[index].MainOrderId = AddOrder.Id - } + // preOrderExts[index].MainOrderId = AddOrder.Id + // } - err = tx.Model(&models.LinePreOrderExt{}).Create(&preOrderExts).Error - if err != nil { - return err - } list := dto.PreOrderRedisList{ Id: AddOrder.Id, Symbol: AddOrder.Symbol, @@ -571,6 +567,7 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP stopOrder.MainId = AddOrder.Id stopOrder.OrderType = 4 stopOrder.Status = 0 + stopOrder.BuyPrice = "0" stopOrder.Rate = req.ReducePriceRatio.String() stopNum := utility.StrToDecimal(AddOrder.Num).Mul(req.ReduceNumRatio.Div(decimal.NewFromInt(100)).Truncate(4)) stopOrder.Num = stopNum.Truncate(int32(tradeSet.AmountDigit)).String() @@ -604,12 +601,12 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP continue } - preOrderExts[index].OrderId = addPosition.Id if err := e.Orm.Create(&addPosition).Error; err != nil { logger.Error("保存加仓单失败") return err } + preOrderExts[index].OrderId = addPosition.Id //止盈、减仓 orders, err := makeFuturesTakeAndReduce(&addPosition, v, tradeSet) @@ -644,6 +641,11 @@ func (e *LinePreOrder) AddPreOrder(req *dto.LineAddPreOrderReq, p *actions.DataP } } } + + err = tx.Model(&models.LinePreOrderExt{}).Create(&preOrderExts).Error + if err != nil { + return err + } return nil }) } @@ -807,9 +809,9 @@ func makeReduceTakeAndStoploss(parentOrder *models.LinePreOrder, ext models.Line } // CheckRepeatOrder 检查重复下单 检查基础货币 -func (e *LinePreOrder) CheckRepeatOrder(orderType int, apiUserId, site, baseCoin string) int64 { +func (e *LinePreOrder) CheckRepeatOrder(symbolType int, apiUserId, site, baseCoin string) int64 { var count int64 - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND pid=0 AND symbol like ? AND order_type = ? AND site = ? AND `status` IN (1,5,6)", apiUserId, baseCoin+"%", orderType, site).Count(&count) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND pid=0 AND symbol like ? AND symbol_type = ? AND site = ? AND `status` IN (1,5,6)", apiUserId, baseCoin+"%", symbolType, site).Count(&count) return count } @@ -897,6 +899,7 @@ func (e *LinePreOrder) AddBatchPreOrder(batchReq *dto.LineBatchAddPreOrderReq, p req.Price = batchReq.Price req.Profit = batchReq.Profit req.Ext = batchReq.Ext + req.SymbolType = batchReq.SymbolType // req.StopPrice = batchReq.StopPrice req.ReducePriceRatio = batchReq.ReducePriceRatio req.PriceType = batchReq.PriceType @@ -1176,6 +1179,8 @@ func (e *LinePreOrder) ClearAll() error { "stop_loss_markt", "_PreSpotOrderList_", "_PreFutOrderList_", + "spot_reduce_list", + "futures_reduce_list", } err = helper.DefaultRedis.DeleteKeysByPrefix(prefixs...) if err != nil { @@ -1308,15 +1313,20 @@ func (e *LinePreOrder) SpotClosePosition(position *dto.ClosePosition, errs *[]er //查询已经开仓的现货交易对 var spotList []models.LinePreOrder if position.Symbol == "" { //全平 - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId).Find(&spotList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol_type =1 AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId).Find(&spotList) } else { - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId, position.Symbol).Find(&spotList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol_type =1 AND symbol = ? AND status = 6 AND pid = 0 AND order_type = 0", position.ApiId, position.Symbol).Find(&spotList) } if len(spotList) <= 0 { *errs = append(*errs, errors.New(fmt.Sprintf("api_id:%d 没有可平仓的交易对", position.ApiId))) } api := binanceservice.SpotRestApi{} + if len(spotList) == 0 { + *errs = append(*errs, errors.New("无仓可平")) + return + } + for _, list := range spotList { for _, balance := range balanceInfo.Balances { suffix := utility.ReplaceSuffix(list.Symbol, list.QuoteSymbol, "") @@ -1402,9 +1412,9 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err //查询已经开仓的合约交易对 var futList []models.LinePreOrder if position.Symbol == "" { - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND order_type =0 AND main_id = 0", position.ApiId).Find(&futList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND status = 6 AND symbol_type =2 AND order_type =0 AND main_id = 0", position.ApiId).Find(&futList) } else { - e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND status = 6 AND order_type = 0 AND main_id = 0", position.ApiId, position.Symbol).Find(&futList) + e.Orm.Model(&models.LinePreOrder{}).Where("api_id = ? AND symbol = ? AND symbol_type =2 AND status = 6 AND order_type = 0 AND main_id = 0", position.ApiId, position.Symbol).Find(&futList) } if len(futList) <= 0 { *errs = append(*errs, fmt.Errorf("api_id:%d 没有可平仓的交易对", position.ApiId)) @@ -1413,6 +1423,11 @@ func (e *LinePreOrder) FutClosePosition(position *dto.ClosePosition, errs *[]err api := binanceservice.FutRestApi{} + if len(futList) == 0 { + *errs = append(*errs, errors.New("无仓可平")) + return + } + for _, list := range futList { risks, err := api.GetPositionV3(&apiUserInfo, list.Symbol) if err != nil { diff --git a/app/admin/service/line_symbol.go b/app/admin/service/line_symbol.go index c4ece3e..9a8f2d7 100644 --- a/app/admin/service/line_symbol.go +++ b/app/admin/service/line_symbol.go @@ -6,6 +6,7 @@ import ( "strings" "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/service" "github.com/shopspring/decimal" @@ -115,6 +116,66 @@ func (e *LineSymbol) GetSamePage(c *dto.LineSymbolGetPageReq, p *actions.DataPer return nil } +// 导出excel +func (e *LineSymbol) ExportExcel(c *gin.Context, p *actions.DataPermission, req *dto.LineSymbolGetPageReq) error { + list := make([]models.LineSymbol, 0) + datas := make([]dto.LineSymbolExportResp, 0) + var data models.LineSymbol + var fileName string + + err := e.Orm.Model(&data). + Scopes( + cDto.MakeCondition(req.GetNeedSearch()), + actions.Permission(data.TableName(), p), + ). + Find(&list).Error + + if err != nil { + return err + } + + for _, v := range list { + item := dto.LineSymbolExportResp{ + Symbol: v.Symbol, + Coin: v.BaseAsset, + Currency: v.QuoteAsset, + } + + if v.Type == "1" { + item.SymbolType = "现货" + } else { + item.SymbolType = "合约" + } + + datas = append(datas, item) + } + + if len(datas) == 0 { + return errors.New("无数据") + } + + if req.Type == "1" { + fileName = "现货交易对" + } else { + fileName = "合约交易对" + } + + err = helper.ExportExcel(c, fileName, datas, []string{}) + + return err +} + +// 获取所有交易对 +func (e *LineSymbol) GetAll(req *dto.LineSymbolGetListReq) ([]string, error) { + result := make([]string, 0) + + if err := e.Orm.Model(&models.LineSymbol{}).Where("type = ? AND exchange_type =?", req.Type, req.ExchangeType).Pluck("symbol", &result).Error; err != nil { + return nil, err + } + + return result, nil +} + // Get 获取LineSymbol对象 func (e *LineSymbol) Get(d *dto.LineSymbolGetReq, p *actions.DataPermission, model *models.LineSymbol) error { var data models.LineSymbol diff --git a/app/admin/service/line_symbol_group.go b/app/admin/service/line_symbol_group.go index 79cbcfc..33ac409 100644 --- a/app/admin/service/line_symbol_group.go +++ b/app/admin/service/line_symbol_group.go @@ -11,6 +11,7 @@ import ( "go-admin/app/admin/service/dto" "go-admin/common/actions" cDto "go-admin/common/dto" + "go-admin/pkg/utility" ) type LineSymbolGroup struct { @@ -73,6 +74,14 @@ func (e *LineSymbolGroup) Insert(c *dto.LineSymbolGroupInsertReq) error { var err error var data models.LineSymbolGroup c.Generate(&data) + + symbols := availableSymbols(data.Symbol, c.Type, e) + + if len(symbols) == 0 { + return errors.New("全部交易对不可用") + } + + data.Symbol = strings.Join(symbols, ",") err = e.Orm.Create(&data).Error if err != nil { e.Log.Errorf("LineSymbolGroupService Insert error:%s \r\n", err) @@ -81,6 +90,25 @@ func (e *LineSymbolGroup) Insert(c *dto.LineSymbolGroupInsertReq) error { return nil } +// 可用交易对 +func availableSymbols(symbols, symbolType string, e *LineSymbolGroup) []string { + blacks := make([]string, 0) + newSymbols := make([]string, 0) + reqSymbols := strings.Split(symbols, ",") + e.Orm.Model(&models.LineSymbolBlack{}).Where("type=?", symbolType).Select("symbol").Find(&blacks) + for _, v := range reqSymbols { + symbol := strings.ToUpper(v) + + //黑名单跳过 + if utility.ContainsStr(blacks, symbol) { + continue + } + + newSymbols = append(newSymbols, symbol) + } + return newSymbols +} + // Update 修改LineSymbolGroup对象 func (e *LineSymbolGroup) Update(c *dto.LineSymbolGroupUpdateReq, p *actions.DataPermission) error { var err error @@ -89,7 +117,13 @@ func (e *LineSymbolGroup) Update(c *dto.LineSymbolGroupUpdateReq, p *actions.Dat actions.Permission(data.TableName(), p), ).First(&data, c.GetId()) c.Generate(&data) + symbols := availableSymbols(data.Symbol, c.Type, e) + if len(symbols) == 0 { + return errors.New("全部交易对不可用") + } + + data.Symbol = strings.Join(symbols, ",") db := e.Orm.Save(&data) if err = db.Error; err != nil { e.Log.Errorf("LineSymbolGroupService Save error:%s \r\n", err) diff --git a/app/admin/service/member_balance.go b/app/admin/service/member_balance.go new file mode 100644 index 0000000..61e1bb0 --- /dev/null +++ b/app/admin/service/member_balance.go @@ -0,0 +1,109 @@ +package service + +import ( + "errors" + + "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" + cDto "go-admin/common/dto" +) + +type MemberBalance struct { + service.Service +} + +// GetPage 获取MemberBalance列表 +func (e *MemberBalance) GetPage(c *dto.MemberBalanceGetPageReq, p *actions.DataPermission, list *[]models.MemberBalance, count *int64) error { + var err error + var data models.MemberBalance + + err = e.Orm.Model(&data). + Scopes( + cDto.MakeCondition(c.GetNeedSearch()), + cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), + actions.Permission(data.TableName(), p), + ). + Find(list).Limit(-1).Offset(-1). + Count(count).Error + if err != nil { + e.Log.Errorf("MemberBalanceService GetPage error:%s \r\n", err) + return err + } + return nil +} + +// Get 获取MemberBalance对象 +func (e *MemberBalance) Get(d *dto.MemberBalanceGetReq, p *actions.DataPermission, model *models.MemberBalance) error { + var data models.MemberBalance + + err := e.Orm.Model(&data). + Scopes( + actions.Permission(data.TableName(), p), + ). + First(model, d.GetId()).Error + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { + err = errors.New("查看对象不存在或无权查看") + e.Log.Errorf("Service GetMemberBalance error:%s \r\n", err) + return err + } + if err != nil { + e.Log.Errorf("db error:%s", err) + return err + } + return nil +} + +// Insert 创建MemberBalance对象 +func (e *MemberBalance) Insert(c *dto.MemberBalanceInsertReq) error { + 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) + return err + } + return nil +} + +// 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) + + 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 +func (e *MemberBalance) Remove(d *dto.MemberBalanceDeleteReq, p *actions.DataPermission) error { + var data models.MemberBalance + + db := e.Orm.Model(&data). + Scopes( + 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("无权删除该数据") + } + return nil +} diff --git a/app/admin/service/member_balance_log.go b/app/admin/service/member_balance_log.go new file mode 100644 index 0000000..76abfd5 --- /dev/null +++ b/app/admin/service/member_balance_log.go @@ -0,0 +1,109 @@ +package service + +import ( + "errors" + + "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" + cDto "go-admin/common/dto" +) + +type MemberBalanceLog struct { + service.Service +} + +// GetPage 获取MemberBalanceLog列表 +func (e *MemberBalanceLog) GetPage(c *dto.MemberBalanceLogGetPageReq, p *actions.DataPermission, list *[]models.MemberBalanceLog, count *int64) error { + var err error + var data models.MemberBalanceLog + + err = e.Orm.Model(&data). + Scopes( + cDto.MakeCondition(c.GetNeedSearch()), + cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), + actions.Permission(data.TableName(), p), + ). + Find(list).Limit(-1).Offset(-1). + Count(count).Error + if err != nil { + e.Log.Errorf("MemberBalanceLogService GetPage error:%s \r\n", err) + return err + } + return nil +} + +// Get 获取MemberBalanceLog对象 +func (e *MemberBalanceLog) Get(d *dto.MemberBalanceLogGetReq, p *actions.DataPermission, model *models.MemberBalanceLog) error { + var data models.MemberBalanceLog + + err := e.Orm.Model(&data). + Scopes( + actions.Permission(data.TableName(), p), + ). + First(model, d.GetId()).Error + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { + err = errors.New("查看对象不存在或无权查看") + e.Log.Errorf("Service GetMemberBalanceLog error:%s \r\n", err) + return err + } + if err != nil { + e.Log.Errorf("db error:%s", err) + return err + } + return nil +} + +// Insert 创建MemberBalanceLog对象 +func (e *MemberBalanceLog) Insert(c *dto.MemberBalanceLogInsertReq) error { + var err error + var data models.MemberBalanceLog + c.Generate(&data) + err = e.Orm.Create(&data).Error + if err != nil { + e.Log.Errorf("MemberBalanceLogService Insert error:%s \r\n", err) + return err + } + return nil +} + +// Update 修改MemberBalanceLog对象 +func (e *MemberBalanceLog) Update(c *dto.MemberBalanceLogUpdateReq, p *actions.DataPermission) error { + var err error + var data = models.MemberBalanceLog{} + 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("MemberBalanceLogService Save error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权更新该数据") + } + return nil +} + +// Remove 删除MemberBalanceLog +func (e *MemberBalanceLog) Remove(d *dto.MemberBalanceLogDeleteReq, p *actions.DataPermission) error { + var data models.MemberBalanceLog + + db := e.Orm.Model(&data). + Scopes( + actions.Permission(data.TableName(), p), + ).Delete(&data, d.GetId()) + if err := db.Error; err != nil { + e.Log.Errorf("Service RemoveMemberBalanceLog error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权删除该数据") + } + return nil +} diff --git a/app/admin/service/member_renwa_log.go b/app/admin/service/member_renwa_log.go new file mode 100644 index 0000000..1449a4f --- /dev/null +++ b/app/admin/service/member_renwa_log.go @@ -0,0 +1,109 @@ +package service + +import ( + "errors" + + "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" + cDto "go-admin/common/dto" +) + +type MemberRenwaLog struct { + service.Service +} + +// GetPage 获取MemberRenwaLog列表 +func (e *MemberRenwaLog) GetPage(c *dto.MemberRenwaLogGetPageReq, p *actions.DataPermission, list *[]models.MemberRenwaLog, count *int64) error { + var err error + var data models.MemberRenwaLog + + err = e.Orm.Model(&data). + Scopes( + cDto.MakeCondition(c.GetNeedSearch()), + cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), + actions.Permission(data.TableName(), p), + ). + Find(list).Limit(-1).Offset(-1). + Count(count).Error + if err != nil { + e.Log.Errorf("MemberRenwaLogService GetPage error:%s \r\n", err) + return err + } + return nil +} + +// Get 获取MemberRenwaLog对象 +func (e *MemberRenwaLog) Get(d *dto.MemberRenwaLogGetReq, p *actions.DataPermission, model *models.MemberRenwaLog) error { + var data models.MemberRenwaLog + + err := e.Orm.Model(&data). + Scopes( + actions.Permission(data.TableName(), p), + ). + First(model, d.GetId()).Error + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { + err = errors.New("查看对象不存在或无权查看") + e.Log.Errorf("Service GetMemberRenwaLog error:%s \r\n", err) + return err + } + if err != nil { + e.Log.Errorf("db error:%s", err) + return err + } + return nil +} + +// Insert 创建MemberRenwaLog对象 +func (e *MemberRenwaLog) Insert(c *dto.MemberRenwaLogInsertReq) error { + 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) + return err + } + return nil +} + +// 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) + + 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 +func (e *MemberRenwaLog) Remove(d *dto.MemberRenwaLogDeleteReq, p *actions.DataPermission) error { + var data models.MemberRenwaLog + + db := e.Orm.Model(&data). + Scopes( + 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("无权删除该数据") + } + return nil +} diff --git a/app/admin/service/member_renwal_config.go b/app/admin/service/member_renwal_config.go new file mode 100644 index 0000000..09f4e83 --- /dev/null +++ b/app/admin/service/member_renwal_config.go @@ -0,0 +1,109 @@ +package service + +import ( + "errors" + + "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" + cDto "go-admin/common/dto" +) + +type MemberRenwalConfig struct { + service.Service +} + +// GetPage 获取MemberRenwalConfig列表 +func (e *MemberRenwalConfig) GetPage(c *dto.MemberRenwalConfigGetPageReq, p *actions.DataPermission, list *[]models.MemberRenwalConfig, count *int64) error { + var err error + var data models.MemberRenwalConfig + + err = e.Orm.Model(&data). + Scopes( + cDto.MakeCondition(c.GetNeedSearch()), + cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), + actions.Permission(data.TableName(), p), + ). + Find(list).Limit(-1).Offset(-1). + Count(count).Error + if err != nil { + e.Log.Errorf("MemberRenwalConfigService GetPage error:%s \r\n", err) + return err + } + return nil +} + +// Get 获取MemberRenwalConfig对象 +func (e *MemberRenwalConfig) Get(d *dto.MemberRenwalConfigGetReq, p *actions.DataPermission, model *models.MemberRenwalConfig) error { + var data models.MemberRenwalConfig + + err := e.Orm.Model(&data). + Scopes( + actions.Permission(data.TableName(), p), + ). + First(model, d.GetId()).Error + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { + err = errors.New("查看对象不存在或无权查看") + e.Log.Errorf("Service GetMemberRenwalConfig error:%s \r\n", err) + return err + } + if err != nil { + e.Log.Errorf("db error:%s", err) + return err + } + return nil +} + +// Insert 创建MemberRenwalConfig对象 +func (e *MemberRenwalConfig) Insert(c *dto.MemberRenwalConfigInsertReq) error { + var err error + var data models.MemberRenwalConfig + c.Generate(&data) + err = e.Orm.Create(&data).Error + if err != nil { + e.Log.Errorf("MemberRenwalConfigService Insert error:%s \r\n", err) + return err + } + return nil +} + +// Update 修改MemberRenwalConfig对象 +func (e *MemberRenwalConfig) Update(c *dto.MemberRenwalConfigUpdateReq, p *actions.DataPermission) error { + var err error + var data = models.MemberRenwalConfig{} + 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("MemberRenwalConfigService Save error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权更新该数据") + } + return nil +} + +// Remove 删除MemberRenwalConfig +func (e *MemberRenwalConfig) Remove(d *dto.MemberRenwalConfigDeleteReq, p *actions.DataPermission) error { + var data models.MemberRenwalConfig + + db := e.Orm.Model(&data). + Scopes( + actions.Permission(data.TableName(), p), + ).Delete(&data, d.GetId()) + if err := db.Error; err != nil { + e.Log.Errorf("Service RemoveMemberRenwalConfig error:%s \r\n", err) + return err + } + if db.RowsAffected == 0 { + return errors.New("无权删除该数据") + } + return nil +} diff --git a/app/admin/service/sys_dict_type.go b/app/admin/service/sys_dict_type.go index bc45fe2..af3f50a 100644 --- a/app/admin/service/sys_dict_type.go +++ b/app/admin/service/sys_dict_type.go @@ -10,6 +10,7 @@ import ( "go-admin/app/admin/models" "go-admin/app/admin/service/dto" cDto "go-admin/common/dto" + statuscode "go-admin/common/status_code" ) type SysDictType struct { @@ -122,3 +123,23 @@ func (e *SysDictType) GetAll(c *dto.SysDictTypeGetPageReq, list *[]models.SysDic } return nil } + +// 获取所有子类 +func (e *SysDictType) GetChild(req *dto.SysDictChildAppReq, list *[]dto.SysDictDataResp) int { + datas := make([]models.SysDictData, 0) + + if err := e.Orm.Model(&models.SysDictData{}).Where("dict_type =?", req.DictCode).Find(&datas).Error; err != nil { + return statuscode.ServerError + } + + for _, v := range datas { + *list = append(*list, dto.SysDictDataResp{ + DictLabel: v.DictLabel, + DictValue: v.DictValue, + Remark: v.Remark, + Status: v.Status, + }) + } + + return statuscode.OK +} diff --git a/app/jobs/examples.go b/app/jobs/examples.go index a259011..0841ba8 100644 --- a/app/jobs/examples.go +++ b/app/jobs/examples.go @@ -71,7 +71,7 @@ func (receiver DeleteExpireOrder) Exec(arg interface{}) error { break } orders := make([]models.LinePreOrder, 0) - err := db.Model(&models.LinePreOrder{}).Where("status = '0' AND expire_time <= ? AND (order_type = 1 or order_type = 2)", time.Now()).Find(&orders).Error + err := db.Model(&models.LinePreOrder{}).Where("status = '0' AND expire_time <= ? AND order_type = 0 AND pid=0", time.Now()).Find(&orders).Error if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return err } diff --git a/app/jobs/jobs.go b/app/jobs/jobs.go index bc937a4..344657f 100644 --- a/app/jobs/jobs.go +++ b/app/jobs/jobs.go @@ -25,9 +25,8 @@ import ( "time" "github.com/bytedance/sonic" - "gorm.io/driver/mysql" - "github.com/shopspring/decimal" + "gorm.io/driver/mysql" "github.com/go-admin-team/go-admin-core/sdk" "gorm.io/gorm" @@ -227,19 +226,28 @@ func (t LimitOrderTimeoutDuration) ReSpotOrderPlace(db *gorm.DB, order models.Li logger.Error(fmt.Sprintf("取消现货委托失败:order_sn:%s err:%+v", order.OrderSn, err)) return err } else { + var remainingQuantity decimal.Decimal + spotOrder, err := spotApi.GetOrderByOrderSnLoop(order.Symbol, order.OrderSn, apiUserinfo, 4) + + if err == nil { + origQty := utility.StrToDecimal(spotOrder.OrigQuoteOrderQty) + excuteQty := utility.StrToDecimal(spotOrder.ExecutedQty) + remainingQuantity = origQty.Sub(excuteQty).Abs() + } + + if remainingQuantity.Cmp(decimal.Zero) <= 0 { + logger.Errorf("剩余数量为0 无需重新下市价单mainid:%v", order.MainId) + return nil + } + + tradeSet, _ := binanceservice.GetTradeSet(order.Symbol, 0) newClientOrderId := snowflakehelper.GetOrderId() + order.Num = remainingQuantity.Truncate(int32(tradeSet.AmountDigit)).String() order.Desc = fmt.Sprintf("取消限价单,重下市价单源订单号:%s ", order.OrderSn) order.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId()) order.MainOrderType = "MARKET" - // var newOrder models.LinePreOrder - // copier.Copy(&newOrder, order) - // newOrder.Id = 0 - // newOrder.OrderSn = utility.Int64ToString(newClientOrderId) - // newOrder.CreatedAt = time.Now() - // newOrder.MainOrderType = "MARKET" - // err = db.Model(&models.LinePreOrder{}).Create(&newOrder).Error - err := db.Model(&order).Updates(map[string]interface{}{"desc": order.Desc, "order_sn": order.OrderSn, "main_order_type": order.MainOrderType}).Error + err = db.Model(&order).Updates(map[string]interface{}{"desc": order.Desc, "order_sn": order.OrderSn, "main_order_type": order.MainOrderType}).Error if err != nil { logger.Error(fmt.Sprintf("生成新市价单失败 err:%+v", err)) @@ -253,7 +261,7 @@ func (t LimitOrderTimeoutDuration) ReSpotOrderPlace(db *gorm.DB, order models.Li TimeInForce: "GTC", Price: utility.StringToDecimal(order.Price), StopPrice: utility.StrToDecimal(order.Price), - Quantity: utility.StringToDecimal(order.Num), + Quantity: remainingQuantity, NewClientOrderId: utility.Int64ToString(newClientOrderId), } if err := spotApi.OrderPlace(db, params); err != nil { @@ -283,8 +291,24 @@ func (t LimitOrderTimeoutDuration) ReFutOrderPlace(db *gorm.DB, order models.Lin logger.Error(fmt.Sprintf("取消现货委托失败:order_sn:%s err:%+v", order.OrderSn, err)) return err } else { + var remainingQuantity decimal.Decimal + spotOrder, err := futApi.GetOrderByOrderSnLoop(order.Symbol, order.OrderSn, apiUserinfo, 4) + + if err == nil { + origQty := utility.StrToDecimal(spotOrder.OrigQty) + excuteQty := utility.StrToDecimal(spotOrder.ExecutedQty) + remainingQuantity = origQty.Sub(excuteQty).Abs() + } + + if remainingQuantity.Cmp(decimal.Zero) <= 0 { + logger.Errorf("剩余数量为0 无需重新下市价单mainid:%v", order.MainId) + return nil + } + + tradeSet, _ := binanceservice.GetTradeSet(order.Symbol, 0) + newClientOrderId := snowflakehelper.GetOrderId() - orderType := "MARKET" + order.Num = remainingQuantity.Truncate(int32(tradeSet.AmountDigit)).String() order.Desc = fmt.Sprintf("取消限价单,重下市价单 源订单号:%s", order.OrderSn) order.OrderSn = utility.Int64ToString(newClientOrderId) @@ -296,31 +320,32 @@ func (t LimitOrderTimeoutDuration) ReFutOrderPlace(db *gorm.DB, order models.Lin // newOrder.MainOrderType = "MARKET" // err = db.Model(&models.LinePreOrder{}).Create(&newOrder).Error + var positionSide string + + if order.Site == "BUY" { + positionSide = "SHORT" + } else { + positionSide = "LONG" + } err = db.Model(&order).Updates(map[string]interface{}{"desc": order.Desc, "order_sn": order.OrderSn}).Error if err != nil { logger.Error(fmt.Sprintf("生成合约新市价单失败 err:%+v", err)) return err } - if order.OrderType == 4 { - orderType = "STOP_MARKET" - } + // params := binanceservice.FutOrderPlace{ + // ApiId: order.ApiId, + // Symbol: order.Symbol, + // Side: order.Site, + // Quantity: remainingQuantity, + // Price: utility.StringToDecimal(order.Price), + // SideType: "MARKET", + // OpenOrder: 0, + // OrderType: "MARKET", + // NewClientOrderId: utility.Int64ToString(newClientOrderId), + // } - params := binanceservice.FutOrderPlace{ - ApiId: order.ApiId, - Symbol: order.Symbol, - Side: order.Site, - Quantity: utility.StringToDecimal(order.Num), - Price: utility.StringToDecimal(order.Price), - SideType: "MARKET", - OpenOrder: 0, - Profit: decimal.Decimal{}, - StopPrice: utility.StringToDecimal(order.Price), - OrderType: orderType, - NewClientOrderId: utility.Int64ToString(newClientOrderId), - } - - if err := futApi.OrderPlace(db, params); err != nil { + if err := futApi.ClosePositionLoop(order.Symbol, order.OrderSn, remainingQuantity, order.Site, positionSide, apiUserinfo, "MARKET", "0", decimal.Zero, 3); err != nil { logger.Error(fmt.Sprintf("重新下合约市价单失败 err:%+v", err)) err := db.Model(&order).Updates(map[string]interface{}{"status": "2", "desc": order.Desc + " err:" + err.Error()}).Error if err != nil { diff --git a/cmd/migrate/migration/version-local/doc.go b/cmd/migrate/migration/version-local/doc.go deleted file mode 100644 index 2cec8bc..0000000 --- a/cmd/migrate/migration/version-local/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -package version_local - -func init() { -} - -/** -开发者项目的迁移脚本放在这个目录里,init写法参考version目录里的migrate或者自动生成 -*/ diff --git a/cmd/migrate/server.go b/cmd/migrate/server.go index b1667ca..6c888be 100644 --- a/cmd/migrate/server.go +++ b/cmd/migrate/server.go @@ -3,21 +3,22 @@ package migrate import ( "bytes" "fmt" - "github.com/go-admin-team/go-admin-core/sdk" - "github.com/go-admin-team/go-admin-core/sdk/pkg" "strconv" "text/template" "time" + "github.com/go-admin-team/go-admin-core/sdk" + "github.com/go-admin-team/go-admin-core/sdk/pkg" + "github.com/go-admin-team/go-admin-core/config/source/file" "github.com/spf13/cobra" - "github.com/go-admin-team/go-admin-core/sdk/config" "go-admin/cmd/migrate/migration" _ "go-admin/cmd/migrate/migration/version" - _ "go-admin/cmd/migrate/migration/version-local" "go-admin/common/database" "go-admin/common/models" + + "github.com/go-admin-team/go-admin-core/sdk/config" ) var ( diff --git a/common/const/dicts/member_renwal_config_status/member_renwal_config_status.go b/common/const/dicts/member_renwal_config_status/member_renwal_config_status.go new file mode 100644 index 0000000..51fe50b --- /dev/null +++ b/common/const/dicts/member_renwal_config_status/member_renwal_config_status.go @@ -0,0 +1,8 @@ +package memberrenwalconfigstatus + +const ( + //启用 + ENABLE = "enable" + //禁用 + DSIABLE = "disable" +) diff --git a/common/const/dicts/member_renwal_isvisible/dict.go b/common/const/dicts/member_renwal_isvisible/dict.go new file mode 100644 index 0000000..44e62bb --- /dev/null +++ b/common/const/dicts/member_renwal_isvisible/dict.go @@ -0,0 +1,6 @@ +package memberrenwalisvisible + +const ( + IsVisibleYes = 1 // 是 + IsVisibleNo = 2 // 否 +) diff --git a/common/helper/excel_helper.go b/common/helper/excel_helper.go new file mode 100644 index 0000000..e02f6d1 --- /dev/null +++ b/common/helper/excel_helper.go @@ -0,0 +1,168 @@ +package helper + +import ( + "encoding/csv" + "errors" + "fmt" + "log" + "reflect" + "strings" + + "github.com/xuri/excelize/v2" + + "github.com/gin-gonic/gin" +) + +/* +导出csv文件 + + - @fileName 文件名 不带拓展名 + - @header 文件头 + - @records 内容 +*/ +func ExportCSV(c *gin.Context, fileName string, header []string, records [][]string) error { + disposition := fmt.Sprintf("attachment; filename=%s.csv", fileName) + + // Set headers + c.Header("Content-Description", "File Transfer") + c.Header("Content-Disposition", disposition) + c.Header("Content-Type", "text/csv") + + // Create a CSV writer using the response writer + writer := csv.NewWriter(c.Writer) + defer writer.Flush() + + // Write CSV header + writer.Write(header) + + for _, record := range records { + writer.Write(record) + } + + return nil +} + +/* +导出excel + + - @fileName 文件名称 + - @data 数据源 + - @ingore 忽略header +*/ +func ExportExcel[T any](c *gin.Context, fileName string, data []T, ingore []string) error { + if len(data) == 0 { + return errors.New("无导出记录") + } + // Create a new Excel file + f := excelize.NewFile() + // Use reflection to get the header from struct tags + t := reflect.TypeOf(data[0]) + headers := []string{} + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + excelTag := field.Tag.Get("excel") + if excelTag != "" && !ArrayAny(ingore, excelTag) { + headers = append(headers, excelTag) + } + } + // Set headers + for i, header := range headers { + col := string('A' + i) + cell := fmt.Sprintf("%s1", col) + f.SetCellValue("Sheet1", cell, header) + } + + // Fill rows with data + for rowIndex, item := range data { + rowValue := reflect.ValueOf(item) + rowType := rowValue.Type() + for colIndex, header := range headers { + col := string('A' + colIndex) + cell := fmt.Sprintf("%s%d", col, rowIndex+2) + var fieldValue reflect.Value + + for i := 0; i < rowType.NumField(); i++ { + field := rowType.Field(i) + if strings.EqualFold(field.Tag.Get("excel"), header) { + fieldValue = rowValue.Field(i) + break + } + } + + // Check if the fieldValue is valid before accessing it + if fieldValue.IsValid() && fieldValue.CanInterface() { + //f.SetCellValue("Sheet1", cell, fieldValue.Interface()) + value := fieldValue.Interface() + + // Ensure the value is a string, convert it if necessary + var stringValue string + if v, ok := value.(string); ok { + stringValue = v // If it's a string, use it directly + } else { + stringValue = fmt.Sprintf("%v", value) // Otherwise, convert to string + } + f.SetCellValue("Sheet1", cell, stringValue) + } else { + // Handle the case where fieldValue is invalid or nil + f.SetCellValue("Sheet1", cell, "") + } + } + } + // Set response headers and send the file to the client + + // c.Writer.Header().Set("Content-Disposition", "attachment; filename=test.xlsx") + // c.Writer.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=binary") + // c.Writer.Header().Set("Content-Transfer-Encoding", "binary") + // c.Writer.Header().Set("Expires", "0") + // c.Writer.Header().Set("Cache-Control", "must-revalidate") + // c.Writer.Header().Set("Pragma", "public") + c.Header("Content-Description", "File Transfer") + c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s.xlsx", fileName)) + c.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + c.Header("Content-Transfer-Encoding", "binary") + c.Header("Expires", "0") + c.Header("Cache-Control", "must-revalidate") + c.Header("Pragma", "public") + c.Header("Content-Encoding", "") + //fmt.Println("c.Writer.Header():", c.Writer.Header()) + if _, err := f.WriteTo(c.Writer); err != nil { + log.Println("Error writing file:", err) + return err + } + return nil + //return f.WriteTo(c.Writer) +} + +func MapExcelToStruct[T any](rows [][]string, headers []string) ([]T, error) { + var results []T + if len(rows) == 0 { + return results, nil + } + + for _, row := range rows { + var result T + v := reflect.ValueOf(&result).Elem() + + for i, header := range headers { + fieldName := "" + for j := 0; j < v.NumField(); j++ { + field := v.Type().Field(j) + tag := field.Tag.Get("excel") + if strings.EqualFold(tag, header) { + fieldName = field.Name + break + } + } + + if fieldName != "" && i < len(row) { + field := v.FieldByName(fieldName) + if field.IsValid() && field.CanSet() { + field.Set(reflect.ValueOf(row[i]).Convert(field.Type())) + } + } + } + results = append(results, result) + } + + return results, nil +} diff --git a/common/helper/extension_helper.go b/common/helper/extension_helper.go new file mode 100644 index 0000000..612216e --- /dev/null +++ b/common/helper/extension_helper.go @@ -0,0 +1,52 @@ +package helper + +/* +判断是否存在 + + - @arr 数组 + - @value 值 +*/ +func ArrayAny[T comparable](arr []T, value T) bool { + for _, v := range arr { + if v == value { + return true + } + } + return false +} + +// 定义一个条件函数类型 +type ConditionFunc[T any] func(T) bool + +/* +判断是否存在 + + - @arr 数组 + + - @condition 判断函数 + + @return 对象指针 +*/ +func ArrayAnyExtension[T any](arr *[]T, condition ConditionFunc[T]) *T { + for _, v := range *arr { + if condition(v) { + return &v + } + } + + return nil +} + +func RemoveDuplicates(nums []int64) []int64 { + m := make(map[int64]bool) + result := []int64{} + + for _, num := range nums { + if !m[num] { + m[num] = true + result = append(result, num) + } + } + + return result +} diff --git a/common/service/sysservice/authservice/authentication.go b/common/service/sysservice/authservice/authentication.go index 816877f..18d5032 100644 --- a/common/service/sysservice/authservice/authentication.go +++ b/common/service/sysservice/authservice/authentication.go @@ -16,6 +16,7 @@ import ( "go-admin/pkg/emailhelper" "time" + "github.com/go-admin-team/go-admin-core/logger" log "github.com/go-admin-team/go-admin-core/logger" "go.uber.org/zap" "gorm.io/gorm" @@ -81,17 +82,23 @@ func UserRegister(orm *gorm.DB, registerInfo sysmodel.FrontedUserRegisterReq) (i //if code := CheckPhoneOrEmailCaptcha(orm, cc); code != statuscode.OK { // return "", "", statuscode.CaptchaInvalid //} + parentRegister := models.LineUser{} + if err := orm.Model(&parentRegister).Where("id =?", registerInfo.Pid).Find(&parentRegister).Error; err != nil { + logger.Error("获取推荐人失败", err) + } + user := models.LineUser{ - Pid: registerInfo.Pid, - Password: registerInfo.Password, - Salt: inttostring.GenerateRandomString(6), - Email: registerInfo.Email, - InviteCode: inttostring.NewInvite().Encode(int(time.Now().Unix())), - Loginip: registerInfo.IP, - Mobile: registerInfo.Phone, - Area: registerInfo.PhoneAreaCode, - Status: "verify", - LoginTime: time.Now(), + Pid: registerInfo.Pid, + TopReferrerId: parentRegister.Pid, + Password: registerInfo.Password, + Salt: inttostring.GenerateRandomString(6), + Email: registerInfo.Email, + InviteCode: inttostring.NewInvite().Encode(int(time.Now().Unix())), + Loginip: registerInfo.IP, + Mobile: registerInfo.Phone, + Area: registerInfo.PhoneAreaCode, + Status: "verify", + LoginTime: time.Now(), ModelTime: cModels.ModelTime{ CreatedAt: time.Now(), UpdatedAt: time.Now(), diff --git a/exchange-single b/exchange-single new file mode 100644 index 0000000..3b907ad Binary files /dev/null and b/exchange-single differ diff --git a/go.mod b/go.mod index 7a05999..348d207 100644 --- a/go.mod +++ b/go.mod @@ -134,6 +134,7 @@ require ( github.com/mitchellh/reflectwalk v1.0.0 // 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/mojocn/base64Captcha v1.3.5 // indirect github.com/nsqio/go-nsq v1.1.0 // indirect github.com/nyaruka/phonenumbers v1.0.55 // indirect @@ -143,6 +144,8 @@ require ( github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/redis/go-redis/v9 v9.3.0 // indirect + github.com/richardlehane/mscfb v1.0.4 // indirect + github.com/richardlehane/msoleps v1.0.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shamsher31/goimgext v1.0.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect @@ -161,10 +164,13 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect + github.com/xuri/excelize/v2 v2.9.0 // indirect + github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/image v0.13.0 // indirect + golang.org/x/image v0.18.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.9.0 // indirect golang.org/x/sys v0.27.0 // indirect diff --git a/models/binancedto/binance.go b/models/binancedto/binance.go index da9423c..fdb64ce 100644 --- a/models/binancedto/binance.go +++ b/models/binancedto/binance.go @@ -22,3 +22,55 @@ type StoplossMarket struct { Symbol string `json:"symbol"` Type int `json:"type" comment:"对冲类型 1-现货 2-合约"` } + +type BinanceSpotOrder struct { + Symbol string `json:"symbol"` // 交易对 + OrderID int64 `json:"orderId"` // 系统的订单ID + OrderListID int64 `json:"orderListId"` // 除非此单是订单列表的一部分, 否则此值为 -1 + ClientOrderID string `json:"clientOrderId"` // 客户自己设置的ID + Price string `json:"price"` // 订单价格 + OrigQty string `json:"origQty"` // 用户设置的原始订单数量 + ExecutedQty string `json:"executedQty"` // 交易的订单数量 + OrigQuoteOrderQty string `json:"origQuoteOrderQty"` // 原始的交易金额 + CummulativeQuoteQty string `json:"cummulativeQuoteQty"` // 累计交易的金额 + Status string `json:"status"` // 订单状态 + TimeInForce string `json:"timeInForce"` // 订单的时效方式 + Type string `json:"type"` // 订单类型,比如市价单,现价单等 + Side string `json:"side"` // 订单方向,买还是卖 + StopPrice string `json:"stopPrice"` // 止损价格 + IcebergQty string `json:"icebergQty"` // 冰山数量 + Time int64 `json:"time"` // 订单时间 + UpdateTime int64 `json:"updateTime"` // 最后更新时间 + IsWorking bool `json:"isWorking"` // 订单是否出现在orderbook中 + WorkingTime int64 `json:"workingTime"` // 订单添加到 order book 的时间 + SelfTradePreventionMode string `json:"selfTradePreventionMode"` // 如何处理自我交易模式 +} + +type BinanceFutureOrder struct { + AvgPrice string `json:"avgPrice"` // 平均成交价 + ClientOrderID string `json:"clientOrderId"` // 用户自定义的订单号 + CumQuote string `json:"cumQuote"` // 成交金额 + ExecutedQty string `json:"executedQty"` // 成交量 + OrderID int64 `json:"orderId"` // 系统订单号 + OrigQty string `json:"origQty"` // 原始委托数量 + OrigType string `json:"origType"` // 触发前订单类型 + Price string `json:"price"` // 委托价格 + ReduceOnly bool `json:"reduceOnly"` // 是否仅减仓 + Side string `json:"side"` // 买卖方向 + PositionSide string `json:"positionSide"` // 持仓方向 + Status string `json:"status"` // 订单状态 + StopPrice string `json:"stopPrice"` // 触发价,对`TRAILING_STOP_MARKET`无效 + ClosePosition bool `json:"closePosition"` // 是否条件全平仓 + Symbol string `json:"symbol"` // 交易对 + Time int64 `json:"time"` // 订单时间 + TimeInForce string `json:"timeInForce"` // 有效方法 + Type string `json:"type"` // 订单类型 + ActivatePrice string `json:"activatePrice"` // 跟踪止损激活价格, 仅`TRAILING_STOP_MARKET` 订单返回此字段 + PriceRate string `json:"priceRate"` // 跟踪止损回调比例, 仅`TRAILING_STOP_MARKET` 订单返回此字段 + UpdateTime int64 `json:"updateTime"` // 更新时间 + WorkingType string `json:"workingType"` // 条件价格触发类型 + PriceProtect bool `json:"priceProtect"` // 是否开启条件单触发保护 + PriceMatch string `json:"priceMatch"` // 盘口价格下单模式 + SelfTradePreventionMode string `json:"selfTradePreventionMode"` // 订单自成交保护模式 + GoodTillDate int64 `json:"goodTillDate"` // 订单TIF为GTD时的自动取消时间 +} diff --git a/services/binanceservice/binancerest.go b/services/binanceservice/binancerest.go index a7e50db..c08d49f 100644 --- a/services/binanceservice/binancerest.go +++ b/services/binanceservice/binancerest.go @@ -9,6 +9,7 @@ import ( "go-admin/common/global" "go-admin/common/helper" "go-admin/models" + "go-admin/models/binancedto" "go-admin/models/spot" "go-admin/pkg/httputils" "go-admin/pkg/utility" @@ -529,3 +530,61 @@ func (e SpotRestApi) GetSpotSymbolLastPrice(targetSymbol string) (lastPrice deci // } return lastPrice } + +func (e SpotRestApi) GetOrderByOrderSn(symbol, orderSn string, apiUserInfo DbModels.LineApiUser) (order binancedto.BinanceSpotOrder, err error) { + result := binancedto.BinanceSpotOrder{} + params := map[string]string{ + "symbol": symbol, + "origClientOrderId": orderSn, + } + + client := GetClient(&apiUserInfo) + + body, code, err := client.SendSpotAuth("/api/v3/order", "GET", params) + if err != nil || code != 200 { + log.Error("查询现货委托 参数:", params) + log.Error("查询现货委托失败 code:", code) + log.Error("查询现货委托失败 err:", err) + dataMap := make(map[string]interface{}) + if err.Error() != "" { + if err := sonic.Unmarshal([]byte(err.Error()), &dataMap); err != nil { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error()) + } + } + + code, ok := dataMap["code"] + if ok { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%s", apiUserInfo.Id, symbol, ErrorMaps[code.(float64)]) + } + if strings.Contains(err.Error(), "Unknown order sent.") { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, ErrorMaps[-2011]) + } + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error()) + } + + sonic.Unmarshal(body, &result) + + if result.OrderID == 0 { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, "订单不存在") + } + + return result, nil +} + +/* +查询现货委托 +*/ +func (e SpotRestApi) GetOrderByOrderSnLoop(symbol, ordersn string, apiUserInfo DbModels.LineApiUser, retryCount int) (order binancedto.BinanceSpotOrder, err error) { + result, err := e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo) + + if err != nil { + for x := 1; x < retryCount; x++ { + result, err = e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo) + if err == nil { + break + } + } + } + + return result, err +} diff --git a/services/binanceservice/binanceservice_test.go b/services/binanceservice/binanceservice_test.go index 402cdb5..2d3bbf5 100644 --- a/services/binanceservice/binanceservice_test.go +++ b/services/binanceservice/binanceservice_test.go @@ -215,3 +215,35 @@ func TestFutOrderPlace(t *testing.T) { fmt.Println("err:", err) } + +func TestFutureQueryOrder(t *testing.T) { + futureApi := FutRestApi{} + // dsn := "root:root@tcp(192.168.1.12:3306)/go_exchange_single?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms" + // db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{}) + + helper.InitDefaultRedis("192.168.1.12:6379", "", 2) + apiUserInfo, _ := GetApiInfo(49) + order, err := futureApi.GetOrderByOrderSnLoop("TRUMPUSDT", "380211842506555392", apiUserInfo, 3) + + if err != nil { + fmt.Println("err:", err) + } + + fmt.Println("future order:", order) +} + +func TestSpotQueryOrder(t *testing.T) { + spotApi := SpotRestApi{} + // dsn := "root:root@tcp(192.168.1.12:3306)/go_exchange_single?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms" + // db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{}) + + helper.InitDefaultRedis("192.168.1.12:6379", "", 2) + apiUserInfo, _ := GetApiInfo(49) + order, err := spotApi.GetOrderByOrderSnLoop("ADAUSDT", "380577197825458177", apiUserInfo, 3) + + if err != nil { + fmt.Println("err:", err) + } + + fmt.Println("spot order:", order) +} diff --git a/services/binanceservice/futuresbinancerest.go b/services/binanceservice/futuresbinancerest.go index 3b9bc95..5130133 100644 --- a/services/binanceservice/futuresbinancerest.go +++ b/services/binanceservice/futuresbinancerest.go @@ -9,6 +9,7 @@ import ( "go-admin/common/global" "go-admin/common/helper" "go-admin/models" + "go-admin/models/binancedto" "go-admin/models/futuresdto" "go-admin/pkg/httputils" "go-admin/pkg/utility" @@ -936,3 +937,66 @@ func (e FutRestApi) GetFutSymbolLastPrice(targetSymbol string) (lastPrice decima // } return lastPrice } + +func (e FutRestApi) GetOrderByOrderSn(symbol, orderSn string, apiUserInfo DbModels.LineApiUser) (order binancedto.BinanceFutureOrder, err error) { + result := binancedto.BinanceFutureOrder{} + params := map[string]string{ + "symbol": symbol, + "origClientOrderId": orderSn, + } + + client := GetClient(&apiUserInfo) + + body, code, err := client.SendFuturesAuth("/fapi/v1/order", "GET", params) + if err != nil || code != 200 { + log.Error("查询合约委托 参数:", params) + log.Error("查询合约委托失败 code:", code) + log.Error("查询合约委托失败 err:", err) + dataMap := make(map[string]interface{}) + if err.Error() != "" { + if err := sonic.Unmarshal([]byte(err.Error()), &dataMap); err != nil { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error()) + } + } + + code, ok := dataMap["code"] + if ok { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%s", apiUserInfo.Id, symbol, ErrorMaps[code.(float64)]) + } + if strings.Contains(err.Error(), "Unknown order sent.") { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, ErrorMaps[-2011]) + } + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, err.Error()) + } + + sonic.Unmarshal(body, &result) + + if result.OrderID == 0 { + return result, fmt.Errorf("api_id:%d 交易对:%s 查询订单失败:%+v", apiUserInfo.Id, symbol, "订单不存在") + } + + return result, nil +} + +/* +查询现货委托 +*/ +// 根据订单号获取订单信息,如果获取失败,则进行重试 +func (e FutRestApi) GetOrderByOrderSnLoop(symbol, ordersn string, apiUserInfo DbModels.LineApiUser, retryCount int) (order binancedto.BinanceFutureOrder, err error) { + result, err := e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo) + // 如果获取失败,则进行重试 + + if err != nil { + // 调用GetOrderByOrderSn方法获取订单信息 + for x := 1; x < retryCount; x++ { + // 如果获取成功,则跳出循环 + result, err = e.GetOrderByOrderSn(symbol, ordersn, apiUserInfo) + if err == nil { + break + } + } + } + // 返回订单信息和错误信息 + + return result, err +} diff --git a/services/binanceservice/futuresjudgeservice.go b/services/binanceservice/futuresjudgeservice.go index 9ef8194..2966fc7 100644 --- a/services/binanceservice/futuresjudgeservice.go +++ b/services/binanceservice/futuresjudgeservice.go @@ -88,7 +88,7 @@ func futTriggerOrder(db *gorm.DB, v *dto.PreOrderRedisList, item string, futApi } //判断是否有已触发交易对 - count, _ := GetSymbolTriggerCount(db, v.Symbol, 2) + count, _ := GetSymbolTriggerCount(db, v.Symbol, v.ApiId, 2) if count > 0 { return @@ -137,7 +137,11 @@ func futTriggerOrder(db *gorm.DB, v *dto.PreOrderRedisList, item string, futApi } } - if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Update("status", "1").Error; err != nil { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? ", preOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + log.Error("更新预下单状态失败 ordersn:", preOrder.OrderSn, " status:1") + } + + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Updates(map[string]interface{}{"status": "1"}).Error; err != nil { log.Error("更新预下单状态失败 ordersn:", v.OrderSn, " status:1") } @@ -260,6 +264,15 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes Updates(map[string]interface{}{"status": 2, "desc": err.Error()}).Error; err2 != nil { log.Errorf("合约减仓更新状态失败 id:%s err:%v", reduceOrder.Id, err2) } + } else { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? ", reduceOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + log.Error("更新减仓单状态失败 ordersn:", reduceOrder.OrderSn, " status:1") + } + + if err := db.Model(&DbModels.LinePreOrder{}). + Where("id = ? AND status =0", reduceOrder.Id).Updates(map[string]interface{}{"status": 1}).Error; err != nil { + log.Errorf("合约减仓更新状态失败 id:%s err:%v", reduceOrder.Id, err) + } } if _, err := helper.DefaultRedis.LRem(key, item); err != nil { @@ -270,7 +283,7 @@ func FuturesReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, futApi FutRes } } -// 判断现货加仓 +// 判断合约加仓 func JudgeFutAddPosition(trade models.TradeSet) { key := fmt.Sprintf(rediskey.FuturesAddPositionList, global.EXCHANGE_BINANCE) preOrderVal, _ := helper.DefaultRedis.GetAllList(key) @@ -316,7 +329,7 @@ func FutAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, futApi defer lock.Release() setting, _ := GetSystemSetting(db) - tradeSet, _ := GetTradeSet(v.Symbol, 0) + tradeSet, _ := GetTradeSet(v.Symbol, 1) if tradeSet.LastPrice == "" { log.Errorf("合约加仓触发 查询交易对失败 交易对:%s ordersn:%s", v.Symbol, v.OrderSn) @@ -384,7 +397,11 @@ func FutAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, futApi } } - if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Update("status", "1").Error; err != nil { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? ", preOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + log.Error("更新预下单状态失败 ordersn:", v.OrderSn, " status:1") + } + + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Updates(map[string]interface{}{"status": "1"}).Error; err != nil { log.Error("更新预下单状态失败 ordersn:", v.OrderSn, " status:1") } return diff --git a/services/binanceservice/futuresrest.go b/services/binanceservice/futuresrest.go index 997ac06..5f2472f 100644 --- a/services/binanceservice/futuresrest.go +++ b/services/binanceservice/futuresrest.go @@ -111,16 +111,20 @@ func handleFutOrderByType(db *gorm.DB, preOrder *DbModels.LinePreOrder, orderSta // 减仓回调 func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { + if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id =? ", preOrder.MainId).Update("reduce_status", 1).Error; err != nil { + logger.Errorf("handleReduceFilled 更新主单减仓状态失败,订单号:%s", preOrder.OrderSn) + } + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) if apiUserInfo.Id == 0 { - logger.Errorf("handleMainReduceFilled 获取api信息失败,订单号:%s", preOrder.OrderSn) + logger.Errorf("handleReduceFilled 获取api信息失败,订单号:%s", preOrder.OrderSn) return } tradeSet, err := GetTradeSet(preOrder.Symbol, 1) if err != nil { - logger.Errorf("handleMainReduceFilled 获取交易对设置失败,订单号:%s", preOrder.OrderSn) + logger.Errorf("handleReduceFilled 获取交易对设置失败,订单号:%s", preOrder.OrderSn) return } @@ -128,7 +132,7 @@ func handleReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { parentOrder, err := GetOrderById(db, preOrder.Pid) if err != nil { - logger.Errorf("handleMainReduceFilled 获取主单失败,订单号:%s", preOrder.OrderSn) + logger.Errorf("handleReduceFilled 获取主单失败,订单号:%s", preOrder.OrderSn) return } parentPrice := utility.StrToDecimal(parentOrder.Price) @@ -272,6 +276,16 @@ func getFuturesPositionNum(apiUserInfo DbModels.LineApiUser, preOrder *DbModels. // 平仓单成交 func handleClosePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeFutLossAndAddPosition(preOrder) + + futApi := FutRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + if err := futApi.CancelAllFutOrder(apiUserInfo, preOrder.Symbol); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + ids := []int{preOrder.Pid, preOrder.MainId} //主单止盈成交 if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ?", ids).Update("status", 9).Error; err != nil { @@ -282,6 +296,20 @@ func handleClosePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) { // 止损单成交 func handleStopLoss(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeFutLossAndAddPosition(preOrder) + + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + ids := []int{preOrder.Pid, preOrder.MainId} //主单止损成交 if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ?", ids).Update("status", 9).Error; err != nil { @@ -293,6 +321,15 @@ func handleStopLoss(db *gorm.DB, preOrder *DbModels.LinePreOrder) { func handleTakeProfit(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeFutLossAndAddPosition(preOrder) + futApi := FutRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + if err := futApi.CancelAllFutOrder(apiUserInfo, preOrder.Symbol); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + ids := []int{preOrder.Pid, preOrder.MainId} //主单止盈成交 if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ? AND order_type=0", ids).Update("status", 9).Error; err != nil { @@ -353,7 +390,7 @@ func removeFutLossAndAddPosition(preOrder *DbModels.LinePreOrder) { // preOrder 主单 func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) { orders := []models.LinePreOrder{} - tradeSet, _ := GetTradeSet(preOrder.Symbol, 0) + tradeSet, _ := GetTradeSet(preOrder.Symbol, 1) if tradeSet.Coin == "" { logger.Error("获取交易对失败") @@ -366,6 +403,10 @@ func handleFutMainOrderFilled(db *gorm.DB, preOrder *models.LinePreOrder) { } if preOrder.OrderCategory == 3 { + if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id = ?", preOrder.MainId).Update("add_position_status", 1).Error; err != nil { + logger.Errorf("更新主单加仓状态失败, 主单号:%s, 错误信息:%v", preOrder.MainId, err) + } + if err := cancelSymbolTakeAndStop(db, preOrder.MainId, preOrder.SymbolType); err != nil { logger.Errorf("取消止盈止损订单失败 orderSn:%s err:%v", preOrder.OrderSn, err) } @@ -469,6 +510,10 @@ func processFutTakeProfitOrder(db *gorm.DB, futApi FutRestApi, order models.Line logger.Error("合约止盈下单失败,更新状态失败:", order.OrderSn, " err:", err) } } else { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? ", order.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + logger.Error("更新合约止盈单触发事件 ordersn:", order.OrderSn) + } + if err := db.Model(&DbModels.LinePreOrder{}).Where("id = ? and status =0", order.Id). Updates(map[string]interface{}{"status": "1", "num": num.String()}).Error; err != nil { logger.Error("合约止盈下单成功,更新状态失败:", order.OrderSn, " err:", err) @@ -499,6 +544,10 @@ func processFutStopLossOrder(db *gorm.DB, order models.LinePreOrder, price, num logger.Error("合约止损下单失败,更新状态失败:", order.OrderSn, " err:", err2) } } else { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? ", order.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + logger.Error("更新合约止损单触发事件 ordersn:", order.OrderSn) + } + if err := db.Model(&order).Where("status =0"). Updates(map[string]interface{}{"status": "1"}).Error; err != nil { logger.Error("合约止损下单成功,更新状态失败:", order.OrderSn, " err:", err) diff --git a/services/binanceservice/orderservice.go b/services/binanceservice/orderservice.go index 8454c8f..1d242a3 100644 --- a/services/binanceservice/orderservice.go +++ b/services/binanceservice/orderservice.go @@ -144,10 +144,10 @@ func GetSymbolTakeAndStop(db *gorm.DB, mainId int, symbolType int) ([]models.Lin // 获取交易对触发数量 // symbol 交易对 // symbolType 交易对类型 1-现货 2-合约 -func GetSymbolTriggerCount(db *gorm.DB, symbol string, symbolType int) (int64, error) { +func GetSymbolTriggerCount(db *gorm.DB, symbol string, apiId, symbolType int) (int64, error) { var count int64 - if err := db.Model(&models.LinePreOrder{}).Where("symbol =? AND symbol_type =? AND order_type =0 AND pid=0 AND status IN (1,5,6)", symbol, symbolType).Count(&count).Error; err != nil { + if err := db.Model(&models.LinePreOrder{}).Where("symbol =? AND api_id =? AND symbol_type =? AND order_type =0 AND pid=0 AND status IN (1,5,6)", symbol, apiId, symbolType).Count(&count).Error; err != nil { logger.Error("查询交易对触发数量失败:", err) return count, err } diff --git a/services/binanceservice/spotjudgeservice.go b/services/binanceservice/spotjudgeservice.go index 9836eeb..da383e4 100644 --- a/services/binanceservice/spotjudgeservice.go +++ b/services/binanceservice/spotjudgeservice.go @@ -84,7 +84,7 @@ func SpotOrderLock(db *gorm.DB, v *dto.PreOrderRedisList, item string, spotApi S } //判断是否有已触发交易对 - count, _ := GetSymbolTriggerCount(db, v.Symbol, 2) + count, _ := GetSymbolTriggerCount(db, v.Symbol, v.ApiId, 1) if count > 0 { return @@ -127,7 +127,7 @@ func SpotOrderLock(db *gorm.DB, v *dto.PreOrderRedisList, item string, spotApi S } } - if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Update("status", "1").Error; err != nil { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? ", preOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { log.Error("更新预下单状态失败 ordersn:", v.OrderSn, " status:1") } return @@ -244,11 +244,16 @@ func SpotStopLossTrigger(db *gorm.DB, stopOrder dto.StopLossRedisList, spotApi S if err := spotApi.OrderPlaceLoop(db, params, 3); err != nil { log.Errorf("现货止损挂单失败 id:%s err:%v", stopOrder.Id, err) + } else { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id = ? ", stopOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + log.Errorf("现货止损更新状态失败 id:%s err:%v", stopOrder.Id, err) + } } if _, err := helper.DefaultRedis.LRem(key, item); err != nil { log.Errorf("现货止损 删除缓存失败 id:%v err:%v", stopOrder.Id, err) } + } else { log.Error("获取锁失败") } @@ -356,6 +361,16 @@ func SpotReduceTrigger(db *gorm.DB, reduceOrder ReduceListItem, spotApi SpotRest Updates(map[string]interface{}{"status": 2, "desc": err.Error()}).Error; err2 != nil { log.Errorf("修改现货减仓状态失败 id:%s err:%v", reduceOrder.Id, err2) } + } else { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =?", reduceOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + log.Error("更新预下单触发事件失败 ordersn:", reduceOrder.OrderSn) + } + + if err := db.Model(&DbModels.LinePreOrder{}). + Where("id =? AND status =0", reduceOrder.Id). + Updates(map[string]interface{}{"status": 1}).Error; err != nil { + log.Errorf("修改现货减仓状态失败 id:%s err:%v", reduceOrder.Id, err) + } } if _, err := helper.DefaultRedis.LRem(key, item); err != nil { @@ -474,7 +489,11 @@ func SpotAddPositionTrigger(db *gorm.DB, v *AddPositionList, item string, spotAp } } - if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Update("status", "1").Error; err != nil { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =?", preOrder.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + log.Error("更新预下单触发事件失败 ordersn:", v.OrderSn) + } + + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? AND status ='0'", preOrder.Id).Updates(map[string]interface{}{"status": "1"}).Error; err != nil { log.Error("更新预下单状态失败 ordersn:", v.OrderSn, " status:1") } return diff --git a/services/binanceservice/spotreset.go b/services/binanceservice/spotreset.go index 916eead..40ce946 100644 --- a/services/binanceservice/spotreset.go +++ b/services/binanceservice/spotreset.go @@ -136,6 +136,19 @@ func handleOrderByType(db *gorm.DB, preOrder *DbModels.LinePreOrder, orderStatus if err := db.Model(&DbModels.LinePreOrder{}).Where("main_id =? AND status =0", preOrder.MainId).Update("status", 4).Error; err != nil { logger.Errorf("主单止损回调 订单号:%s 修改主单状态失败:%v", preOrder.OrderSn, err) } + + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } } } @@ -158,6 +171,10 @@ func handleMainReduceFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { orders := make([]models.LinePreOrder, 0) rate := utility.StringAsFloat(preOrder.Rate) + if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id =? ", preOrder.MainId).Update("reduce_status", 1).Error; err != nil { + logger.Errorf("handleMainReduceFilled 更新主单减仓状态失败,订单号:%s", preOrder.OrderSn) + } + // 100%减仓 终止流程 if rate >= 100 { removeSpotLossAndAddPosition(preOrder) @@ -357,16 +374,41 @@ func handleMainOrderClosePosition(db *gorm.DB, preOrder *DbModels.LinePreOrder) return nil }) - } removeSpotLossAndAddPosition(preOrder) + + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } } // 止盈成交 func handleSpotTakeProfitFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { removeSpotLossAndAddPosition(preOrder) + spotApi := SpotRestApi{} + apiUserInfo, _ := GetApiInfo(preOrder.ApiId) + + if apiUserInfo.Id > 0 { + req := CancelOpenOrdersReq{ + Symbol: preOrder.Symbol, + ApiId: preOrder.ApiId, + } + if err := spotApi.CancelOpenOrders(db, req); err != nil { + logger.Errorf("止盈单成功 取消其它订单失败 订单号:%s:", err) + } + } + db.Transaction(func(tx *gorm.DB) error { ids := []int{preOrder.Pid, preOrder.MainId} if err := db.Model(&DbModels.LinePreOrder{}).Where("id IN ? AND status =6 AND order_type=0", ids).Update("status", 9).Error; err != nil { @@ -436,6 +478,12 @@ func removeSpotLossAndAddPosition(preOrder *DbModels.LinePreOrder) { // 主单成交 func handleMainOrderFilled(db *gorm.DB, preOrder *DbModels.LinePreOrder) { + if preOrder.OrderCategory == 3 { + if err := db.Model(&DbModels.LinePreOrderStatus{}).Where("order_id = ?", preOrder.MainId).Update("add_position_status", 1).Error; err != nil { + logger.Errorf("更新主单加仓状态失败, 主单号:%s, 错误信息:%v", preOrder.MainId, err) + } + } + processTakeProfitAndStopLossOrders(db, preOrder) } @@ -638,6 +686,9 @@ func processTakeProfitOrder(db *gorm.DB, spotApi SpotRestApi, order models.LineP logger.Error("现货止盈下单失败,更新状态失败:", order.OrderSn, " err:", err) } } else { + if err := db.Model(&DbModels.LinePreOrder{}).Where("id =? ", order.Id).Updates(map[string]interface{}{"trigger_time": time.Now()}).Error; err != nil { + logger.Error("更新现货止盈单触发事件 ordersn:", order.OrderSn) + } if err := db.Model(&DbModels.LinePreOrder{}).Where("id = ? and status ='0'", order.Id). Updates(map[string]interface{}{"status": "1", "num": order.Num}).Error; err != nil { logger.Error("现货止盈下单成功,更新状态失败:", order.OrderSn, " err:", err) diff --git a/services/excservice/binancesocketmanager.go b/services/excservice/binancesocketmanager.go index 45b428a..ae94624 100644 --- a/services/excservice/binancesocketmanager.go +++ b/services/excservice/binancesocketmanager.go @@ -79,13 +79,17 @@ func (wm *BinanceWebSocketManager) Start() { // 重启连接 func (wm *BinanceWebSocketManager) Restart(apiKey, apiSecret, proxyType, proxyAddress string) *BinanceWebSocketManager { + wm.mu.Lock() + defer wm.mu.Unlock() + wm.apiKey = apiKey wm.apiSecret = apiSecret wm.proxyType = proxyType wm.proxyAddress = proxyAddress if wm.isStopped { - wm.run() + wm.isStopped = false + utility.SafeGo(wm.run) } else { wm.reconnect <- struct{}{} } @@ -385,7 +389,12 @@ func (wm *BinanceWebSocketManager) Stop() { } wm.isStopped = true - close(wm.stopChannel) + // 关闭 stopChannel(确保已经关闭,避免 panic) + select { + case <-wm.stopChannel: + default: + close(wm.stopChannel) + } if wm.cancelFunc != nil { wm.cancelFunc() @@ -398,6 +407,9 @@ func (wm *BinanceWebSocketManager) Stop() { log.Info(fmt.Sprintf("key【%s】close", wm.apiKey)) } } + + // **重新创建 stopChannel,避免 Restart() 时无效** + wm.stopChannel = make(chan struct{}) } // 重连机制