1
This commit is contained in:
		
							
								
								
									
										191
									
								
								app/admin/apis/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								app/admin/apis/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							| @ -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 LineUserSetting 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.LineUserSetting}} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/line-user-setting [get] | ||||
| // @Security Bearer | ||||
| func (e LineUserSetting) GetPage(c *gin.Context) { | ||||
|     req := dto.LineUserSettingGetPageReq{} | ||||
|     s := service.LineUserSetting{} | ||||
|     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.LineUserSetting, 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.LineUserSetting} "{"code": 200, "data": [...]}" | ||||
| // @Router /api/v1/line-user-setting/{id} [get] | ||||
| // @Security Bearer | ||||
| func (e LineUserSetting) Get(c *gin.Context) { | ||||
| 	req := dto.LineUserSettingGetReq{} | ||||
| 	s := service.LineUserSetting{} | ||||
|     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.LineUserSetting | ||||
|  | ||||
| 	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.LineUserSettingInsertReq true "data" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "添加成功"}" | ||||
| // @Router /api/v1/line-user-setting [post] | ||||
| // @Security Bearer | ||||
| func (e LineUserSetting) Insert(c *gin.Context) { | ||||
|     req := dto.LineUserSettingInsertReq{} | ||||
|     s := service.LineUserSetting{} | ||||
|     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.LineUserSettingUpdateReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "修改成功"}" | ||||
| // @Router /api/v1/line-user-setting/{id} [put] | ||||
| // @Security Bearer | ||||
| func (e LineUserSetting) Update(c *gin.Context) { | ||||
|     req := dto.LineUserSettingUpdateReq{} | ||||
|     s := service.LineUserSetting{} | ||||
|     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.LineUserSettingDeleteReq true "body" | ||||
| // @Success 200 {object} response.Response	"{"code": 200, "message": "删除成功"}" | ||||
| // @Router /api/v1/line-user-setting [delete] | ||||
| // @Security Bearer | ||||
| func (e LineUserSetting) Delete(c *gin.Context) { | ||||
|     s := service.LineUserSetting{} | ||||
|     req := dto.LineUserSettingDeleteReq{} | ||||
|     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(), "删除成功") | ||||
| } | ||||
| @ -4,6 +4,7 @@ import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/gin-gonic/gin/binding" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" | ||||
| 	_ "github.com/go-admin-team/go-admin-core/sdk/pkg/response" | ||||
| @ -32,7 +33,7 @@ func (e MemberRenwaLog) GetPage(c *gin.Context) { | ||||
| 	s := service.MemberRenwaLog{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
|         Bind(&req). | ||||
| 		Bind(&req, binding.Form, binding.Query). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
|  | ||||
| @ -112,6 +112,12 @@ func (e MemberRenwalConfig) Insert(c *gin.Context) { | ||||
| 		e.Error(500, err, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if err := req.Valid(); err != nil { | ||||
| 		e.Error(500, err, "") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// 设置创建人 | ||||
| 	req.SetCreateBy(user.GetUserId(c)) | ||||
|  | ||||
| @ -148,6 +154,12 @@ func (e MemberRenwalConfig) Update(c *gin.Context) { | ||||
| 		e.Error(500, err, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if err := req.Valid(); err != nil { | ||||
| 		e.Error(500, err, "") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	req.SetUpdateBy(user.GetUserId(c)) | ||||
| 	p := actions.GetPermissionFromContext(c) | ||||
|  | ||||
|  | ||||
| @ -76,7 +76,7 @@ func (e SysDictData) Get(c *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	var object models.SysDictData | ||||
| 	var object dto.SysDictDataResp | ||||
|  | ||||
| 	err = s.Get(&req, &object) | ||||
| 	if err != nil { | ||||
|  | ||||
							
								
								
									
										37
									
								
								app/admin/fronted/common.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/admin/fronted/common.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| package fronted | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/app/admin/service/appservice" | ||||
| 	"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 Common struct { | ||||
| 	api.Api | ||||
| } | ||||
|  | ||||
| // 获取默认设置 | ||||
| func (e Common) GetDefaultSet(c *gin.Context) { | ||||
| 	s := appservice.Common{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| 		e.Logger.Error(err) | ||||
| 		e.Error(statuscode.ServerError, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.ServerError)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	data, code := s.GetDefaultSet() | ||||
|  | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(data, "success") | ||||
| } | ||||
| @ -119,7 +119,7 @@ func (e LineUserApi) VerifyEmail(c *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 	// 核验邮箱验证码 | ||||
| 	code := authservice.UserVerifyEmail(req.Email, req.VerifyCode, e.Orm) | ||||
| 	code := authservice.UserVerifyEmail(req.Email, req.VerifyCode, 0, e.Orm) | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| @ -133,7 +133,7 @@ func (e LineUserApi) VerifyEmail(c *gin.Context) { | ||||
|  | ||||
| } | ||||
|  | ||||
| // SendVerifyEmail 发送注册校验邮箱 | ||||
| // SendVerifyEmail 发送邮箱 | ||||
| func (e LineUserApi) SendVerifyEmail(c *gin.Context) { | ||||
| 	s := service.LineUser{} | ||||
| 	req := dto.FrontedSendVerifyEmailReq{} | ||||
| @ -154,7 +154,8 @@ func (e LineUserApi) SendVerifyEmail(c *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 	emailCode := inttostring.GenerateRandomString(10) | ||||
| 	code = authservice.SendRegisterEmail(req.Email, emailCode) | ||||
| 	language := common.GetLanguage(c) | ||||
| 	code = authservice.SendRegisterEmail(req.Email, emailCode, req.Type, language) | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| @ -183,13 +184,15 @@ func (e LineUserApi) SendRegisterSms(c *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if req.Type == 0 { | ||||
| 		user, _ := aduserdb.GetUserByPhone(e.Orm, req.PhoneAreaCode, req.Phone) | ||||
| 		if user.Id > 0 { | ||||
| 			e.Error(statuscode.TheAccountIsAlreadyRegistered, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.TheAccountIsAlreadyRegistered)) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	code = authservice.SendGoToneSms(req.Phone, req.PhoneAreaCode) | ||||
| 	code = authservice.SendGoToneSms(req.Phone, req.PhoneAreaCode, req.Type) | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| @ -346,9 +349,11 @@ func (e LineUserApi) GetWhiteIp(c *gin.Context) { | ||||
| // Info 用户中心 | ||||
| func (e LineUserApi) Info(c *gin.Context) { | ||||
| 	s := service.LineUser{} | ||||
| 	balance := service.MemberBalance{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		MakeService(&s.Service). | ||||
| 		MakeService(&balance.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| 		e.Logger.Error(err) | ||||
| @ -404,11 +409,15 @@ func (e LineUserApi) Info(c *gin.Context) { | ||||
| 		fundingAsset = resp[0:] | ||||
| 	} | ||||
|  | ||||
| 	balanceData, _ := balance.GetBalance(userId) | ||||
|  | ||||
| 	//获取盈利情况 | ||||
| 	logs := service.LineUserProfitLogs{Service: s.Service} | ||||
| 	totalProfit, todayProfit := logs.GetProfitInfoByUserId(userinfo.Id) | ||||
| 	user := map[string]interface{}{ | ||||
| 		"avatar":      userinfo.Avatar, | ||||
| 		"user_id":     userinfo.Id, | ||||
| 		"user_name":   userinfo.Nickname, | ||||
| 		"invite_num":  userinfo.RecommendNum, | ||||
| 		"open_status": apiUserinfo.OpenStatus, | ||||
| 		"is_auth":     isAuth, | ||||
| @ -425,6 +434,11 @@ func (e LineUserApi) Info(c *gin.Context) { | ||||
| 		"funding_asset": fundingAsset, | ||||
| 		"total_profit":  totalProfit.Float64, | ||||
| 		"today_profit":  todayProfit.Float64, | ||||
| 		"balance": map[string]interface{}{ //系统余额 | ||||
| 			"total_amount":  balanceData.TotalAmount, | ||||
| 			"free_amount":   balanceData.FreeAmount, | ||||
| 			"frozen_amount": balanceData.FrozenAmount, | ||||
| 		}, | ||||
| 	} | ||||
| 	e.OK(returnMap, "success") | ||||
|  | ||||
| @ -634,3 +648,82 @@ func (e LineUserApi) GetProperty(c *gin.Context) { | ||||
|  | ||||
| 	e.OK(data, "success") | ||||
| } | ||||
|  | ||||
| // 获取到期时间 | ||||
| func (e LineUserApi) GetUserInfo(c *gin.Context) { | ||||
| 	s := appservice.LineUser{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| 		e.Logger.Error(err) | ||||
| 		e.Error(statuscode.ServerError, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.ServerError)) | ||||
| 	} | ||||
|  | ||||
| 	userId := common.GetUserId(c) | ||||
| 	var data dto.LineUserAppResp | ||||
| 	code := s.GetUserInfo(userId, &data) | ||||
|  | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(data, "success") | ||||
| } | ||||
|  | ||||
| // 用户下单设置 | ||||
| func (e LineUserApi) UserOrderSet(c *gin.Context) { | ||||
| 	s := service.LineUser{} | ||||
| 	req := dto.LineUserOrderSetReq{} | ||||
|  | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		Bind(&req). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| 		e.Logger.Error(err) | ||||
| 		e.Error(statuscode.ServerError, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.ServerError)) | ||||
| 	} | ||||
|  | ||||
| 	userId := common.GetUserId(c) | ||||
| 	code := s.OrderSet(&req, userId) | ||||
|  | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(nil, "success") | ||||
| } | ||||
|  | ||||
| func (e LineUserApi) ResetPassword(c *gin.Context) { | ||||
| 	s := service.LineUser{} | ||||
| 	req := dto.LineUserResetPwdReq{} | ||||
|  | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		Bind(&req). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| 		e.Logger.Error(err) | ||||
| 		e.Error(statuscode.ServerError, nil, sysstatuscode.GetStatusCodeDescription(c, statuscode.ServerError)) | ||||
| 	} | ||||
|  | ||||
| 	if code := req.Valid(); code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	code := s.ResetPassword(&req) | ||||
|  | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	e.OK(nil, "success") | ||||
| } | ||||
|  | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 	statuscode "go-admin/common/status_code" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/gin-gonic/gin/binding" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||
| ) | ||||
|  | ||||
| @ -21,7 +22,7 @@ func (e MemberBalanceLog) GetPage(c *gin.Context) { | ||||
| 	req := dto.MemberBalanceLogPageAppReq{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		Bind(&req). | ||||
| 		Bind(&req, binding.Form, binding.Query). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| @ -30,6 +31,7 @@ func (e MemberBalanceLog) GetPage(c *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 	req.UserId = common.GetUserId(c) | ||||
| 	req.Language = common.GetLanguage(c) | ||||
| 	data := make([]dto.MemberBalanceLogAppResp, 0) | ||||
| 	var count int64 | ||||
| 	code := s.GetPage(&req, &data, &count) | ||||
|  | ||||
| @ -4,6 +4,7 @@ import ( | ||||
| 	"go-admin/app/admin/service/appservice" | ||||
| 	statuscode "go-admin/common/status_code" | ||||
|  | ||||
| 	"go-admin/common/service/common" | ||||
| 	"go-admin/common/service/sysservice/sysstatuscode" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| @ -27,7 +28,9 @@ func (e MemberRenwalConfig) GetActiveList(c *gin.Context) { | ||||
| 		e.Error(500, err, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	data, code := s.GetList() | ||||
|  | ||||
| 	language := common.GetLanguage(c) | ||||
| 	data, code := s.GetList(language) | ||||
|  | ||||
| 	if code != statuscode.OK { | ||||
| 		e.Error(code, nil, sysstatuscode.GetStatusCodeDescription(c, code)) | ||||
|  | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 	statuscode "go-admin/common/status_code" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/gin-gonic/gin/binding" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/api" | ||||
| ) | ||||
|  | ||||
| @ -21,7 +22,7 @@ func (e MemberRenwalLog) GetPage(c *gin.Context) { | ||||
| 	req := dto.MemberRenwalLogPageAppReq{} | ||||
| 	err := e.MakeContext(c). | ||||
| 		MakeOrm(). | ||||
| 		Bind(&req). | ||||
| 		Bind(&req, binding.Form, binding.Query). | ||||
| 		MakeService(&s.Service). | ||||
| 		Errors | ||||
| 	if err != nil { | ||||
| @ -30,6 +31,7 @@ func (e MemberRenwalLog) GetPage(c *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 	userId := common.GetUserId(c) | ||||
| 	req.Language = common.GetLanguage(c) | ||||
| 	data := make([]dto.MemberRenwalLogResp, 0) | ||||
| 	var count int64 | ||||
| 	code := s.GetPage(userId, &req, &data, &count) | ||||
|  | ||||
							
								
								
									
										34
									
								
								app/admin/models/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/admin/models/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| package models | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"go-admin/common/models" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| type LineUserSetting struct { | ||||
| 	models.Model | ||||
|  | ||||
| 	UserId               int             `json:"userId" gorm:"type:bigint;comment:用户ID"` | ||||
| 	MinOrderAmount       decimal.Decimal `json:"minOrderAmount" gorm:"type:decimal(32,8);comment:单笔最小金额"` | ||||
| 	SpotUsdtFreeAmount   decimal.Decimal `json:"spotUsdtFreeAmount" gorm:"type:decimal(32,8);comment:现货USDT可用余额"` | ||||
| 	FutureUsdtFreeAmount decimal.Decimal `json:"futureUsdtFreeAmount" gorm:"type:decimal(32,8);comment:合约USDT可用余额"` | ||||
| 	AssetUpdateTime      *time.Time      `json:"assetUpdateTime" gorm:"type:datetime;comment:资产更新时间"` | ||||
| 	models.ModelTime | ||||
| 	models.ControlBy | ||||
| } | ||||
|  | ||||
| func (LineUserSetting) TableName() string { | ||||
| 	return "line_user_setting" | ||||
| } | ||||
|  | ||||
| func (e *LineUserSetting) Generate() models.ActiveRecord { | ||||
| 	o := *e | ||||
| 	return &o | ||||
| } | ||||
|  | ||||
| func (e *LineUserSetting) GetId() interface{} { | ||||
| 	return e.Id | ||||
| } | ||||
| @ -10,7 +10,7 @@ type MemberBalance struct { | ||||
| 	models.Model | ||||
|  | ||||
| 	UserId       int             `json:"userId" gorm:"type:bigint;comment:用户id"` | ||||
| 	TotalAmont   decimal.Decimal `json:"totalAmont" gorm:"type:decimal(18,6);comment:总余额"` | ||||
| 	TotalAmount  decimal.Decimal `json:"totalAmount" 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 | ||||
|  | ||||
| @ -11,6 +11,8 @@ import ( | ||||
| type MemberRenwaLog struct { | ||||
| 	models.Model | ||||
|  | ||||
| 	NetworkName         string          `json:"networkName" gorm:"type:varchar(255);comment:网络名称"` | ||||
| 	ReceiveAddress      string          `json:"receiveAddress" gorm:"type:varchar(255);comment:接收地址"` | ||||
| 	RenwalId            int             `json:"renwalId" gorm:"type:bigint;comment:套餐id"` | ||||
| 	UserId              int             `json:"userId" gorm:"type:bigint;comment:用户id"` | ||||
| 	RenwalName          string          `json:"renwalName" gorm:"type:varchar(255);comment:续期套餐名称"` | ||||
| @ -23,6 +25,7 @@ type MemberRenwaLog struct { | ||||
| 	PaymentTime         *time.Time      `json:"paymentTime" gorm:"type:datetime;comment:支付时间"` | ||||
| 	Hash                string          `json:"hash" gorm:"type:varchar(255);comment:交易hash"` | ||||
| 	ExpirationTime      time.Time       `json:"expirationTime" gorm:"type:datetime;comment:到期时间"` | ||||
| 	NickName            string          `json:"nickName" gorm:"-"` | ||||
| 	models.ModelTime | ||||
| 	models.ControlBy | ||||
| } | ||||
|  | ||||
| @ -10,6 +10,7 @@ type MemberRenwalConfig struct { | ||||
| 	models.Model | ||||
|  | ||||
| 	PackageName   string          `json:"packageName" gorm:"type:varchar(255);comment:套餐名称"` | ||||
| 	PackageNameEn string          `json:"packageNameEn" 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为未设置"` | ||||
|  | ||||
| @ -22,6 +22,8 @@ type MemberWithdrawalLog struct { | ||||
| 	ConfirmTime *time.Time      `json:"confirmTime" gorm:"type:datetime;comment:确认时间"` | ||||
| 	Fee         decimal.Decimal `json:"fee" gorm:"type:decimal(10,2);comment:手续费比例"` | ||||
| 	Remark      string          `json:"remark" gorm:"type:varchar(255);comment:备注"` | ||||
| 	UserName    string          `json:"userName" gorm:"-"` | ||||
| 	NickName    string          `json:"nickName" gorm:"-"` | ||||
| 	models.ModelTime | ||||
| 	models.ControlBy | ||||
| } | ||||
|  | ||||
| @ -16,6 +16,7 @@ type SysDictData struct { | ||||
| 	Status    int    `json:"status" gorm:"size:4;comment:Status"` | ||||
| 	Default   string `json:"default" gorm:"size:8;comment:Default"` | ||||
| 	Remark    string `json:"remark" gorm:"size:255;comment:Remark"` | ||||
| 	Language  string `json:"language" gorm:"type:text;comment:多语言(json)"` | ||||
| 	models.ControlBy | ||||
| 	models.ModelTime | ||||
| } | ||||
|  | ||||
| @ -22,7 +22,7 @@ type FrontedUserRegisterReq struct { | ||||
| 	InviteCode    string `json:"invite_code"`     // 邀请码 | ||||
| 	IP            string `json:"-"`               // IP | ||||
| 	Pid           int    `json:"-"`               // 推荐人ID | ||||
|  | ||||
| 	Language      string `json:"-"`               //语言 | ||||
| } | ||||
|  | ||||
| // CheckParams 校验邮箱参数 | ||||
|  | ||||
| @ -3,10 +3,11 @@ package router | ||||
| import ( | ||||
| 	"os" | ||||
|  | ||||
| 	common "go-admin/common/middleware" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	log "github.com/go-admin-team/go-admin-core/logger" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk" | ||||
| 	common "go-admin/common/middleware" | ||||
| ) | ||||
|  | ||||
| // InitRouter 路由初始化,不要怀疑,这里用到了 | ||||
|  | ||||
| @ -47,6 +47,9 @@ func frontedRegisterLinUserRouter(v1 *gin.RouterGroup) { | ||||
| 	r.POST("/updateApiAuth", middleware.FrontedAuth, api.UpdateApiKey) //用户手动修改Apikey | ||||
| 	r.POST("/opStatus", middleware.FrontedAuth, api.OpenStatus)        //开启或者关闭状态 | ||||
| 	r.DELETE("/logout", middleware.FrontedAuth, api.Logout)            //退出登录 | ||||
| 	r.GET("user-info", middleware.FrontedAuth, api.GetUserInfo)        //用户详情 | ||||
| 	r.PUT("order-set", middleware.FrontedAuth, api.UserOrderSet)       //用户下单设置 | ||||
| 	r.PUT("reset-pwd", api.ResetPassword)                              //重置密码 | ||||
|  | ||||
| 	r.GET("/exchange-balance", middleware.FrontedAuth, api.GetProperty) //合约用户交易所u资产 | ||||
|  | ||||
| @ -60,6 +63,11 @@ func frontedRegisterLinUserRouter(v1 *gin.RouterGroup) { | ||||
| 	r.POST("/callback", api.CallBack)                         //coinGate 回调地址 | ||||
| 	r.POST("/preorder", middleware.FrontedAuth, api.PreOrder) //coinGate 充值 | ||||
|  | ||||
| 	commonApi := fronted.Common{} | ||||
| 	r2 := v1.Group("common") | ||||
| 	{ | ||||
| 		r2.GET("default-set", commonApi.GetDefaultSet) //默认设置 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func frontedUserCenterRouter(v1 *gin.RouterGroup) { | ||||
|  | ||||
							
								
								
									
										27
									
								
								app/admin/router/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/admin/router/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							| @ -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, registerLineUserSettingRouter) | ||||
| } | ||||
|  | ||||
| // registerLineUserSettingRouter | ||||
| func registerLineUserSettingRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { | ||||
| 	api := apis.LineUserSetting{} | ||||
| 	r := v1.Group("/line-user-setting").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) | ||||
| 	} | ||||
| } | ||||
| @ -25,6 +25,9 @@ func registerMemberWithdrawalLogRouter(v1 *gin.RouterGroup, authMiddleware *jwt. | ||||
| 		r.POST("", api.Insert) | ||||
| 		r.PUT("/:id", actions.PermissionAction(), api.Update) | ||||
| 		r.DELETE("", api.Delete) | ||||
|  | ||||
| 		r.PUT("/approve", actions.PermissionAction(), api.Process) //审核提现申请 | ||||
| 		r.PUT("confirm", actions.PermissionAction(), api.Confirm)  //确认提现申请 | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										47
									
								
								app/admin/service/appservice/common.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								app/admin/service/appservice/common.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| package appservice | ||||
|  | ||||
| import ( | ||||
| 	adminservice "go-admin/app/admin/service" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	statuscode "go-admin/common/status_code" | ||||
| 	"go-admin/pkg/utility" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk/service" | ||||
| ) | ||||
|  | ||||
| type Common struct { | ||||
| 	service.Service | ||||
| } | ||||
|  | ||||
| // 获取前端 默认设置 | ||||
| func (e *Common) GetDefaultSet() (dto.FrontedDefaultSetResp, int) { | ||||
| 	result := dto.FrontedDefaultSetResp{} | ||||
| 	keys := []string{"control_telegram_link", "control_customer_service", "control_binance_referral", "member_min_order_amount"} | ||||
| 	configService := adminservice.SysConfig{Service: e.Service} | ||||
| 	configMaps := make(map[string]dto.GetSysConfigByKEYForServiceResp) | ||||
| 	configService.GetWithKeys(&keys, &configMaps) | ||||
|  | ||||
| 	if config, ok := configMaps["control_telegram_link"]; ok { | ||||
| 		result.TelegramLink = config.ConfigValue | ||||
| 	} | ||||
|  | ||||
| 	if config, ok := configMaps["control_customer_service"]; ok { | ||||
| 		result.CustomServiceLink = config.ConfigValue | ||||
| 	} | ||||
|  | ||||
| 	if config, ok := configMaps["control_binance_referral"]; ok { | ||||
| 		result.BinanceReferralLink = config.ConfigValue | ||||
|  | ||||
| 		params, _ := utility.ParseURLParams(result.BinanceReferralLink) | ||||
|  | ||||
| 		if code, ok := params["ref"]; ok { | ||||
| 			result.BinanceReferralCode = code | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if config, ok := configMaps["member_min_order_amount"]; ok { | ||||
| 		result.MinOrderAmount = config.ConfigValue | ||||
| 	} | ||||
|  | ||||
| 	return result, statuscode.OK | ||||
| } | ||||
| @ -25,7 +25,7 @@ func (e *InviteLog) GetPage(req *dto.PersonnalInviteLogPageReq, list *[]dto.Invi | ||||
| 	} | ||||
|  | ||||
| 	for _, v := range datas { | ||||
| 		pids = append(pids, v.Pid) | ||||
| 		pids = append(pids, v.Id) | ||||
| 	} | ||||
| 	if err := e.Orm.Model(&models.LineUser{}).Where("pid in (?)", pids).Find(&childs).Error; err != nil { | ||||
| 		logger.Error("查询子邀请失败", err) | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package appservice | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"go-admin/app/admin/models" | ||||
| @ -11,6 +12,7 @@ import ( | ||||
| 	memberrenwallogstatus "go-admin/common/const/dicts/member_renwal_log_status" | ||||
| 	"go-admin/common/const/rediskey" | ||||
| 	"go-admin/common/helper" | ||||
| 	statuscode "go-admin/common/status_code" | ||||
| 	"go-admin/pkg/utility" | ||||
| 	"time" | ||||
|  | ||||
| @ -83,25 +85,53 @@ func (e *LineUser) Expire() error { | ||||
| // 会员开通支付回调 | ||||
| func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
| 	now := time.Now() | ||||
| 	startTime := time.Now().Add(-4 * time.Hour) | ||||
| 	// startTime := time.Now().Add(-4 * time.Hour) | ||||
| 	log := models.MemberRenwaLog{} | ||||
| 	configService := adminservice.SysConfig{Service: e.Service} | ||||
| 	keys := []string{"member_invitation_rate1", "member_invitation_rate2"} | ||||
| 	configs := make(map[string]dto.GetSysConfigByKEYForServiceResp) | ||||
| 	configService.GetWithKeys(&keys, &configs) | ||||
| 	renwalLogs := make([]models.MemberRenwaLog, 0) | ||||
|  | ||||
| 	if err := e.Orm.Model(&models.MemberRenwaLog{}).Where("expiration_time >NOW() and status =?", memberrenwallogstatus.PENDING).Find(&renwalLogs).Error; err != nil { | ||||
| 		logger.Error("查询未过期续费记录失败", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	for _, data := range datas { | ||||
| 		err := e.doCallBack(data, log, renwalLogs, now, configs) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // 回调逻辑 | ||||
| func (e *LineUser) doCallBack(data models.MemberRenwaLog, log models.MemberRenwaLog, renwalLogs []models.MemberRenwaLog, now time.Time, configs map[string]dto.GetSysConfigByKEYForServiceResp) error { | ||||
| 	lock := helper.NewRedisLock(fmt.Sprintf(rediskey.OrderCallBackLock, data.PayableAmount), 200, 5, 100*time.Millisecond) | ||||
|  | ||||
| 	if ok, err := lock.AcquireWait(context.Background()); err != nil { | ||||
| 		logger.Debug("获取锁失败", err) | ||||
| 		return err | ||||
| 	} else if ok { | ||||
| 		defer lock.Release() | ||||
|  | ||||
| 		// 检查是否已经处理过该订单 | ||||
| 		hashKey := fmt.Sprintf(rediskey.MemberHash, data.Hash) | ||||
| 		val, _ := helper.DefaultRedis.GetString(hashKey) | ||||
| 		if val != "" { | ||||
| 			logger.Info("已处理过的hash:", data.Hash) | ||||
| 			continue | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		for index := range renwalLogs { | ||||
| 			if renwalLogs[index].PayableAmount.Cmp(data.PayableAmount) == 0 { | ||||
| 				// 查询续费记录 | ||||
| 		if err := e.Orm.Model(&log).Where("payable_amount=? AND create_at >? AND status =?", data.PayableAmount, startTime, memberrenwallogstatus.PENDING).First(&log).Error; err != nil { | ||||
| 				if err := e.Orm.Model(&log).Where("payable_amount=? AND status =?", data.PayableAmount, memberrenwallogstatus.PENDING).First(&log).Error; err != nil { | ||||
| 					if errors.Is(err, gorm.ErrRecordNotFound) { | ||||
|  | ||||
| 						// 如果记录未找到,跳过该项 | ||||
| 						logger.Warnf("续费记录未找到 hash:%v amount:%v", data.Hash, data.PayableAmount) | ||||
| 						continue | ||||
| @ -113,14 +143,15 @@ func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
| 				log.Status = memberrenwallogstatus.PAID | ||||
| 				log.PaymentTime = &now | ||||
| 				log.FromAddress = data.FromAddress | ||||
| 				log.ActualPaymentAmount = data.ActualPaymentAmount | ||||
| 				log.Hash = data.Hash | ||||
| 		// 查询用户信息 | ||||
|  | ||||
| 				user := models.LineUser{} | ||||
| 				// 查询用户信息 | ||||
| 				if err := e.Orm.Model(&user).Where("id =?", log.UserId).First(&user).Error; err != nil { | ||||
| 					logger.Errorf("用户查询失败 hash:%v amount:%v err:%v", data.Hash, data.PayableAmount, err) | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				// 更新 ExpirationTime | ||||
| 				if user.ExpirationTime != nil && user.ExpirationTime.After(now) { | ||||
| 					expirationTime := user.ExpirationTime.AddDate(0, 0, log.RenwalDuration) | ||||
| @ -129,7 +160,6 @@ func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
| 					expirationTime := now.AddDate(0, 0, log.RenwalDuration) | ||||
| 					user.ExpirationTime = &expirationTime | ||||
| 				} | ||||
|  | ||||
| 				// 计算返现记录 | ||||
| 				balanceLogs := make([]models.MemberBalanceLog, 0) | ||||
| 				if user.Pid > 0 { | ||||
| @ -149,7 +179,6 @@ func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				// 修改续期订单记录 | ||||
| 				if err := e.Orm.Model(log).Save(&log).Error; err != nil { | ||||
| 					logger.Errorf("续费更新订单失败 userid:%v hash:%v amount:%v err:%v", user.Id, data.Hash, data.PayableAmount, err) | ||||
| @ -160,7 +189,6 @@ func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
| 					logger.Errorf("续费更新失败 userid:%v hash:%v amount:%v err:%v", user.Id, data.Hash, data.PayableAmount, err) | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 				// 事务操作,保存返现记录及更新余额 | ||||
| 				err := e.Orm.Transaction(func(tx *gorm.DB) error { | ||||
| 					// 保存返现记录 | ||||
| @ -171,7 +199,7 @@ func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
|  | ||||
| 					// 更新用户余额 | ||||
| 					for _, item := range balanceLogs { | ||||
| 				if err := e.Orm.Exec("update member_balance set total_amount=total_amount+?,free_amount=free_amount +? where user_id=?", item.Amount, item.UserId).Error; err != nil { | ||||
| 						if err := e.Orm.Exec("update member_balance set total_amount=total_amount+?,free_amount=free_amount +? where user_id=?", item.Amount, item.Amount, item.UserId).Error; err != nil { | ||||
| 							logger.Errorf("续费更新余额失败 userid:%v 返现userid:%v hash:%v amount:%v err:%v", user.Id, item.UserId, data.Hash, data.PayableAmount, err) | ||||
| 							return err | ||||
| 						} | ||||
| @ -186,11 +214,12 @@ func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
| 					continue | ||||
| 				} | ||||
|  | ||||
| 		if err := helper.DefaultRedis.SetString(hashKey, "1"); err != nil { | ||||
| 				if err := helper.DefaultRedis.SetStringExpire(hashKey, "1", time.Hour*1); err != nil { | ||||
| 					logger.Errorf("续费成功,写入hash缓存失败 :续费userid:%v,hash:%s,err:%v", user.Id, data.Hash, err) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -198,8 +227,32 @@ func (e *LineUser) PayCallBack(datas []models.MemberRenwaLog) error { | ||||
| func calculateBalance(userId int, amount decimal.Decimal, rate decimal.Decimal) models.MemberBalanceLog { | ||||
| 	return models.MemberBalanceLog{ | ||||
| 		UserId:       userId, | ||||
| 		ChangeSource: memberbalancechangesource.WITH_DRAW, | ||||
| 		ChangeSource: memberbalancechangesource.CASH_BACK, | ||||
| 		ChangeType:   1, | ||||
| 		Amount:       amount.Mul(rate.Div(decimal.NewFromInt(100))).Truncate(2), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // 获取用户过期时间 | ||||
| // return statuscode | ||||
| func (e *LineUser) GetUserInfo(userId int, data *dto.LineUserAppResp) int { | ||||
| 	user := models.LineUser{} | ||||
| 	userSetting := models.LineUserSetting{} | ||||
|  | ||||
| 	if err := e.Orm.Model(&user).Where("id = ?", userId).First(&user).Error; err != nil { | ||||
| 		if errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 			return statuscode.DataError | ||||
| 		} | ||||
|  | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	e.Orm.Model(&userSetting).Where("user_id = ?", userId).First(&userSetting) | ||||
|  | ||||
| 	if user.ExpirationTime != nil { | ||||
| 		data.ExpirationTimeUnix = user.ExpirationTime.UnixNano() / int64(time.Millisecond) | ||||
| 	} | ||||
| 	data.MinOrderAmount = userSetting.MinOrderAmount | ||||
|  | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
| @ -2,6 +2,7 @@ package appservice | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/app/admin/models" | ||||
| 	adminservice "go-admin/app/admin/service" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	cDto "go-admin/common/dto" | ||||
| 	statuscode "go-admin/common/status_code" | ||||
| @ -18,12 +19,13 @@ type MemberBalanceLog struct { | ||||
| // 分页查询个人资金记录 | ||||
| func (e *MemberBalanceLog) GetPage(req *dto.MemberBalanceLogPageAppReq, list *[]dto.MemberBalanceLogAppResp, count *int64) int { | ||||
| 	var data models.MemberBalanceLog | ||||
| 	var datas []models.MemberBalanceLog | ||||
| 	datas := make([]models.MemberBalanceLog, 0) | ||||
| 	item := dto.MemberBalanceLogAppResp{} | ||||
|  | ||||
| 	err := e.Orm.Model(&data). | ||||
| 		Where("user_id =?", req.UserId). | ||||
| 		Scopes( | ||||
| 			cDto.MakeCondition(req.GetNeedSearch()), | ||||
| 			cDto.Paginate(req.GetPageSize(), req.GetPageIndex()), | ||||
| 		). | ||||
| 		Find(&datas).Limit(-1).Offset(-1). | ||||
| @ -32,11 +34,15 @@ func (e *MemberBalanceLog) GetPage(req *dto.MemberBalanceLogPageAppReq, list *[] | ||||
| 	if err != nil { | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
| 	dictService := adminservice.SysDictData{Service: e.Service} | ||||
| 	dicts, _ := dictService.GetByType("member_change_source") | ||||
|  | ||||
| 	for _, v := range datas { | ||||
| 		copier.Copy(&item, v) | ||||
|  | ||||
| 		item.CreateTimeUnix = v.CreatedAt.UnixNano() / int64(time.Millisecond) | ||||
| 		item.ChangeSourceName, _ = dictService.GetLanguageByDatas(&dicts, item.ChangeSource, req.Language) | ||||
|  | ||||
| 		*list = append(*list, item) | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -2,6 +2,7 @@ package appservice | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/app/admin/service/dto" | ||||
| 	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" | ||||
| @ -13,10 +14,30 @@ 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 { | ||||
| func (e *MemberRenwalConfigAppService) GetList(language string) ([]dto.MemberRenwalConfigAppResp, int) { | ||||
| 	var datas []models.MemberRenwalConfig | ||||
| 	result := make([]dto.MemberRenwalConfigAppResp, 0) | ||||
| 	if err := e.Orm.Model(&models.MemberRenwalConfig{}).Where(" status =? AND is_visible =?", | ||||
| 		memberrenwalconfigstatus.ENABLE, memberrenwalisvisible.IsVisibleYes). | ||||
| 		Order("sort asc").Find(&datas).Error; err != nil { | ||||
| 		return result, statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	for _, v := range datas { | ||||
| 		item := dto.MemberRenwalConfigAppResp{ | ||||
| 			Id:            v.Id, | ||||
| 			PackageName:   v.PackageName, | ||||
| 			OriginalPrice: v.OriginalPrice, | ||||
| 			DiscountPrice: v.DiscountPrice, | ||||
| 			DurationDay:   v.DurationDay, | ||||
| 			Remark:        v.Remark, | ||||
| 		} | ||||
|  | ||||
| 		if language != "zh_CN" { | ||||
| 			item.PackageName = v.PackageNameEn | ||||
| 		} | ||||
| 		result = append(result, item) | ||||
| 	} | ||||
|  | ||||
| 	return result, statuscode.OK | ||||
| } | ||||
|  | ||||
| @ -32,10 +32,13 @@ func (e *MemberRenwalLog) GetPage(userId int, req *dto.MemberRenwalLogPageAppReq | ||||
| 	var data models.MemberRenwaLog | ||||
| 	var datas []models.MemberRenwaLog | ||||
| 	resp := dto.MemberRenwalLogResp{} | ||||
| 	renwalIds := make([]int, 0) | ||||
| 	renwals := make([]models.MemberRenwalConfig, 0) | ||||
|  | ||||
| 	err := e.Orm.Model(&data). | ||||
| 		Where("user_id = ?", userId). | ||||
| 		Where("user_id = ? AND status !=?", userId, memberrenwallogstatus.EXPIRED). | ||||
| 		Scopes( | ||||
| 			cDto.MakeCondition(req.GetNeedSearch()), | ||||
| 			cDto.Paginate(req.GetPageSize(), req.GetPageIndex()), | ||||
| 		). | ||||
| 		Find(&datas).Limit(-1).Offset(-1). | ||||
| @ -45,6 +48,15 @@ func (e *MemberRenwalLog) GetPage(userId int, req *dto.MemberRenwalLogPageAppReq | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	for _, v := range datas { | ||||
| 		if utility.ContainsInt(renwalIds, v.RenwalId) { | ||||
| 			continue | ||||
| 		} | ||||
| 		renwalIds = append(renwalIds, v.RenwalId) | ||||
| 	} | ||||
|  | ||||
| 	e.Orm.Model(&models.MemberRenwalConfig{}).Where("id IN (?)", renwalIds).Find(&renwals) | ||||
|  | ||||
| 	for _, item := range datas { | ||||
| 		copier.Copy(&resp, item) | ||||
|  | ||||
| @ -54,6 +66,14 @@ func (e *MemberRenwalLog) GetPage(userId int, req *dto.MemberRenwalLogPageAppReq | ||||
|  | ||||
| 		resp.ExpirationTimeUnix = item.ExpirationTime.UnixNano() / int64(time.Millisecond) | ||||
|  | ||||
| 		if req.Language != "zh_CN" { | ||||
| 			for _, v := range renwals { | ||||
| 				if v.Id == item.RenwalId { | ||||
| 					resp.RenwalName = v.PackageNameEn | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		*list = append(*list, resp) | ||||
| 	} | ||||
|  | ||||
| @ -116,6 +136,8 @@ func (e *MemberRenwalLog) Renwal(req *dto.MemberRenwalCreateAppReq, data *dto.Me | ||||
| 	renwalLog.ExpirationTime = now.Add(time.Minute * time.Duration(expirationVal)) | ||||
| 	renwalLog.Coin = "USDT" | ||||
| 	renwalLog.PayableAmount = amount | ||||
| 	renwalLog.NetworkName = "TRC20" | ||||
| 	renwalLog.ReceiveAddress = toAddress | ||||
|  | ||||
| 	if err := e.Orm.Model(&models.MemberRenwaLog{}).Create(&renwalLog).Error; err != nil { | ||||
| 		logger.Errorf("创建续费记录失败,userId:%v err:%v", req.UserId, err) | ||||
| @ -123,8 +145,8 @@ func (e *MemberRenwalLog) Renwal(req *dto.MemberRenwalCreateAppReq, data *dto.Me | ||||
| 	} | ||||
| 	data.Amount = renwalLog.PayableAmount | ||||
| 	data.ExpirationTimeUnix = renwalLog.ExpirationTime.UnixNano() / int64(time.Millisecond) | ||||
| 	data.NetworkName = "TRC20" | ||||
| 	data.ToAddress = toAddress | ||||
| 	data.NetworkName = renwalLog.NetworkName | ||||
| 	data.ToAddress = renwalLog.ReceiveAddress | ||||
|  | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
| @ -44,15 +44,15 @@ func GetDeviceID(ctx *gin.Context) string { | ||||
| 	return device | ||||
| } | ||||
|  | ||||
| // 获取 language,默认语言:zh-CN | ||||
| // 获取 language,默认语言:zh_CN | ||||
| // 英语 en | ||||
| // 日本语 jp | ||||
| // 韩语 kr | ||||
| // 马来西亚语 my | ||||
| // 泰国语 th | ||||
| // 越南语 vn | ||||
| // 简体中文 zh-CN | ||||
| // 繁体中文 zh-HK | ||||
| // 简体中文 zh_CN | ||||
| // 繁体中文 zh_HK | ||||
| func GetLanguage(ctx *gin.Context) string { | ||||
| 	lang := "" | ||||
|  | ||||
| @ -62,7 +62,7 @@ func GetLanguage(ctx *gin.Context) string { | ||||
| 		val, exits := ctx.Get("language") | ||||
|  | ||||
| 		if !exits { | ||||
| 			lang = "zh-CN" | ||||
| 			lang = "zh_CN" | ||||
| 		} else { | ||||
| 			lang = val.(string) | ||||
| 		} | ||||
|  | ||||
| @ -211,11 +211,13 @@ type FrontedUserVerifyEmailReq struct { | ||||
|  | ||||
| type FrontedSendVerifyEmailReq struct { | ||||
| 	Email string `json:"email"` | ||||
| 	Type  int    `json:"type"` | ||||
| } | ||||
|  | ||||
| type FrontedSendVerifySmsReq struct { | ||||
| 	PhoneAreaCode string `json:"phone_area_code"` // 区域电话代码 | ||||
| 	Phone         string `json:"phone"`           // 手机号码 | ||||
| 	Type          int    `json:"type" comment:"类型 0-注册 1-忘记密码"` | ||||
| } | ||||
|  | ||||
| func (receiver *FrontedSendVerifyEmailReq) CheckParams() int { | ||||
| @ -351,3 +353,56 @@ type LineUserPropertyResp struct { | ||||
| 	FuturesTotalAmount decimal.Decimal `json:"futuresTotalAmount"` //合约U总资产 | ||||
| 	FuturesFreeAmount  decimal.Decimal `json:"futuresFreeAmount"`  //合约U可用余额 | ||||
| } | ||||
|  | ||||
| type LineUserAppResp struct { | ||||
| 	ExpirationTimeUnix int64           `json:"expirationTimeUnix"` | ||||
| 	MinOrderAmount     decimal.Decimal `json:"minOrderAmount"` | ||||
| } | ||||
|  | ||||
| type LineUserOrderSetReq struct { | ||||
| 	MinOrderAmount decimal.Decimal `json:"minOrderAmount"` | ||||
| } | ||||
|  | ||||
| type LineUserResetPwdReq struct { | ||||
| 	Pwd           string `json:"pwd"` | ||||
| 	CheckPwd      string `json:"check_pwd" comment:"确认密码"` | ||||
| 	PhoneAreaCode string `json:"phone_area_code" comment:"区号"` | ||||
| 	Code          string `json:"code"` | ||||
| 	Email         string `json:"email"` | ||||
| 	Phone         string `json:"phone"` | ||||
| 	Type          int    `json:"type" comment:"类型 1-手机验证码 2-邮箱验证码"` | ||||
| } | ||||
|  | ||||
| // 参数校验 | ||||
| func (e *LineUserResetPwdReq) Valid() int { | ||||
| 	if e.Pwd == "" { | ||||
| 		return statuscode.ParameterInvalid | ||||
| 	} | ||||
|  | ||||
| 	if e.Code == "" { | ||||
| 		return statuscode.ParameterInvalid | ||||
| 	} | ||||
|  | ||||
| 	if e.CheckPwd != e.Pwd { | ||||
| 		return statuscode.UserResetPasswordInconsistency | ||||
| 	} | ||||
|  | ||||
| 	switch e.Type { | ||||
| 	case 1: | ||||
| 		if e.Phone == "" { | ||||
| 			return statuscode.ParameterInvalid | ||||
| 		} | ||||
|  | ||||
| 		if e.PhoneAreaCode == "" { | ||||
| 			return statuscode.ParameterInvalid | ||||
| 		} | ||||
| 	case 2: | ||||
| 		if e.Email == "" { | ||||
| 			return statuscode.ParameterInvalid | ||||
| 		} | ||||
| 	default: | ||||
| 		return statuscode.ParameterInvalid | ||||
| 	} | ||||
|  | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
							
								
								
									
										99
									
								
								app/admin/service/dto/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								app/admin/service/dto/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | ||||
| package dto | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
|  | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| type LineUserSettingGetPageReq struct { | ||||
| 	dto.Pagination `search:"-"` | ||||
| 	LineUserSettingOrder | ||||
| } | ||||
|  | ||||
| type LineUserSettingOrder struct { | ||||
| 	Id                    string `form:"idOrder"  search:"type:order;column:id;table:line_user_setting"` | ||||
| 	MinOrderAmount        string `form:"minOrderAmountOrder"  search:"type:order;column:min_order_amount;table:line_user_setting"` | ||||
| 	SpotUsdtFreeAmount    string `form:"spotUsdtFreeAmountOrder"  search:"type:order;column:spot_usdt_free_amount;table:line_user_setting"` | ||||
| 	FutureUsdtTotalAmount string `form:"futureUsdtTotalAmountOrder"  search:"type:order;column:future_usdt_total_amount;table:line_user_setting"` | ||||
| 	AssetUpdateTime       string `form:"assetUpdateTimeOrder"  search:"type:order;column:asset_update_time;table:line_user_setting"` | ||||
| 	CreatedAt             string `form:"createdAtOrder"  search:"type:order;column:created_at;table:line_user_setting"` | ||||
| 	UpdatedAt             string `form:"updatedAtOrder"  search:"type:order;column:updated_at;table:line_user_setting"` | ||||
| 	DeletedAt             string `form:"deletedAtOrder"  search:"type:order;column:deleted_at;table:line_user_setting"` | ||||
| 	CreateBy              string `form:"createByOrder"  search:"type:order;column:create_by;table:line_user_setting"` | ||||
| 	UpdateBy              string `form:"updateByOrder"  search:"type:order;column:update_by;table:line_user_setting"` | ||||
| } | ||||
|  | ||||
| func (m *LineUserSettingGetPageReq) GetNeedSearch() interface{} { | ||||
| 	return *m | ||||
| } | ||||
|  | ||||
| type LineUserSettingInsertReq struct { | ||||
| 	Id                   int             `json:"-" comment:"主键"` // 主键 | ||||
| 	MinOrderAmount       decimal.Decimal `json:"minOrderAmount" comment:"单笔最小金额"` | ||||
| 	SpotUsdtFreeAmount   decimal.Decimal `json:"spotUsdtFreeAmount" comment:"现货USDT可用余额"` | ||||
| 	FutureUsdtFreeAmount decimal.Decimal `json:"futureUsdtFreeAmount" comment:"合约USDT可用余额"` | ||||
| 	AssetUpdateTime      time.Time       `json:"assetUpdateTime" comment:"资产更新时间"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *LineUserSettingInsertReq) Generate(model *models.LineUserSetting) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.MinOrderAmount = s.MinOrderAmount | ||||
| 	model.SpotUsdtFreeAmount = s.SpotUsdtFreeAmount | ||||
| 	model.FutureUsdtFreeAmount = s.FutureUsdtFreeAmount | ||||
| 	model.AssetUpdateTime = &s.AssetUpdateTime | ||||
| 	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | ||||
| } | ||||
|  | ||||
| func (s *LineUserSettingInsertReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| type LineUserSettingUpdateReq struct { | ||||
| 	Id                   int             `uri:"id" comment:"主键"` // 主键 | ||||
| 	MinOrderAmount       decimal.Decimal `json:"minOrderAmount" comment:"单笔最小金额"` | ||||
| 	SpotUsdtFreeAmount   decimal.Decimal `json:"spotUsdtFreeAmount" comment:"现货USDT可用余额"` | ||||
| 	FutureUsdtFreeAmount decimal.Decimal `json:"futureUsdtFreeAmount" comment:"合约USDT可用余额"` | ||||
| 	AssetUpdateTime      time.Time       `json:"assetUpdateTime" comment:"资产更新时间"` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| func (s *LineUserSettingUpdateReq) Generate(model *models.LineUserSetting) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.MinOrderAmount = s.MinOrderAmount | ||||
| 	model.SpotUsdtFreeAmount = s.SpotUsdtFreeAmount | ||||
| 	model.FutureUsdtFreeAmount = s.FutureUsdtFreeAmount | ||||
| 	model.AssetUpdateTime = &s.AssetUpdateTime | ||||
| 	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | ||||
| } | ||||
|  | ||||
| func (s *LineUserSettingUpdateReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // LineUserSettingGetReq 功能获取请求参数 | ||||
| type LineUserSettingGetReq struct { | ||||
| 	Id int `uri:"id"` | ||||
| } | ||||
|  | ||||
| func (s *LineUserSettingGetReq) GetId() interface{} { | ||||
| 	return s.Id | ||||
| } | ||||
|  | ||||
| // LineUserSettingDeleteReq 功能删除请求参数 | ||||
| type LineUserSettingDeleteReq struct { | ||||
| 	Ids []int `json:"ids"` | ||||
| } | ||||
|  | ||||
| func (s *LineUserSettingDeleteReq) GetId() interface{} { | ||||
| 	return s.Ids | ||||
| } | ||||
| @ -41,7 +41,7 @@ func (s *MemberBalanceInsertReq) Generate(model *models.MemberBalance) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.TotalAmont = s.TotalAmont | ||||
| 	model.TotalAmount = s.TotalAmont | ||||
| 	model.FreeAmount = s.FreeAmount | ||||
| 	model.FrozenAmount = s.FrozenAmount | ||||
| 	model.CreateBy = s.CreateBy // 添加这而,需要记录是被谁创建的 | ||||
| @ -63,7 +63,7 @@ func (s *MemberBalanceUpdateReq) Generate(model *models.MemberBalance) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.TotalAmont = s.TotalAmont | ||||
| 	model.TotalAmount = s.TotalAmont | ||||
| 	model.FreeAmount = s.FreeAmount | ||||
| 	model.FrozenAmount = s.FrozenAmount | ||||
| 	model.UpdateBy = s.UpdateBy // 添加这而,需要记录是被谁更新的 | ||||
|  | ||||
| @ -16,7 +16,7 @@ type MemberBalanceLogGetPageReq struct { | ||||
| } | ||||
|  | ||||
| type MemberBalanceLogOrder struct { | ||||
| 	Id            string `form:"idOrder"  search:"type:order;column:id;table:member_balance_log"` | ||||
| 	Id            string `form:"idOrder" query:"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"` | ||||
| @ -117,15 +117,21 @@ type MemberBalanceLogPageAppReq struct { | ||||
| 	dto.Pagination `search:"-"` | ||||
| 	ChangeSource   string `form:"changeSource"  search:"type:exact;column:change_source;table:member_balance_log" comment:"变更来源 (member_change_source)"` | ||||
| 	ChangeType     string `form:"changeType"  search:"type:exact;column:change_type;table:member_balance_log" comment:"变更类别 1-收入 2-支出"` | ||||
| 	UserId         int    `json:"userId"` | ||||
| 	UserId         int    `json:"userId" search:"-"` | ||||
| 	Language       string `json:"language" search:"-"` | ||||
| 	MemberBalanceLogOrder | ||||
| } | ||||
|  | ||||
| func (m *MemberBalanceLogPageAppReq) GetNeedSearch() interface{} { | ||||
| 	return *m | ||||
| } | ||||
|  | ||||
| type MemberBalanceLogAppResp struct { | ||||
| 	Id               int             `json:"-" comment:"主键"` // 主键 | ||||
| 	UserId           int             `json:"userId" comment:"用户id"` | ||||
| 	UserName         string          `json:"userName" comment:"用户名"` | ||||
| 	ChangeSource     string          `json:"changeSource" comment:"变更来源 (member_change_source)"` | ||||
| 	ChangeSourceName string          `json:"changeSourceName"` | ||||
| 	ChangeType       int             `json:"changeType" comment:"变更类别 1-收入 2-支出"` | ||||
| 	Amount           decimal.Decimal `json:"amount" comment:"变更金额"` | ||||
| 	Remark           string          `json:"remark" comment:"备注"` | ||||
|  | ||||
| @ -17,13 +17,22 @@ type MemberRenwaLogGetPageReq struct { | ||||
|  | ||||
| type MemberRenwalLogPageAppReq struct { | ||||
| 	dto.Pagination `search:"-"` | ||||
| 	Language       string `search:"-"` | ||||
| 	MemberRenwaLogOrder | ||||
| } | ||||
|  | ||||
| func (m *MemberRenwalLogPageAppReq) GetNeedSearch() interface{} { | ||||
| 	return *m | ||||
| } | ||||
|  | ||||
| type MemberRenwalLogResp struct { | ||||
| 	Id                  int             `json:"id"` | ||||
| 	NetworkName         string          `json:"networkName"` | ||||
| 	ReceiveAddress      string          `json:"receiveAddress"` | ||||
| 	RenwalName          string          `json:"renwalName" comment:"续期套餐名称"` | ||||
| 	RenwalDuration      int             `json:"renwalDuration" comment:"续期时长(天数)"` | ||||
| 	Status              string          `json:"status" comment:"订单状态(member_renwal_log_status)"` | ||||
| 	StatusLabel         string          `json:"statusLabel"` | ||||
| 	PayableAmount       decimal.Decimal `json:"payableAmount" comment:"应付金额"` | ||||
| 	ActualPaymentAmount decimal.Decimal `json:"actualPaymentAmount" comment:"实付金额"` | ||||
| 	FromAddress         string          `json:"fromAddress" comment:"付款地址"` | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package dto | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
| @ -38,6 +39,7 @@ func (m *MemberRenwalConfigGetPageReq) GetNeedSearch() interface{} { | ||||
| type MemberRenwalConfigInsertReq struct { | ||||
| 	Id            int              `json:"-" comment:"主键"` // 主键 | ||||
| 	PackageName   string           `json:"packageName" comment:"套餐名称"` | ||||
| 	PackageNameEn string           `json:"packageNameEn" comment:"套餐名称英文"` | ||||
| 	DurationDay   int              `json:"durationDay" comment:"续期时间(天)"` | ||||
| 	OriginalPrice decimal.Decimal  `json:"originalPrice" comment:"原始单价"` | ||||
| 	DiscountPrice *decimal.Decimal `json:"discountPrice" comment:"折扣价格 -1为未设置"` | ||||
| @ -49,11 +51,29 @@ type MemberRenwalConfigInsertReq struct { | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| // 校验 | ||||
| func (s *MemberRenwalConfigInsertReq) Valid() error { | ||||
| 	if s.PackageName == "" { | ||||
| 		return errors.New("套餐名称不能为空") | ||||
| 	} | ||||
|  | ||||
| 	if s.PackageNameEn == "" { | ||||
| 		return errors.New("套餐名称英文不能为空") | ||||
| 	} | ||||
|  | ||||
| 	if s.DurationDay <= 0 { | ||||
| 		return errors.New("续期时间(天)不能为空") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *MemberRenwalConfigInsertReq) Generate(model *models.MemberRenwalConfig) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.PackageName = s.PackageName | ||||
| 	model.PackageNameEn = s.PackageNameEn | ||||
| 	model.DurationDay = s.DurationDay | ||||
| 	model.OriginalPrice = s.OriginalPrice | ||||
|  | ||||
| @ -77,6 +97,7 @@ func (s *MemberRenwalConfigInsertReq) GetId() interface{} { | ||||
| type MemberRenwalConfigUpdateReq struct { | ||||
| 	Id            int              `uri:"id" comment:"主键"` // 主键 | ||||
| 	PackageName   string           `json:"packageName" comment:"套餐名称"` | ||||
| 	PackageNameEn string           `json:"packageNameEn" comment:"套餐名称英文"` | ||||
| 	DurationDay   int              `json:"durationDay" comment:"续期时间(天)"` | ||||
| 	OriginalPrice decimal.Decimal  `json:"originalPrice" comment:"原始单价"` | ||||
| 	DiscountPrice *decimal.Decimal `json:"discountPrice" comment:"折扣价格 -1为未设置"` | ||||
| @ -88,11 +109,29 @@ type MemberRenwalConfigUpdateReq struct { | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| // 校验 | ||||
| func (s *MemberRenwalConfigUpdateReq) Valid() error { | ||||
| 	if s.PackageName == "" { | ||||
| 		return errors.New("套餐名称不能为空") | ||||
| 	} | ||||
|  | ||||
| 	if s.PackageNameEn == "" { | ||||
| 		return errors.New("套餐名称英文不能为空") | ||||
| 	} | ||||
|  | ||||
| 	if s.DurationDay <= 0 { | ||||
| 		return errors.New("续期时间(天)不能为空") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *MemberRenwalConfigUpdateReq) Generate(model *models.MemberRenwalConfig) { | ||||
| 	if s.Id == 0 { | ||||
| 		model.Model = common.Model{Id: s.Id} | ||||
| 	} | ||||
| 	model.PackageName = s.PackageName | ||||
| 	model.PackageNameEn = s.PackageNameEn | ||||
| 	model.DurationDay = s.DurationDay | ||||
| 	model.OriginalPrice = s.OriginalPrice | ||||
|  | ||||
| @ -130,3 +169,12 @@ type MemberRenwalConfigDeleteReq struct { | ||||
| func (s *MemberRenwalConfigDeleteReq) GetId() interface{} { | ||||
| 	return s.Ids | ||||
| } | ||||
|  | ||||
| type MemberRenwalConfigAppResp struct { | ||||
| 	Id            int             `json:"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为未设置"` | ||||
| 	Remark        string          `json:"remark" comment:"备注"` | ||||
| } | ||||
|  | ||||
| @ -171,6 +171,7 @@ func (e *MemberWithdrawalLogApplyReq) Valid() int { | ||||
| type MemberWithdrawalLogResp struct { | ||||
| 	Id              int             `json:"id"` | ||||
| 	NetworkId       int             `json:"networkId"` | ||||
| 	NetworkName     string          `json:"networkName"` | ||||
| 	UserId          int             `json:"userId"` | ||||
| 	NickName        string          `json:"nickName"` | ||||
| 	Amount          decimal.Decimal `json:"amount"` | ||||
|  | ||||
| @ -115,3 +115,11 @@ type SameSymbol struct { | ||||
| 	Symbol string `json:"symbol"` | ||||
| 	Number int    `json:"number"` | ||||
| } | ||||
|  | ||||
| type FrontedDefaultSetResp struct { | ||||
| 	MinOrderAmount      string `json:"minOrderAmount"` | ||||
| 	BinanceReferralLink string `json:"binanceReferralLink"` | ||||
| 	BinanceReferralCode string `json:"binanceReferalCode"` | ||||
| 	CustomServiceLink   string `json:"customServiceLink"` | ||||
| 	TelegramLink        string `json:"telegramLink"` | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,8 @@ import ( | ||||
| 	"go-admin/app/admin/models" | ||||
| 	"go-admin/common/dto" | ||||
| 	common "go-admin/common/models" | ||||
|  | ||||
| 	"github.com/bytedance/sonic" | ||||
| ) | ||||
|  | ||||
| type SysDictDataGetPageReq struct { | ||||
| @ -25,6 +27,7 @@ type SysDictDataGetAllResp struct { | ||||
| } | ||||
|  | ||||
| type SysDictDataResp struct { | ||||
| 	DictCode     int                       `json:"dictCode"` | ||||
| 	DictSort     int                       `json:"dictSort" comment:""` | ||||
| 	DictLabel    string                    `json:"dictLabel" comment:""` | ||||
| 	DictValue    string                    `json:"dictValue" comment:""` | ||||
| @ -35,6 +38,7 @@ type SysDictDataResp struct { | ||||
| 	Status       int                       `json:"status" comment:""` | ||||
| 	Default      string                    `json:"default" comment:""` | ||||
| 	Remark       string                    `json:"remark" comment:""` | ||||
| 	LanguageData []SysDictDataLanguageData `json:"languageData"` | ||||
| } | ||||
| type SysDictDataInsertReq struct { | ||||
| 	Id           int                       `json:"-" comment:""` | ||||
| @ -48,6 +52,7 @@ type SysDictDataInsertReq struct { | ||||
| 	Status       int                       `json:"status" comment:""` | ||||
| 	Default      string                    `json:"default" comment:""` | ||||
| 	Remark       string                    `json:"remark" comment:""` | ||||
| 	LanguageData []SysDictDataLanguageData `json:"languageData" comment:""` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| @ -63,6 +68,7 @@ func (s *SysDictDataInsertReq) Generate(model *models.SysDictData) { | ||||
| 	model.Status = s.Status | ||||
| 	model.Default = s.Default | ||||
| 	model.Remark = s.Remark | ||||
| 	model.Language, _ = sonic.MarshalString(s.LanguageData) | ||||
| } | ||||
|  | ||||
| func (s *SysDictDataInsertReq) GetId() interface{} { | ||||
| @ -81,6 +87,7 @@ type SysDictDataUpdateReq struct { | ||||
| 	Status       int                       `json:"status" comment:""` | ||||
| 	Default      string                    `json:"default" comment:""` | ||||
| 	Remark       string                    `json:"remark" comment:""` | ||||
| 	LanguageData []SysDictDataLanguageData `json:"languageData" comment:""` | ||||
| 	common.ControlBy | ||||
| } | ||||
|  | ||||
| @ -96,6 +103,7 @@ func (s *SysDictDataUpdateReq) Generate(model *models.SysDictData) { | ||||
| 	model.Status = s.Status | ||||
| 	model.Default = s.Default | ||||
| 	model.Remark = s.Remark | ||||
| 	model.Language, _ = sonic.MarshalString(s.LanguageData) | ||||
| } | ||||
|  | ||||
| func (s *SysDictDataUpdateReq) GetId() interface{} { | ||||
| @ -118,3 +126,8 @@ type SysDictDataDeleteReq struct { | ||||
| func (s *SysDictDataDeleteReq) GetId() interface{} { | ||||
| 	return s.Ids | ||||
| } | ||||
|  | ||||
| type SysDictDataLanguageData struct { | ||||
| 	Key   string `json:"k"` //多语言键 | ||||
| 	Value string `json:"v"` | ||||
| } | ||||
|  | ||||
| @ -6,11 +6,13 @@ import ( | ||||
| 	"go-admin/common/const/rediskey" | ||||
| 	"go-admin/common/global" | ||||
| 	"go-admin/common/helper" | ||||
| 	"go-admin/common/service/sysservice/authservice" | ||||
| 	statuscode "go-admin/common/status_code" | ||||
| 	ext "go-admin/config" | ||||
| 	"go-admin/models/coingatedto" | ||||
| 	"go-admin/pkg/coingate" | ||||
| 	"go-admin/pkg/cryptohelper/aeshelper" | ||||
| 	"go-admin/pkg/cryptohelper/md5helper" | ||||
| 	"go-admin/pkg/timehelper" | ||||
| 	"go-admin/pkg/udunhelper" | ||||
| 	"go-admin/pkg/utility" | ||||
| @ -580,5 +582,105 @@ func (e *LineUser) GetProperty(userId int, data *dto.LineUserPropertyResp) int { | ||||
| 	binanceservice.GetSpotUProperty(lineApiUser, data) | ||||
| 	binanceservice.GetFuturesUProperty(lineApiUser, data) | ||||
|  | ||||
| 	userSetting := models.LineUserSetting{} | ||||
| 	e.Orm.Model(&userSetting).Where("user_id=?", userId).First(&userSetting) | ||||
|  | ||||
| 	if userSetting.Id > 0 { | ||||
| 		userSetting.SpotUsdtFreeAmount = data.SpotFreeAmount | ||||
| 		userSetting.FutureUsdtFreeAmount = data.FuturesFreeAmount | ||||
|  | ||||
| 		if err := e.Orm.Model(&userSetting).Updates(map[string]interface{}{"spot_usdt_free_amount": data.SpotFreeAmount, "future_usdt_free_amount": data.FuturesFreeAmount, "asset_update_time": time.Now()}).Error; err != nil { | ||||
| 			logger.Errorf("用户id %v 更新用户资产失败:%v", userId, err) | ||||
| 		} | ||||
| 	} else { | ||||
| 		now := time.Now() | ||||
| 		userSetting.UserId = userId | ||||
| 		userSetting.SpotUsdtFreeAmount = data.SpotFreeAmount | ||||
| 		userSetting.FutureUsdtFreeAmount = data.FuturesFreeAmount | ||||
| 		userSetting.AssetUpdateTime = &now | ||||
|  | ||||
| 		if err := e.Orm.Create(&userSetting).Error; err != nil { | ||||
| 			logger.Errorf("用户id %v 创建用户资产失败:%v", userId, err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
| // 设置用户下单配置 | ||||
| // return statuscode | ||||
| func (e *LineUser) OrderSet(req *dto.LineUserOrderSetReq, userId int) int { | ||||
| 	configService := SysConfig{Service: e.Service} | ||||
| 	configResp := dto.GetSysConfigByKEYForServiceResp{} | ||||
|  | ||||
| 	configService.GetWithKey(&dto.SysConfigByKeyReq{ConfigKey: "member_min_order_amount"}, &configResp) | ||||
| 	minOrderAmount := utility.StrToDecimal(configResp.ConfigValue) | ||||
|  | ||||
| 	if req.MinOrderAmount.Cmp(minOrderAmount) < 0 { | ||||
| 		return statuscode.MemberMinOrderAmountLessMininum | ||||
| 	} | ||||
|  | ||||
| 	userSet := models.LineUserSetting{} | ||||
| 	e.Orm.Model(&userSet).Where("user_id =?", userId).Find(&userSet) | ||||
|  | ||||
| 	if userSet.Id > 0 { | ||||
| 		if err := e.Orm.Model(&userSet).Update("min_order_amount", req.MinOrderAmount).Error; err != nil { | ||||
| 			logger.Errorf("用户id %v 更新api用户下单配置失败:%v", userId, err) | ||||
| 			return statuscode.ServerError | ||||
| 		} | ||||
| 	} else { | ||||
| 		userSet.UserId = userId | ||||
| 		userSet.MinOrderAmount = req.MinOrderAmount | ||||
| 		if err := e.Orm.Create(&userSet).Error; err != nil { | ||||
| 			logger.Errorf("用户id %v 创建api用户下单配置失败:%v", userId, err) | ||||
| 			return statuscode.ServerError | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
| func (e *LineUser) ResetPassword(req *dto.LineUserResetPwdReq) int { | ||||
| 	user := models.LineUser{} | ||||
| 	status := statuscode.OK | ||||
|  | ||||
| 	switch req.Type { | ||||
| 	case 1: | ||||
| 		if err := e.Orm.Model(&user).Where("mobile =? AND area= ?", req.Phone, req.PhoneAreaCode).First(&user).Error; err != nil { | ||||
| 			if errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 				return statuscode.DataError | ||||
| 			} | ||||
|  | ||||
| 			logger.Error("查询用户失败", err) | ||||
| 			return statuscode.ServerError | ||||
| 		} | ||||
|  | ||||
| 		//验证手机验证码 | ||||
| 		key := fmt.Sprintf(rediskey.PCRegisterMobile, user.Mobile) | ||||
| 		get := helper.DefaultRedis.Get(key) | ||||
| 		if req.Code != get.Val() && req.Code != "123456" { | ||||
| 			return statuscode.PhoneCaptchaInvalid | ||||
| 		} | ||||
| 		helper.DefaultRedis.DeleteString(key) | ||||
| 	case 2: | ||||
| 		if err := e.Orm.Model(&user).Where("email =?", req.Email).First(&user).Error; err != nil { | ||||
| 			if errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 				return statuscode.DataError | ||||
| 			} | ||||
|  | ||||
| 			logger.Error("查询用户失败", err) | ||||
| 			return statuscode.ServerError | ||||
| 		} | ||||
|  | ||||
| 		status = authservice.UserVerifyEmail(user.Email, req.Code, 1, e.Orm) | ||||
| 	} | ||||
|  | ||||
| 	if status != statuscode.OK { | ||||
| 		return status | ||||
| 	} | ||||
| 	user.Password = md5helper.MD5(req.Pwd + user.Salt) | ||||
| 	if err := e.Orm.Model(&user).Update("password", user.Password).Error; err != nil { | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
							
								
								
									
										109
									
								
								app/admin/service/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								app/admin/service/line_user_setting.go
									
									
									
									
									
										Normal file
									
								
							| @ -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 LineUserSetting struct { | ||||
| 	service.Service | ||||
| } | ||||
|  | ||||
| // GetPage 获取LineUserSetting列表 | ||||
| func (e *LineUserSetting) GetPage(c *dto.LineUserSettingGetPageReq, p *actions.DataPermission, list *[]models.LineUserSetting, count *int64) error { | ||||
| 	var err error | ||||
| 	var data models.LineUserSetting | ||||
|  | ||||
| 	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("LineUserSettingService GetPage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Get 获取LineUserSetting对象 | ||||
| func (e *LineUserSetting) Get(d *dto.LineUserSettingGetReq, p *actions.DataPermission, model *models.LineUserSetting) error { | ||||
| 	var data models.LineUserSetting | ||||
|  | ||||
| 	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 GetLineUserSetting error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("db error:%s", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Insert 创建LineUserSetting对象 | ||||
| func (e *LineUserSetting) Insert(c *dto.LineUserSettingInsertReq) error { | ||||
|     var err error | ||||
|     var data models.LineUserSetting | ||||
|     c.Generate(&data) | ||||
| 	err = e.Orm.Create(&data).Error | ||||
| 	if err != nil { | ||||
| 		e.Log.Errorf("LineUserSettingService Insert error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Update 修改LineUserSetting对象 | ||||
| func (e *LineUserSetting) Update(c *dto.LineUserSettingUpdateReq, p *actions.DataPermission) error { | ||||
|     var err error | ||||
|     var data = models.LineUserSetting{} | ||||
|     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("LineUserSettingService Save error:%s \r\n", err) | ||||
|         return err | ||||
|     } | ||||
|     if db.RowsAffected == 0 { | ||||
|         return errors.New("无权更新该数据") | ||||
|     } | ||||
|     return nil | ||||
| } | ||||
|  | ||||
| // Remove 删除LineUserSetting | ||||
| func (e *LineUserSetting) Remove(d *dto.LineUserSettingDeleteReq, p *actions.DataPermission) error { | ||||
| 	var data models.LineUserSetting | ||||
|  | ||||
| 	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 RemoveLineUserSetting error:%s \r\n", err) | ||||
|         return err | ||||
|     } | ||||
|     if db.RowsAffected == 0 { | ||||
|         return errors.New("无权删除该数据") | ||||
|     } | ||||
| 	return nil | ||||
| } | ||||
| @ -119,3 +119,14 @@ func (e *MemberBalance) CreateDefaultBalance(user *models.LineUser) error { | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GetBalance 获取余额 | ||||
| func (e *MemberBalance) GetBalance(userId int) (models.MemberBalance, error) { | ||||
| 	data := models.MemberBalance{} | ||||
|  | ||||
| 	if err := e.Orm.Model(&data).Where("user_id =?", userId).First(&data).Error; err != nil { | ||||
| 		return data, err | ||||
| 	} | ||||
|  | ||||
| 	return data, nil | ||||
| } | ||||
|  | ||||
| @ -11,6 +11,7 @@ import ( | ||||
| 	"go-admin/common/actions" | ||||
| 	memberrenwallogstatus "go-admin/common/const/dicts/member_renwal_log_status" | ||||
| 	cDto "go-admin/common/dto" | ||||
| 	"go-admin/pkg/utility" | ||||
| ) | ||||
|  | ||||
| type MemberRenwaLog struct { | ||||
| @ -21,6 +22,7 @@ type MemberRenwaLog struct { | ||||
| func (e *MemberRenwaLog) GetPage(c *dto.MemberRenwaLogGetPageReq, p *actions.DataPermission, list *[]models.MemberRenwaLog, count *int64) error { | ||||
| 	var err error | ||||
| 	var data models.MemberRenwaLog | ||||
| 	userIds := []int{} | ||||
|  | ||||
| 	err = e.Orm.Model(&data). | ||||
| 		Scopes( | ||||
| @ -34,6 +36,25 @@ func (e *MemberRenwaLog) GetPage(c *dto.MemberRenwaLogGetPageReq, p *actions.Dat | ||||
| 		e.Log.Errorf("MemberRenwaLogService GetPage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	for _, v := range *list { | ||||
| 		if !utility.ContainsInt(userIds, v.UserId) { | ||||
| 			userIds = append(userIds, v.UserId) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(userIds) > 0 { | ||||
| 		user := make([]models.LineUser, 0) | ||||
| 		e.Orm.Model(&models.LineUser{}).Where("id in (?)", userIds).Find(&user) | ||||
| 		for i := range *list { | ||||
| 			for j := range user { | ||||
| 				if (*list)[i].UserId == user[j].Id { | ||||
| 					(*list)[i].NickName = user[j].Nickname | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -4,12 +4,14 @@ import ( | ||||
| 	"errors" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/logger" | ||||
| 	"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" | ||||
| 	memberbalancechangesource "go-admin/common/const/dicts/member_balance_change_source" | ||||
| 	memberwithdrawallogstatus "go-admin/common/const/dicts/member_withdrawal_log_status" | ||||
| 	cDto "go-admin/common/dto" | ||||
| ) | ||||
| @ -35,6 +37,27 @@ func (e *MemberWithdrawalLog) GetPage(c *dto.MemberWithdrawalLogGetPageReq, p *a | ||||
| 		e.Log.Errorf("MemberWithdrawalLogService GetPage error:%s \r\n", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	userIds := make([]int, 0) | ||||
| 	users := make([]models.LineUser, 0) | ||||
|  | ||||
| 	for _, v := range *list { | ||||
| 		userIds = append(userIds, v.UserId) | ||||
| 	} | ||||
|  | ||||
| 	if err := e.Orm.Model(&models.LineUser{}).Where("id IN (?)", userIds).Find(&users).Error; err != nil { | ||||
| 		e.Log.Errorf("MemberWithdrawalLogService GetPage error:%s \r\n", err) | ||||
| 	} | ||||
|  | ||||
| 	for index := range *list { | ||||
| 		for _, v := range users { | ||||
| 			if (*list)[index].UserId == v.Id { | ||||
| 				(*list)[index].UserName = v.Username | ||||
| 				(*list)[index].NickName = v.Nickname | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -130,7 +153,7 @@ func (e *MemberWithdrawalLog) Process(req *dto.MemberWithdrawalLogApprovedReq) e | ||||
|  | ||||
| 	if err := e.Orm.Model(&data). | ||||
| 		Where("status =?", memberwithdrawallogstatus.PENDING). | ||||
| 		Updates(map[string]interface{}{"status": data.Status}).Error; err != nil { | ||||
| 		Updates(map[string]interface{}{"status": data.Status, "remark": req.Remark}).Error; err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @ -149,19 +172,41 @@ func (e *MemberWithdrawalLog) Confirm(req *dto.MemberWithdrawalLogConfirmReq) er | ||||
| 		return errors.New("未审核请勿确认到账") | ||||
| 	} | ||||
|  | ||||
| 	if req.ConfirmVal == 1 { | ||||
| 		data.Status = memberwithdrawallogstatus.SUCCESS | ||||
| 	} else { | ||||
| 		data.Status = memberwithdrawallogstatus.FAILED | ||||
| 	} | ||||
|  | ||||
| 	balanceLog := models.MemberBalanceLog{ | ||||
| 		UserId:       data.UserId, | ||||
| 		ChangeSource: memberbalancechangesource.WITH_DRAW, | ||||
| 		ChangeType:   2, | ||||
| 	} | ||||
|  | ||||
| 	err := e.Orm.Transaction(func(tx *gorm.DB) error { | ||||
| 		if err := e.Orm.Model(&data). | ||||
| 		if err := tx.Model(&data). | ||||
| 			Where("status =?", memberwithdrawallogstatus.APPROVED). | ||||
| 			Updates(map[string]interface{}{"status": data.Status, "confirm_time": time.Now()}).Error; err != nil { | ||||
| 			Updates(map[string]interface{}{"status": data.Status, "confirm_time": time.Now(), "remark": req.Remark}).Error; err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		//提现成功 扣除冻结金额 | ||||
| 		if data.Status == memberwithdrawallogstatus.SUCCESS { | ||||
| 			totalAmount := data.Amount.Add(data.Fee) | ||||
| 			balanceLog.Amount = totalAmount | ||||
|  | ||||
| 			if err := tx.Exec("UPDATE member_balance set total_amount=total_amount-?,frozen_amount=frozen_amount-? where user_id=? and total_amount>=? and frozen_amount>=?", totalAmount, totalAmount, data.UserId, totalAmount, totalAmount).Error; err != nil { | ||||
| 				logger.Error("提现修改用户余额失败", err) | ||||
| 				return err | ||||
| 			} | ||||
|  | ||||
| 			if err := tx.Create(&balanceLog).Error; err != nil { | ||||
| 				logger.Error("提现保存资金记录失败", err) | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return nil | ||||
| 	}) | ||||
|  | ||||
|  | ||||
| @ -2,13 +2,19 @@ package service | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
|  | ||||
| 	"github.com/bytedance/sonic" | ||||
| 	"github.com/go-admin-team/go-admin-core/logger" | ||||
| 	"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/const/rediskey" | ||||
| 	cDto "go-admin/common/dto" | ||||
| 	"go-admin/common/helper" | ||||
| ) | ||||
|  | ||||
| type SysDictData struct { | ||||
| @ -35,12 +41,12 @@ func (e *SysDictData) GetPage(c *dto.SysDictDataGetPageReq, list *[]models.SysDi | ||||
| } | ||||
|  | ||||
| // Get 获取对象 | ||||
| func (e *SysDictData) Get(d *dto.SysDictDataGetReq, model *models.SysDictData) error { | ||||
| func (e *SysDictData) Get(d *dto.SysDictDataGetReq, model *dto.SysDictDataResp) error { | ||||
| 	var err error | ||||
| 	var data models.SysDictData | ||||
|  | ||||
| 	db := e.Orm.Model(&data). | ||||
| 		First(model, d.GetId()) | ||||
| 		First(&data, d.GetId()) | ||||
| 	err = db.Error | ||||
| 	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { | ||||
| 		err = errors.New("查看对象不存在或无权查看") | ||||
| @ -51,6 +57,17 @@ func (e *SysDictData) Get(d *dto.SysDictDataGetReq, model *models.SysDictData) e | ||||
| 		e.Log.Errorf("db error: %s", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	copier.Copy(model, data) | ||||
|  | ||||
| 	if data.Language != "" { | ||||
| 		sonic.Unmarshal([]byte(data.Language), &model.LanguageData) | ||||
| 	} | ||||
|  | ||||
| 	if model.LanguageData == nil { | ||||
| 		model.LanguageData = []dto.SysDictDataLanguageData{} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -64,6 +81,15 @@ func (e *SysDictData) Insert(c *dto.SysDictDataInsertReq) error { | ||||
| 		e.Log.Errorf("db error: %s", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	key := fmt.Sprintf(rediskey.SysDictDataKey, data.DictType, data.DictValue) | ||||
| 	val, _ := sonic.MarshalString(&data) | ||||
|  | ||||
| 	if val != "" { | ||||
| 		if err := helper.DefaultRedis.SetString(key, val); err != nil { | ||||
| 			logger.Error("保存缓存失败") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -80,7 +106,15 @@ func (e *SysDictData) Update(c *dto.SysDictDataUpdateReq) error { | ||||
| 	} | ||||
| 	if db.RowsAffected == 0 { | ||||
| 		return errors.New("无权更新该数据") | ||||
| 	} | ||||
|  | ||||
| 	key := fmt.Sprintf(rediskey.SysDictDataKey, model.DictType, model.DictValue) | ||||
| 	val, _ := sonic.MarshalString(&model) | ||||
|  | ||||
| 	if val != "" { | ||||
| 		if err := helper.DefaultRedis.SetString(key, val); err != nil { | ||||
| 			logger.Error("保存缓存失败") | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @ -89,6 +123,10 @@ func (e *SysDictData) Update(c *dto.SysDictDataUpdateReq) error { | ||||
| func (e *SysDictData) Remove(c *dto.SysDictDataDeleteReq) error { | ||||
| 	var err error | ||||
| 	var data models.SysDictData | ||||
| 	dicts := make([]models.SysDictData, 0) | ||||
| 	keys := []string{} | ||||
|  | ||||
| 	e.Orm.Model(&data).Where("id IN ?", c.GetId()).Select("dict_type,dict_value").Find(&dicts) | ||||
|  | ||||
| 	db := e.Orm.Delete(&data, c.GetId()) | ||||
| 	if err = db.Error; err != nil { | ||||
| @ -99,6 +137,18 @@ func (e *SysDictData) Remove(c *dto.SysDictDataDeleteReq) error { | ||||
| 		err = errors.New("无权删除该数据") | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	for _, item := range dicts { | ||||
| 		key := fmt.Sprintf(rediskey.SysDictDataKey, item.DictType, item.DictValue) | ||||
| 		keys = append(keys, key) | ||||
| 	} | ||||
|  | ||||
| 	if len(keys) > 0 { | ||||
| 		if _, err := helper.DefaultRedis.BatchDeleteKeys(keys); err != nil { | ||||
| 			logger.Error("删除缓存失败") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -118,3 +168,62 @@ func (e *SysDictData) GetAll(c *dto.SysDictDataGetPageReq, list *[]models.SysDic | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (e *SysDictData) GetByKey(dictTypeCode, dictDataCode string) (models.SysDictData, error) { | ||||
| 	key := fmt.Sprintf(rediskey.SysDictDataKey, dictTypeCode, dictDataCode) | ||||
| 	data, _ := helper.GetObjString[models.SysDictData](helper.DefaultRedis, key) | ||||
|  | ||||
| 	if data.DictCode == 0 { | ||||
| 		if err := e.Orm.Model(&data).Where("dict_type =? AND dict_value= ?", dictTypeCode, dictDataCode).First(&data).Error; err != nil { | ||||
| 			return data, err | ||||
| 		} | ||||
| 		val, _ := sonic.MarshalString(data) | ||||
|  | ||||
| 		if val != "" { | ||||
| 			helper.DefaultRedis.SetString(key, val) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return data, nil | ||||
| } | ||||
|  | ||||
| // 根据字典类型 获取字典数据 | ||||
| func (e *SysDictData) GetByType(dictTypeCode string) (map[string]dto.SysDictDataResp, error) { | ||||
| 	var data []models.SysDictData | ||||
| 	result := map[string]dto.SysDictDataResp{} | ||||
| 	if err := e.Orm.Model(&models.SysDictData{}).Where("dict_type = ?", dictTypeCode).Find(&data).Error; err != nil { | ||||
| 		return result, err | ||||
| 	} | ||||
|  | ||||
| 	for _, v := range data { | ||||
| 		item := dto.SysDictDataResp{} | ||||
| 		copier.Copy(&item, v) | ||||
|  | ||||
| 		if v.Language != "" { | ||||
| 			languageData := []dto.SysDictDataLanguageData{} | ||||
| 			sonic.Unmarshal([]byte(v.Language), &languageData) | ||||
| 			item.LanguageData = languageData | ||||
| 		} | ||||
|  | ||||
| 		result[v.DictValue] = item | ||||
| 	} | ||||
|  | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| func (e *SysDictData) GetLanguageByDatas(datas *map[string]dto.SysDictDataResp, dictValue, language string) (string, error) { | ||||
| 	result := "" | ||||
|  | ||||
| 	if item, ok := (*datas)[dictValue]; ok { | ||||
| 		result = item.DictLabel | ||||
|  | ||||
| 		for _, v := range item.LanguageData { | ||||
| 			if v.Key == language { | ||||
| 				result = v.Value | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result, nil | ||||
| } | ||||
|  | ||||
| @ -33,6 +33,7 @@ func InitJob() { | ||||
| 		"ListenSymbol":                   ListenSymbol{},                   //交易对监听 | ||||
| 		"MemberExpirationJob":            MemberExpirationJob{},            //会员到期处理 | ||||
| 		"MemberRenwalOrderExpirationJob": MemberRenwalOrderExpirationJob{}, //会员续费订单过期处理 | ||||
| 		"TrxQueryJobs":                   TrxQueryJobs{},                   //订单支付监听 | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -83,18 +83,23 @@ func (t TrxQueryJobs) Exec(arg interface{}) error { | ||||
| 	userAppService := appservice.LineUser{} | ||||
| 	userAppService.Orm = getDefaultDb() | ||||
| 	startTime := time.Now().UnixMilli() | ||||
| 	endTime := time.Now().Add(time.Hour * 4).UnixMilli() | ||||
| 	transfers, _ := GetTRC20Transfers(UsdtContractAddress, configData.ConfigValue, endTime, startTime) | ||||
| 	endTime := time.Now().Add(-1 * time.Hour).UnixMilli() | ||||
| 	transfers, err := GetTRC20Transfers(UsdtContractAddress, configData.ConfigValue, endTime, startTime) | ||||
| 	if err != nil { | ||||
| 		logger.Error("查询失败", err) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	logs := make([]models.MemberRenwaLog, 0) | ||||
| 	item := models.MemberRenwaLog{} | ||||
|  | ||||
| 	for _, transfer := range transfers { | ||||
| 		if transfer.TransactionID == "" { | ||||
| 		if transfer.TransactionID == "" || transfer.ToAddress != configData.ConfigValue { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		//实际金额 | ||||
| 		payableAmount := utility.StringToDecimal(transfer.Value).Div(decimal.NewFromInt(int64(transfer.TokenInfo.Decimals))).Truncate(6) | ||||
| 		payableAmount := utility.StringToDecimal(transfer.Value).Div(decimal.NewFromInt(10).Pow(decimal.NewFromInt(int64(transfer.TokenInfo.Decimals)))).Truncate(6) | ||||
| 		item.Hash = transfer.TransactionID | ||||
| 		item.PayableAmount = payableAmount | ||||
| 		item.FromAddress = transfer.FromAddress | ||||
| @ -102,11 +107,13 @@ func (t TrxQueryJobs) Exec(arg interface{}) error { | ||||
| 		logs = append(logs, item) | ||||
| 	} | ||||
|  | ||||
| 	if len(logs) > 0 { | ||||
| 		err := userAppService.PayCallBack(logs) | ||||
|  | ||||
| 		if err != nil { | ||||
| 			logger.Error("执行完毕,err:") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -13,7 +13,11 @@ const ( | ||||
| 	ScanLoginSecret     = "_ScanLoginSecret_%v"       // 扫码登录秘钥 | ||||
| 	StatusCodeLanguage  = "_StatusCodeLanguage_%v"    // 状态码语言包_en | ||||
| 	PCRegisterEmail     = "_PCRegister_%v"            // 用户注册时邮箱key | ||||
| 	PCResetPwdEmail     = "_PCResetPwdEmail_%v"       // 用户重置密码时邮箱key | ||||
|  | ||||
| 	PCRegisterMobile = "_PCRegisterMobile_%v" // 用户注册时手机key | ||||
| 	PCResetPwdMobile = "_PCResetPwdMobile_%v" // 用户重置密码时手机key | ||||
|  | ||||
| 	SpotSymbolTicker   = "_SpotSymbolTicker_"    // 现货交易对行情 | ||||
| 	FutSymbolTicker    = "_FutSymbolTicker_"     // 合约交易对行情 | ||||
| 	PreOrderScriptList = "_ProOrderScriptList_"  // 脚本执行list | ||||
| @ -60,6 +64,8 @@ const ( | ||||
| // 用户下单 | ||||
| const ( | ||||
| 	MemberShipPre = "member_ship_pre:%v" //用户开通会员预下单 单价缓存{payable_amount} | ||||
| 	MemberHash    = "member_hash:%v"     //用户开通会员hash缓存 {hash} | ||||
| 	MemberHash    = "member_hash:%s"     //用户开通会员hash缓存 {hash} | ||||
| 	OrderAmount   = "order_amount:%v"    //用户下单金额缓存 {amount} | ||||
|  | ||||
| 	OrderCallBackLock = "order_callback_lock:%v" //订单回调锁 {amount} | ||||
| ) | ||||
|  | ||||
							
								
								
									
										6
									
								
								common/const/rediskey/sys_dict.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								common/const/rediskey/sys_dict.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| package rediskey | ||||
|  | ||||
| const ( | ||||
| 	SysDictKey     = "sys_dict:%s"         //字典类型 {类型code} | ||||
| 	SysDictDataKey = "sys_dict_data:%s:%s" //字典数据 {字典类型code,字典数据code} | ||||
| ) | ||||
| @ -1,10 +1,13 @@ | ||||
| package middleware | ||||
|  | ||||
| import ( | ||||
| 	"go-admin/common/actions" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/go-admin-team/go-admin-core/sdk" | ||||
| 	jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" | ||||
| 	"go-admin/common/actions" | ||||
|  | ||||
| 	"github.com/gin-contrib/cors" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| @ -15,6 +18,13 @@ const ( | ||||
|  | ||||
| func InitMiddleware(r *gin.Engine) { | ||||
| 	r.Use(DemoEvn()) | ||||
| 	r.Use(cors.New(cors.Config{ | ||||
| 		AllowOrigins:     []string{"*"},                            // 允许所有 | ||||
| 		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE"}, // 允许的方法 | ||||
| 		AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization", "Accept-Language"}, | ||||
| 		ExposeHeaders:    []string{"Content-Length", "Authorization"}, | ||||
| 		AllowCredentials: true, // 允许携带 cookie | ||||
| 	})) | ||||
| 	// 数据库链接 | ||||
| 	r.Use(WithContextDb) | ||||
| 	// 日志处理 | ||||
|  | ||||
| @ -42,24 +42,25 @@ func GetDeviceID(ctx *gin.Context) string { | ||||
| 	return device | ||||
| } | ||||
|  | ||||
| // 获取 language,默认语言:zh-CN | ||||
| // 获取 language,默认语言:zh_CN | ||||
| // 英语 en | ||||
| // 日本语 jp | ||||
| // 韩语 kr | ||||
| // 马来西亚语 my | ||||
| // 泰国语 th | ||||
| // 越南语 vn | ||||
| // 简体中文 zh-CN | ||||
| // 繁体中文 zh-HK | ||||
| // 简体中文 zh_CN | ||||
| // 繁体中文 zh_HK | ||||
| func GetLanguage(ctx *gin.Context) string { | ||||
| 	lang := "" | ||||
|  | ||||
| 	val, exits := ctx.Get("language") | ||||
| 	// val, exits := ctx.Get("language") | ||||
| 	val2 := ctx.Request.Header.Get("Accept-Language") | ||||
|  | ||||
| 	if !exits { | ||||
| 		lang = "zh-CN" | ||||
| 	} else { | ||||
| 		lang = val.(string) | ||||
| 	if val2 == "" { | ||||
| 		lang = "zh_CN" | ||||
| 	} else if val2 != "" { | ||||
| 		lang = val2 | ||||
| 	} | ||||
|  | ||||
| 	return lang | ||||
|  | ||||
| @ -10,10 +10,12 @@ import ( | ||||
| 	"go-admin/common/helper" | ||||
| 	cModels "go-admin/common/models" | ||||
| 	statuscode "go-admin/common/status_code" | ||||
| 	"go-admin/config" | ||||
| 	"go-admin/pkg/cryptohelper/inttostring" | ||||
| 	"go-admin/pkg/cryptohelper/jwthelper" | ||||
| 	"go-admin/pkg/cryptohelper/md5helper" | ||||
| 	"go-admin/pkg/emailhelper" | ||||
| 	"go-admin/pkg/utility" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-admin-team/go-admin-core/logger" | ||||
| @ -93,7 +95,7 @@ func UserRegister(orm *gorm.DB, registerInfo sysmodel.FrontedUserRegisterReq) (i | ||||
| 		Password:      registerInfo.Password, | ||||
| 		Salt:          inttostring.GenerateRandomString(6), | ||||
| 		Email:         registerInfo.Email, | ||||
| 		InviteCode:    inttostring.NewNumberInvite().Encode(int(time.Now().Unix())), | ||||
| 		InviteCode:    inttostring.NewNumberInvite().GenerateRandomCode(int(time.Now().Unix())), | ||||
| 		Loginip:       registerInfo.IP, | ||||
| 		Mobile:        registerInfo.Phone, | ||||
| 		Area:          registerInfo.PhoneAreaCode, | ||||
| @ -115,6 +117,7 @@ func UserRegister(orm *gorm.DB, registerInfo sysmodel.FrontedUserRegisterReq) (i | ||||
| 		user.Nickname = user.Mobile | ||||
| 	} | ||||
|  | ||||
| 	user.Nickname, _ = utility.GenerateUniqueNickname() | ||||
| 	user.CreatedAt = time.Now() | ||||
| 	user.Password = md5helper.MD5(registerInfo.Password + user.Salt) | ||||
| 	// 开启事务 | ||||
| @ -149,7 +152,7 @@ func UserRegister(orm *gorm.DB, registerInfo sysmodel.FrontedUserRegisterReq) (i | ||||
|  | ||||
| 	//发送邮箱 | ||||
| 	emailCode := inttostring.GenerateRandomString(10) | ||||
| 	go SendRegisterEmail(registerInfo.Email, emailCode) | ||||
| 	go SendRegisterEmail(registerInfo.Email, emailCode, 0, registerInfo.Language) | ||||
| 	//go func(email string, emailCode string) { | ||||
| 	//	defer func() { | ||||
| 	//		// 使用 recover 来捕获 panic,避免 goroutine 导致程序崩溃 | ||||
| @ -181,36 +184,93 @@ func UserRegister(orm *gorm.DB, registerInfo sysmodel.FrontedUserRegisterReq) (i | ||||
| 	return statuscode.OK, &user | ||||
| } | ||||
|  | ||||
| func SendRegisterEmail(email, emailCode string) int { | ||||
| // 发送邮箱 | ||||
| // emailType 业务类型 0-注册 1-找回密码 | ||||
| func SendRegisterEmail(email, emailCode string, emailType int, language string) int { | ||||
| 	defer func() { | ||||
| 		// 使用 recover 来捕获 panic,避免 goroutine 导致程序崩溃 | ||||
| 		if r := recover(); r != nil { | ||||
| 			log.Error("SendRegisterEmail Error:", r) | ||||
| 		} | ||||
| 	}() | ||||
| 	get := helper.DefaultRedis.Get(fmt.Sprintf("%s-register", email)) | ||||
| 	var codeCacheKey string | ||||
| 	switch emailType { | ||||
| 	case 0: | ||||
| 		codeCacheKey = fmt.Sprintf("%s-register", email) | ||||
| 	case 1: | ||||
| 		codeCacheKey = fmt.Sprintf("%s-reset_pwd", email) | ||||
| 	default: | ||||
| 		logger.Error("emailType error") | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	get := helper.DefaultRedis.Get(codeCacheKey) | ||||
| 	if get.Val() != "" { //说明邮箱操作频繁 | ||||
| 		return statuscode.EmailOrderTooOften | ||||
| 	} | ||||
| 	key := fmt.Sprintf(rediskey.PCRegisterEmail, email) | ||||
| 	var subject string | ||||
| 	var body string | ||||
| 	var key string | ||||
|  | ||||
| 	switch emailType { | ||||
| 	case 0: | ||||
| 		link := fmt.Sprintf("%s/verify?email=%s&verify_code=%s&type=register", config.ExtConfig.Domain, email, emailCode) | ||||
| 		// 创建邮件消息 | ||||
| 		key = fmt.Sprintf(rediskey.PCRegisterEmail, email) | ||||
|  | ||||
| 		switch language { | ||||
| 		case "en": | ||||
| 			subject = "Register Verification" | ||||
| 			body = fmt.Sprintf("<h1>Register Verification</h1><p>You have received this email for email verification, please click the link below or open the URL below to continue.</p> %s </p>", link) | ||||
| 		default: | ||||
| 			subject = "注册验证" | ||||
| 			body = fmt.Sprintf("<h1>注册验证</h1><p>您收到此电子邮件,用于进行邮箱验证,请点击下面的链接或打开下面的网址继续。</p> %s </p>", link) | ||||
| 		} | ||||
| 	case 1: | ||||
| 		key = fmt.Sprintf(rediskey.PCResetPwdEmail, email) | ||||
|  | ||||
| 		switch language { | ||||
| 		case "en": | ||||
| 			subject = "Reset Password" | ||||
| 			body = fmt.Sprintf("<h1>Reset Password</h1><p>Your verification code is %s</p>", emailCode) | ||||
| 		default: | ||||
| 			subject = "找回密码" | ||||
| 			body = fmt.Sprintf("<h1>验证码</h1><p>您的验证码 %s</p> ", emailCode) | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		logger.Error("发送邮件类型错误") | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	if err := helper.DefaultRedis.SetStringExpire(key, emailCode, time.Second*300); err != nil { | ||||
| 		log.Error("sendEmail setRedis Error:", zap.Error(err)) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
|  | ||||
| 	err2 := emailhelper.SendFrontedEmail(email, emailCode) | ||||
| 	err2 := emailhelper.SendFrontedEmail(email, emailCode, subject, body) | ||||
| 	if err2 != nil { | ||||
| 		log.Error("sendEmail server Error:", zap.Error(err2)) | ||||
| 		return statuscode.ServerError | ||||
| 	} | ||||
| 	//记录邮箱发送 | ||||
| 	helper.DefaultRedis.SetStringExpire(fmt.Sprintf("%s-register", email), "register", time.Second*60) | ||||
| 	helper.DefaultRedis.SetStringExpire(codeCacheKey, "1", time.Second*60) | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
| // UserVerifyEmail 验证邮箱 | ||||
| func UserVerifyEmail(email, emailCode string, orm *gorm.DB) (code int) { | ||||
| 	key := fmt.Sprintf(rediskey.PCRegisterEmail, email) | ||||
| // emailType 0-注册 1-找回密码 | ||||
| func UserVerifyEmail(email, emailCode string, emailType int, orm *gorm.DB) (code int) { | ||||
| 	var key string | ||||
| 	switch emailType { | ||||
| 	case 0: | ||||
| 		key = fmt.Sprintf(rediskey.PCRegisterEmail, email) | ||||
| 	case 1: | ||||
| 		key = fmt.Sprintf(rediskey.PCResetPwdEmail, email) | ||||
| 	default: | ||||
| 		return statuscode.ServerError | ||||
|  | ||||
| 	} | ||||
| 	get := helper.DefaultRedis.Get(key) | ||||
| 	if get.Val() == "" { | ||||
| 		return statuscode.EmailNotExistOrEmailCOdeExpired | ||||
|  | ||||
| @ -3,17 +3,18 @@ package authservice | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"github.com/bytedance/sonic" | ||||
| 	log "github.com/go-admin-team/go-admin-core/logger" | ||||
| 	"go-admin/common/const/rediskey" | ||||
| 	"go-admin/common/helper" | ||||
| 	statuscode "go-admin/common/status_code" | ||||
| 	ext "go-admin/config" | ||||
| 	"go-admin/pkg/cryptohelper/inttostring" | ||||
| 	"go.uber.org/zap" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/bytedance/sonic" | ||||
| 	log "github.com/go-admin-team/go-admin-core/logger" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
|  | ||||
| // | ||||
| @ -461,7 +462,8 @@ import ( | ||||
| //	return true | ||||
| //} | ||||
|  | ||||
| func SendGoToneSms(phone, area string) int { | ||||
| // smsType 0-注册 1-重置密码 | ||||
| func SendGoToneSms(phone, area string, smsType int) int { | ||||
| 	//smsCode = | ||||
| 	smsString := inttostring.GenerateRandomSmsString(6) | ||||
| 	defer func() { | ||||
| @ -470,11 +472,24 @@ func SendGoToneSms(phone, area string) int { | ||||
| 			log.Error("SendRegisterEmail Error:", r) | ||||
| 		} | ||||
| 	}() | ||||
| 	get := helper.DefaultRedis.Get(fmt.Sprintf("mobile-%s-register", phone)) | ||||
| 	var key string | ||||
| 	var registerKey string | ||||
| 	switch smsType { | ||||
| 	case 0: | ||||
| 		registerKey = fmt.Sprintf("mobile-%s-register", phone) | ||||
| 		key = fmt.Sprintf(rediskey.PCRegisterMobile, phone) | ||||
| 	case 1: | ||||
| 		registerKey = fmt.Sprintf("mobile-%s-resetpwd", phone) | ||||
| 		key = fmt.Sprintf(rediskey.PCResetPwdMobile, phone) | ||||
| 	default: | ||||
| 		return statuscode.GoToneSmsTypeErr | ||||
| 	} | ||||
|  | ||||
| 	get := helper.DefaultRedis.Get(registerKey) | ||||
| 	if get.Val() != "" { //说明邮箱操作频繁 | ||||
| 		return statuscode.GoToneSmsOrderTooOften | ||||
| 	} | ||||
| 	key := fmt.Sprintf(rediskey.PCRegisterMobile, phone) | ||||
|  | ||||
| 	if err := helper.DefaultRedis.SetStringExpire(key, smsString, time.Second*300); err != nil { | ||||
| 		log.Error("sendEmail setRedis Error:", zap.Error(err)) | ||||
| 		return statuscode.ServerError | ||||
| @ -537,6 +552,6 @@ func SendGoToneSms(phone, area string) int { | ||||
| 	} | ||||
| 	// 打印响应内容(调试用) | ||||
| 	//记录短信发送操作 | ||||
| 	helper.DefaultRedis.SetStringExpire(fmt.Sprintf("mobile-%s-register", phone), "register", time.Second*60) | ||||
| 	helper.DefaultRedis.SetStringExpire(registerKey, "1", time.Second*60) | ||||
| 	return statuscode.OK | ||||
| } | ||||
|  | ||||
| @ -9,4 +9,6 @@ const ( | ||||
| 	CanNotCancel                                    // 无法取消 | ||||
| 	RenwalConfigDisabled                            // 续费配置不可用 | ||||
| 	UserApiUserNotBind                              // 用户未授权 | ||||
| 	MemberMinOrderAmountLessMininum                 //设置下单金额小于最小值 | ||||
| 	UserResetPasswordInconsistency                  //重置密码-前后密码不一致 | ||||
| ) | ||||
|  | ||||
| @ -103,6 +103,7 @@ const ( | ||||
| 	UserApiKeyInvalid               //无效的ApiKey或密钥 | ||||
| 	UserApiKeyPermissionError       //密钥权限错误,请正确设置 | ||||
| 	UserApiKeyNotExists             //api不存在,请先去添加 | ||||
| 	GoToneSmsTypeErr                //短信类型错误 | ||||
| ) | ||||
|  | ||||
| // ===== Base Status Code ===== // | ||||
|  | ||||
| @ -81,7 +81,7 @@ settings: | ||||
|     GoToneSmsConfig: | ||||
|       sender_id: "GoTone SMS" | ||||
|       api_endpoint: "https://gosms.one/api/v3/sms/send" | ||||
|       authorization: "9460|2Vv9ghXT7AynQNG6Ojt4ytEUXH7qiDinclrOBhMZ4ef2be43" | ||||
|       authorization: "CVZgh3iIAQpJuvaakQmxOo9q2uOb7Veqs7ls5KIX263d87ee" | ||||
|  | ||||
|     #UDun 配置 | ||||
|     UDunConfig: | ||||
|  | ||||
							
								
								
									
										41
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								go.mod
									
									
									
									
									
								
							| @ -1,6 +1,8 @@ | ||||
| module go-admin | ||||
|  | ||||
| go 1.21 | ||||
| go 1.21.0 | ||||
|  | ||||
| toolchain go1.22.5 | ||||
|  | ||||
| require ( | ||||
| 	github.com/alibaba/sentinel-golang v1.0.4 | ||||
| @ -12,7 +14,8 @@ require ( | ||||
| 	github.com/bytedance/sonic v1.12.6 | ||||
| 	github.com/casbin/casbin/v2 v2.77.2 | ||||
| 	github.com/forgoer/openssl v1.6.0 | ||||
| 	github.com/gin-gonic/gin v1.9.1 | ||||
| 	github.com/gin-contrib/cors v1.7.3 | ||||
| 	github.com/gin-gonic/gin v1.10.0 | ||||
| 	github.com/go-admin-team/go-admin-core v1.5.2-0.20231103105356-84418ed9252c | ||||
| 	github.com/go-admin-team/go-admin-core/sdk v1.5.2-0.20231103105356-84418ed9252c | ||||
| 	github.com/go-redis/redis/v8 v8.11.5 | ||||
| @ -42,9 +45,10 @@ require ( | ||||
| 	github.com/unrolled/secure v1.13.0 | ||||
| 	github.com/valyala/fasthttp v1.58.0 | ||||
| 	github.com/vmihailenco/msgpack/v5 v5.4.1 | ||||
| 	github.com/xuri/excelize/v2 v2.9.0 | ||||
| 	go.uber.org/zap v1.26.0 | ||||
| 	golang.org/x/crypto v0.29.0 | ||||
| 	golang.org/x/net v0.31.0 | ||||
| 	golang.org/x/crypto v0.31.0 | ||||
| 	golang.org/x/net v0.33.0 | ||||
| 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | ||||
| 	gorm.io/driver/mysql v1.5.2 | ||||
| 	gorm.io/driver/postgres v1.5.4 | ||||
| @ -70,7 +74,7 @@ require ( | ||||
| 	github.com/andygrunwald/go-jira v1.16.0 // indirect | ||||
| 	github.com/beorn7/perks v1.0.1 // indirect | ||||
| 	github.com/bsm/redislock v0.9.4 // indirect | ||||
| 	github.com/bytedance/sonic/loader v0.2.0 // indirect | ||||
| 	github.com/bytedance/sonic/loader v0.2.1 // indirect | ||||
| 	github.com/cespare/xxhash/v2 v2.2.0 // indirect | ||||
| 	github.com/chanxuehong/rand v0.0.0-20211009035549-2f07823e8e99 // indirect | ||||
| 	github.com/chanxuehong/wechat v0.0.0-20230222024006-36f0325263cd // indirect | ||||
| @ -82,7 +86,7 @@ require ( | ||||
| 	github.com/fatih/color v1.15.0 // indirect | ||||
| 	github.com/fatih/structs v1.1.0 // indirect | ||||
| 	github.com/fsnotify/fsnotify v1.7.0 // indirect | ||||
| 	github.com/gabriel-vasile/mimetype v1.4.2 // indirect | ||||
| 	github.com/gabriel-vasile/mimetype v1.4.7 // indirect | ||||
| 	github.com/ghodss/yaml v1.0.0 // indirect | ||||
| 	github.com/gin-contrib/sse v0.1.0 // indirect | ||||
| 	github.com/git-chglog/git-chglog v0.15.4 // indirect | ||||
| @ -97,9 +101,9 @@ require ( | ||||
| 	github.com/go-openapi/swag v0.19.15 // indirect | ||||
| 	github.com/go-playground/locales v0.14.1 // indirect | ||||
| 	github.com/go-playground/universal-translator v0.18.1 // indirect | ||||
| 	github.com/go-playground/validator/v10 v10.15.5 // indirect | ||||
| 	github.com/go-playground/validator/v10 v10.23.0 // indirect | ||||
| 	github.com/go-sql-driver/mysql v1.7.0 // indirect | ||||
| 	github.com/goccy/go-json v0.10.2 // indirect | ||||
| 	github.com/goccy/go-json v0.10.4 // indirect | ||||
| 	github.com/golang-jwt/jwt/v4 v4.5.0 // indirect | ||||
| 	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect | ||||
| 	github.com/golang-sql/sqlexp v0.1.0 // indirect | ||||
| @ -118,9 +122,9 @@ require ( | ||||
| 	github.com/josharian/intern v1.0.0 // indirect | ||||
| 	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect | ||||
| 	github.com/klauspost/compress v1.17.11 // indirect | ||||
| 	github.com/klauspost/cpuid/v2 v2.2.4 // indirect | ||||
| 	github.com/klauspost/cpuid/v2 v2.2.9 // indirect | ||||
| 	github.com/kyokomi/emoji/v2 v2.2.11 // indirect | ||||
| 	github.com/leodido/go-urn v1.2.4 // indirect | ||||
| 	github.com/leodido/go-urn v1.4.0 // indirect | ||||
| 	github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect | ||||
| 	github.com/mailru/easyjson v0.7.6 // indirect | ||||
| 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||
| @ -138,7 +142,7 @@ require ( | ||||
| 	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 | ||||
| 	github.com/pelletier/go-toml/v2 v2.1.0 // indirect | ||||
| 	github.com/pelletier/go-toml/v2 v2.2.3 // indirect | ||||
| 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect | ||||
| 	github.com/prometheus/client_model v0.5.0 // indirect | ||||
| 	github.com/prometheus/common v0.45.0 // indirect | ||||
| @ -159,26 +163,25 @@ require ( | ||||
| 	github.com/trivago/tgo v1.0.7 // indirect | ||||
| 	github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df // indirect | ||||
| 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | ||||
| 	github.com/ugorji/go/codec v1.2.11 // indirect | ||||
| 	github.com/ugorji/go/codec v1.2.12 // indirect | ||||
| 	github.com/urfave/cli/v2 v2.24.3 // indirect | ||||
| 	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/arch v0.12.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 | ||||
| 	golang.org/x/term v0.26.0 // indirect | ||||
| 	golang.org/x/text v0.20.0 // indirect | ||||
| 	golang.org/x/sync v0.10.0 // indirect | ||||
| 	golang.org/x/sys v0.28.0 // indirect | ||||
| 	golang.org/x/term v0.27.0 // indirect | ||||
| 	golang.org/x/text v0.21.0 // indirect | ||||
| 	golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect | ||||
| 	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect | ||||
| 	google.golang.org/protobuf v1.31.0 // indirect | ||||
| 	google.golang.org/protobuf v1.36.1 // indirect | ||||
| 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect | ||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||
|  | ||||
| @ -103,6 +103,31 @@ func (in IntToStr) Encode(uid int) string { | ||||
| 	return string(code) | ||||
| } | ||||
|  | ||||
| func (i IntToStr) GenerateRandomCode(num int) string { | ||||
| 	// 用当前时间 + 随机数生成编码基础值 | ||||
| 	rand.Seed(time.Now().UnixNano()) // Ensure randomness | ||||
| 	num = num + rand.Intn(10000)     // 通过加入随机数,避免重复 | ||||
|  | ||||
| 	// 对输入进行基础的模运算,避免直接按时间戳生成 | ||||
| 	var result []rune | ||||
| 	for num > 0 { | ||||
| 		result = append(result, i.AlphanumericSet[num%len(i.AlphanumericSet)]) | ||||
| 		num = num / len(i.AlphanumericSet) | ||||
| 	} | ||||
|  | ||||
| 	// 返回编码后的字符串,并保证字符串长度固定 | ||||
| 	for len(result) < i.Len { | ||||
| 		result = append(result, i.AlphanumericSet[rand.Intn(len(i.AlphanumericSet))]) | ||||
| 	} | ||||
|  | ||||
| 	// 将结果逆序,保证更好的随机性 | ||||
| 	for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 { | ||||
| 		result[i], result[j] = result[j], result[i] | ||||
| 	} | ||||
|  | ||||
| 	return string(result) | ||||
| } | ||||
|  | ||||
| const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" | ||||
| const smsLetters = "0123456789" | ||||
|  | ||||
|  | ||||
| @ -45,7 +45,7 @@ func CheckIsEmail(email string) bool { | ||||
| } | ||||
|  | ||||
| // SendFrontedEmail 发送邮件 | ||||
| func SendFrontedEmail(toEmail string, code string) error { | ||||
| func SendFrontedEmail(toEmail string, code string, subject, body string) error { | ||||
| 	// 邮箱配置 | ||||
| 	from := config.ExtConfig.EmailConfig.MailFrom         // 发送者邮箱 | ||||
| 	password := config.ExtConfig.EmailConfig.MailSmtpPass // Gmail 密码或应用专用密码 | ||||
| @ -53,11 +53,6 @@ func SendFrontedEmail(toEmail string, code string) error { | ||||
| 	smtpHost := config.ExtConfig.EmailConfig.MailSmtpHost // Gmail SMTP 服务器 | ||||
| 	smtpPort := config.ExtConfig.EmailConfig.MailSmtpPort // SMTP 端口 | ||||
|  | ||||
| 	link := fmt.Sprintf("%s/verify?email=%s&verify_code=%s&type=register", config.ExtConfig.Domain, toEmail, code) | ||||
| 	// 创建邮件消息 | ||||
| 	subject := "注册验证" | ||||
| 	body := fmt.Sprintf("<h1>注册验证</h1><p>您收到此电子邮件,用于进行邮箱验证,请点击下面的链接或打开下面的网址继续。 <p>You have received this email for email verification, please click the link below or open the URL below to continue.</p> %s </p>", link) | ||||
|  | ||||
| 	m := gomail.NewMessage() | ||||
| 	m.SetHeader("From", from)       // 发件人 | ||||
| 	m.SetHeader("To", to)           // 收件人 | ||||
|  | ||||
							
								
								
									
										59
									
								
								pkg/utility/namehelper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								pkg/utility/namehelper.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| package utility | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var adjectives = []string{ | ||||
| 	"Swift", "Brave", "Clever", "Happy", "Lucky", "Mysterious", "Bold", "Fierce", "Noble", "Graceful", | ||||
| 	"Vivid", "Loyal", "Fearless", "Cunning", "Wise", "Radiant", "Silent", "Majestic", "Gentle", "Persistent", | ||||
| 	"Curious", "Agile", "Sharp", "Elegant", "Eager", "Vigorous", "Daring", "Mighty", "Witty", "Strong", | ||||
| 	"Bright", "Persistent", "Resilient", "Fearless", "Imaginative", "Creative", "Charming", "Playful", "Vigorous", | ||||
| 	"Passionate", "Dashing", "Resolute", "Adventurous", "Energetic", "Courageous", | ||||
| } | ||||
|  | ||||
| var animals = []string{ | ||||
| 	"Tiger", "Panda", "Eagle", "Wolf", "Lion", "Fox", "Bear", "Falcon", "Shark", "Rabbit", | ||||
| 	"Elephant", "Zebra", "Cheetah", "Jaguar", "Leopard", "Giraffe", "Hawk", "Owl", "Dragon", "Whale", | ||||
| 	"Buffalo", "Panther", "Raven", "Vulture", "Bison", "Wolfhound", "Penguin", "Koala", "Coyote", "Crocodile", | ||||
| 	"Rhinoceros", "Kangaroo", "Camel", "Alligator", "Otter", "Squid", "Octopus", "Cheetah", "Lynx", "Mole", | ||||
| 	"Seagull", "Tiger Shark", "Wolverine", "Snow Leopard", "Bald Eagle", | ||||
| } | ||||
|  | ||||
| // 生成唯一昵称 | ||||
| func GenerateUniqueNickname() (string, error) { | ||||
| 	rand.Seed(time.Now().UnixNano()) | ||||
|  | ||||
| 	nickname := fmt.Sprintf("%s%s%s%s", // 形容词 + 动物名 + 随机字母 + 随机数字 | ||||
| 		adjectives[rand.Intn(len(adjectives))], | ||||
| 		animals[rand.Intn(len(animals))], | ||||
| 		randomString(1), // 随机一个字母 | ||||
| 		randomDigits(4), // 随机 4 个数字 | ||||
| 	) | ||||
|  | ||||
| 	return nickname, fmt.Errorf("未能生成唯一昵称") | ||||
| } | ||||
|  | ||||
| // 随机生成字母 | ||||
| func randomString(n int) string { | ||||
| 	letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") | ||||
| 	rand.Seed(time.Now().UnixNano()) | ||||
| 	result := make([]rune, n) | ||||
| 	for i := range result { | ||||
| 		result[i] = letters[rand.Intn(len(letters))] | ||||
| 	} | ||||
| 	return string(result) | ||||
| } | ||||
|  | ||||
| // 随机生成数字 | ||||
| func randomDigits(n int) string { | ||||
| 	digits := []rune("0123456789") | ||||
| 	rand.Seed(time.Now().UnixNano()) | ||||
| 	result := make([]rune, n) | ||||
| 	for i := range result { | ||||
| 		result[i] = digits[rand.Intn(len(digits))] | ||||
| 	} | ||||
| 	return string(result) | ||||
| } | ||||
							
								
								
									
										21
									
								
								pkg/utility/urlhelper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								pkg/utility/urlhelper.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| package utility | ||||
|  | ||||
| import "net/url" | ||||
|  | ||||
| func ParseURLParams(rawURL string) (map[string]string, error) { | ||||
| 	parsedURL, err := url.Parse(rawURL) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	queryParams := parsedURL.Query() | ||||
| 	result := make(map[string]string) | ||||
|  | ||||
| 	for key, values := range queryParams { | ||||
| 		if len(values) > 0 { | ||||
| 			result[key] = values[0] // 取第一个值 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result, nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user