feat: add member URL pool and login tracking
This commit is contained in:
@@ -21,6 +21,8 @@ type AppMemberListInp struct {
|
||||
MemberStatus int `json:"memberStatus" dc:"会员状态"`
|
||||
AutoDispatch int `json:"autoDispatch" dc:"派单模式"`
|
||||
MemberCategory int `json:"memberCategory" dc:"会员类别"`
|
||||
RegisterDomain string `json:"registerDomain" dc:"注册域名(模糊查询)"`
|
||||
DomainStatus int `json:"domainStatus" dc:"域名绑定状态"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt" dc:"注册时间"`
|
||||
}
|
||||
|
||||
@@ -47,6 +49,10 @@ type AppMemberListModel struct {
|
||||
LastLoginRegion string `json:"lastLoginRegion"`
|
||||
TodayTradeCount int `json:"todayTradeCount"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UrlPoolId uint64 `json:"urlPoolId"`
|
||||
RegisterDomain string `json:"registerDomain"`
|
||||
DomainStatus int `json:"domainStatus"`
|
||||
DomainBoundAt *gtime.Time `json:"domainBoundAt"`
|
||||
}
|
||||
|
||||
type AppMemberViewInp struct {
|
||||
@@ -85,11 +91,8 @@ type AppMemberEditInp struct {
|
||||
}
|
||||
|
||||
func (in *AppMemberEditInp) Filter(ctx context.Context) error {
|
||||
if in.Id == 0 && strings.TrimSpace(in.Mobile) == "" {
|
||||
return gerror.New("新增会员时手机号不能为空")
|
||||
}
|
||||
if in.Id == 0 && len(in.Password) < 8 {
|
||||
return gerror.New("新增会员密码不能少于8位")
|
||||
if in.Id == 0 {
|
||||
return gerror.New("后台不支持创建会员,请由会员在C端完成注册")
|
||||
}
|
||||
if in.Password != "" && (len(in.Password) < 8 || !containsLetterAndNumber(in.Password)) {
|
||||
return gerror.New("密码至少8位且必须同时包含字母和数字")
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
type AppMemberRegisterInp struct {
|
||||
Username string `json:"username" v:"required|length:3,64#用户名不能为空|用户名长度为3到64个字符"`
|
||||
Mobile string `json:"mobile" v:"required|phone-loose#手机号不能为空|手机号格式不正确"`
|
||||
Password string `json:"password" v:"required|length:8,64#密码不能为空|密码长度为8到64个字符"`
|
||||
InviteCode string `json:"inviteCode" v:"max-length:32#邀请码不能超过32个字符"`
|
||||
RegisterOrigin string `json:"registerOrigin" v:"max-length:512#注册来源不能超过512个字符"`
|
||||
RegisterHost string `json:"registerHost" v:"max-length:255#注册域名不能超过255个字符"`
|
||||
}
|
||||
|
||||
func (in *AppMemberRegisterInp) Filter(ctx context.Context) error {
|
||||
in.Username = strings.TrimSpace(in.Username)
|
||||
in.Mobile = strings.TrimSpace(in.Mobile)
|
||||
in.InviteCode = strings.TrimSpace(in.InviteCode)
|
||||
if !containsLetterAndNumber(in.Password) {
|
||||
return gerror.New("密码至少8位且必须同时包含字母和数字")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AppMemberRegisterModel struct {
|
||||
MemberId uint64 `json:"memberId"`
|
||||
MemberNo string `json:"memberNo"`
|
||||
Bound bool `json:"bound"`
|
||||
Domain string `json:"domain"`
|
||||
}
|
||||
|
||||
type AppMemberAccountLoginInp struct {
|
||||
Account string `json:"account" v:"required|max-length:64#登录账号不能为空|登录账号不能超过64个字符"`
|
||||
Password string `json:"password" v:"required|max-length:64#登录密码不能为空|登录密码不能超过64个字符"`
|
||||
LoginHost string `json:"loginHost" v:"max-length:255#登录域名不能超过255个字符"`
|
||||
}
|
||||
|
||||
func (in *AppMemberAccountLoginInp) Filter(ctx context.Context) error {
|
||||
in.Account = strings.TrimSpace(in.Account)
|
||||
return nil
|
||||
}
|
||||
|
||||
type AppMemberMobileLoginInp struct {
|
||||
Mobile string `json:"mobile" v:"required|phone-loose#手机号不能为空|手机号格式不正确"`
|
||||
Code string `json:"code" v:"required|length:4,8#验证码不能为空|验证码格式不正确"`
|
||||
LoginHost string `json:"loginHost" v:"max-length:255#登录域名不能超过255个字符"`
|
||||
}
|
||||
|
||||
func (in *AppMemberMobileLoginInp) Filter(ctx context.Context) error {
|
||||
in.Mobile = strings.TrimSpace(in.Mobile)
|
||||
return nil
|
||||
}
|
||||
|
||||
type AppMemberLoginModel struct {
|
||||
Id uint64 `json:"id"`
|
||||
MemberNo string `json:"memberNo"`
|
||||
Username string `json:"username"`
|
||||
Mobile string `json:"mobile"`
|
||||
Token string `json:"token"`
|
||||
Expires int64 `json:"expires"`
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/form"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type AppMemberLoginLogListInp struct {
|
||||
form.PageReq
|
||||
Keyword string `json:"keyword" dc:"会员编号、用户名或手机号"`
|
||||
LoginType int `json:"loginType" dc:"登录方式"`
|
||||
Status int `json:"status" dc:"登录状态"`
|
||||
LoginDomain string `json:"loginDomain" dc:"登录域名"`
|
||||
LoginIp string `json:"loginIp" dc:"登录IP脱敏值"`
|
||||
LoginAt []*gtime.Time `json:"loginAt" dc:"登录时间"`
|
||||
}
|
||||
|
||||
func (in *AppMemberLoginLogListInp) Filter(ctx context.Context) error {
|
||||
if in.LoginType > 0 && !dict.HasOptionKey(consts.AppMemberLoginTypeOptions, in.LoginType) {
|
||||
return gerror.New("登录方式不合法")
|
||||
}
|
||||
if in.Status > 0 && in.Status != consts.StatusEnabled && in.Status != consts.StatusDisable {
|
||||
return gerror.New("登录状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AppMemberLoginLogListModel struct {
|
||||
Id uint64 `json:"id"`
|
||||
ReqId string `json:"reqId"`
|
||||
MemberId uint64 `json:"memberId"`
|
||||
MemberNo string `json:"memberNo"`
|
||||
Username string `json:"username"`
|
||||
MobileMask string `json:"mobileMask"`
|
||||
LoginType int `json:"loginType"`
|
||||
Status int `json:"status"`
|
||||
ErrMsg string `json:"errMsg"`
|
||||
LoginAt *gtime.Time `json:"loginAt"`
|
||||
LoginIpMask string `json:"loginIpMask"`
|
||||
LoginRegion string `json:"loginRegion"`
|
||||
LoginDomain string `json:"loginDomain"`
|
||||
UserAgent string `json:"userAgent"`
|
||||
Os string `json:"os"`
|
||||
Browser string `json:"browser"`
|
||||
}
|
||||
|
||||
type AppMemberLoginLogViewInp struct {
|
||||
Id uint64 `json:"id" v:"required|min:1#日志ID不能为空|日志ID不能为空"`
|
||||
}
|
||||
|
||||
func (in *AppMemberLoginLogViewInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type AppMemberLoginLogViewModel struct {
|
||||
AppMemberLoginLogListModel
|
||||
}
|
||||
|
||||
type AppMemberLoginLogExportModel struct {
|
||||
Id uint64 `json:"id" description:"日志ID"`
|
||||
MemberNo string `json:"memberNo" description:"会员编号"`
|
||||
Username string `json:"username" description:"用户名"`
|
||||
MobileMask string `json:"mobileMask" description:"手机号"`
|
||||
LoginType int `json:"loginType" description:"登录方式"`
|
||||
Status int `json:"status" description:"登录状态"`
|
||||
LoginAt *gtime.Time `json:"loginAt" description:"登录时间"`
|
||||
LoginIpMask string `json:"loginIpMask" description:"登录IP"`
|
||||
LoginRegion string `json:"loginRegion" description:"登录地区"`
|
||||
LoginDomain string `json:"loginDomain" description:"登录域名"`
|
||||
Os string `json:"os" description:"操作系统"`
|
||||
Browser string `json:"browser" description:"浏览器"`
|
||||
ErrMsg string `json:"errMsg" description:"失败原因"`
|
||||
}
|
||||
|
||||
type AppMemberLoginLogPushInp struct {
|
||||
Member *entity.AppMember
|
||||
LoginType int
|
||||
Account string
|
||||
Err error
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package sysin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/library/dict"
|
||||
"hotgo/internal/model/input/form"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type UrlPoolListInp struct {
|
||||
form.PageReq
|
||||
Name string `json:"name" dc:"地址名称"`
|
||||
Domain string `json:"domain" dc:"域名关键词"`
|
||||
Status int `json:"status" dc:"状态"`
|
||||
CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
|
||||
}
|
||||
|
||||
func (in *UrlPoolListInp) Filter(ctx context.Context) error {
|
||||
if in.Status > 0 && !dict.HasOptionKey(consts.UrlPoolStatusOptions, in.Status) {
|
||||
return gerror.New("URL地址状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UrlPoolListModel struct {
|
||||
Id uint64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Scheme string `json:"scheme"`
|
||||
Domain string `json:"domain"`
|
||||
BaseUrl string `json:"baseUrl"`
|
||||
Status int `json:"status"`
|
||||
BindCount uint64 `json:"bindCount"`
|
||||
CurrentBoundCount uint64 `json:"currentBoundCount"`
|
||||
LastBoundAt *gtime.Time `json:"lastBoundAt"`
|
||||
Remark string `json:"remark"`
|
||||
CreatedAt *gtime.Time `json:"createdAt"`
|
||||
UpdatedAt *gtime.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type UrlPoolViewInp struct {
|
||||
Id uint64 `json:"id" v:"required|min:1#地址ID不能为空|地址ID不能为空"`
|
||||
}
|
||||
|
||||
func (in *UrlPoolViewInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type UrlPoolViewModel struct {
|
||||
UrlPoolListModel
|
||||
CreatedBy uint64 `json:"createdBy"`
|
||||
UpdatedBy uint64 `json:"updatedBy"`
|
||||
}
|
||||
|
||||
type UrlPoolEditInp struct {
|
||||
Id uint64 `json:"id"`
|
||||
Name string `json:"name" v:"required|max-length:100#地址名称不能为空|地址名称不能超过100个字符"`
|
||||
BaseUrl string `json:"baseUrl" v:"required|max-length:512#注册入口不能为空|注册入口不能超过512个字符"`
|
||||
Status int `json:"status" v:"required#状态不能为空"`
|
||||
Remark string `json:"remark" v:"max-length:500#备注不能超过500个字符"`
|
||||
}
|
||||
|
||||
func (in *UrlPoolEditInp) Filter(ctx context.Context) error {
|
||||
in.Name = strings.TrimSpace(in.Name)
|
||||
in.BaseUrl = strings.TrimSpace(in.BaseUrl)
|
||||
if !dict.HasOptionKey(consts.UrlPoolStatusOptions, in.Status) {
|
||||
return gerror.New("URL地址状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UrlPoolStatusInp struct {
|
||||
Id uint64 `json:"id" v:"required|min:1#地址ID不能为空|地址ID不能为空"`
|
||||
Status int `json:"status" v:"required#状态不能为空"`
|
||||
}
|
||||
|
||||
func (in *UrlPoolStatusInp) Filter(ctx context.Context) error {
|
||||
if !dict.HasOptionKey(consts.UrlPoolStatusOptions, in.Status) {
|
||||
return gerror.New("URL地址状态不合法")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UrlPoolImportIssue struct {
|
||||
Row int `json:"row" dc:"Excel行号"`
|
||||
Message string `json:"message" dc:"失败原因"`
|
||||
}
|
||||
|
||||
type UrlPoolImportModel struct {
|
||||
TotalRows int `json:"totalRows" dc:"有效数据行数"`
|
||||
SuccessCount int `json:"successCount" dc:"成功导入数量"`
|
||||
DuplicateCount int `json:"duplicateCount" dc:"重复跳过数量"`
|
||||
FailedCount int `json:"failedCount" dc:"校验失败数量"`
|
||||
Issues []*UrlPoolImportIssue `json:"issues" dc:"校验失败明细,最多返回100条"`
|
||||
}
|
||||
|
||||
type UrlPoolMemberListInp struct {
|
||||
form.PageReq
|
||||
UrlPoolId uint64 `json:"urlPoolId" v:"required|min:1#地址ID不能为空|地址ID不能为空"`
|
||||
Keyword string `json:"keyword" dc:"会员编号、用户名或手机号"`
|
||||
BoundAt []*gtime.Time `json:"boundAt" dc:"绑定时间"`
|
||||
}
|
||||
|
||||
func (in *UrlPoolMemberListInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type UrlPoolMemberListModel struct {
|
||||
MemberId uint64 `json:"memberId"`
|
||||
MemberNo string `json:"memberNo"`
|
||||
Username string `json:"username"`
|
||||
Mobile string `json:"mobile"`
|
||||
MemberStatus int `json:"memberStatus"`
|
||||
BoundAt *gtime.Time `json:"boundAt"`
|
||||
}
|
||||
|
||||
type UrlPoolSummaryInp struct{}
|
||||
|
||||
func (in *UrlPoolSummaryInp) Filter(ctx context.Context) error { return nil }
|
||||
|
||||
type UrlPoolSummaryModel struct {
|
||||
TotalCount int `json:"totalCount"`
|
||||
EnabledCount int `json:"enabledCount"`
|
||||
InvalidCount int `json:"invalidCount"`
|
||||
BoundMemberCount int `json:"boundMemberCount"`
|
||||
UnboundMemberCount int `json:"unboundMemberCount"`
|
||||
InvalidMemberCount int `json:"invalidMemberCount"`
|
||||
}
|
||||
Reference in New Issue
Block a user