diff --git a/auto/api/v1/share_key.go b/auto/api/v1/share_key.go new file mode 100644 index 00000000..e7f38795 --- /dev/null +++ b/auto/api/v1/share_key.go @@ -0,0 +1,70 @@ +package v1 + +import ( + "github.com/alimy/mir/v4" + "github.com/gin-gonic/gin" + "github.com/rocboss/paopao-ce/internal/model/web" + "net/http" +) + +type KeyQuery interface { + _default_ + + Chain() gin.HandlersChain + + GetKeyDetail(*web.GetUserKeysReq) (*web.GetUserKeysResp, mir.Error) + mustEmbedUnimplementedShareKeyServant() + DeleteKeyDetail(req *web.DeleteKeyReq) (*web.DeleteKeyResp, mir.Error) +} + +// RegisterKeyQueryServant 使用路由组的方式注册路由 /v1/key +func RegisterKeyQueryServant(e *gin.Engine, s KeyQuery) { + router := e.Group("v1") + // use chain for router + middlewares := s.Chain() + router.Use(middlewares...) + + // 注册路由 + router.Handle("GET", "/user/keys", func(c *gin.Context) { + select { + case <-c.Request.Context().Done(): + return + default: + } + req := new(web.GetUserKeysReq) + var bv _binding_ = req + if err := bv.Bind(c); err != nil { + s.Render(c, nil, err) + return + } + resp, err := s.GetKeyDetail(req) + s.Render(c, resp, err) + }) + + //逻辑删除,将status置为1 + router.Handle("POST", "/user/keys", func(c *gin.Context) { + select { + case <-c.Request.Context().Done(): + return + default: + } + req := new(web.DeleteKeyReq) + var bv _binding_ = req + if err := bv.Bind(c); err != nil { + s.Render(c, nil, err) + return + } + resp, err := s.DeleteKeyDetail(req) + s.Render(c, resp, err) + }) + +} + +type UnimplementedShareKeyServant struct{} + +// GetKeyDetail 用于提供接口的默认行为 +func (UnimplementedShareKeyServant) GetKeyDetail(req *web.GetUserKeysReq) (*web.GetUserKeysResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +} + +func (UnimplementedShareKeyServant) mustEmbedUnimplementedShareKeyServant() {} diff --git a/go.sum b/go.sum index 03aef2ed..b3adcf7f 100644 --- a/go.sum +++ b/go.sum @@ -1158,7 +1158,7 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartwalle/alipay/v3 v3.2.15 h1:3fvFJnINKKAOXHR/Iv20k1Z7KJ+nOh3oK214lELPqG8= -github.com/smartwalle/alipay/v3 v3.2.15/go.mod h1:niTNB609KyUYuAx9Bex/MawEjv2yPx4XOjxSAkqmGjE= +gitub.com/smartwalle/alipay/v3 v3.2.15/go.mod h1:niTNB609KyUYuAx9Bex/MawEjv2yPx4XOjxSAkqmGjE= github.com/smartwalle/ncrypto v1.0.2 h1:pTAhCqtPCMhpOwFXX+EcMdR6PNzruBNoGQrN2S1GbGI= github.com/smartwalle/ncrypto v1.0.2/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk= github.com/smartwalle/ngx v1.0.6 h1:JPNqNOIj+2nxxFtrSkJO+vKJfeNUSEQueck/Wworjps= diff --git a/internal/core/core.go b/internal/core/core.go index 9a8eb26f..6dde2d3e 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -34,4 +34,7 @@ type DataService interface { // 安全服务 SecurityService AttachmentCheckService + + // share_key服务 + ShareKeyService } diff --git a/internal/core/share_key.go b/internal/core/share_key.go new file mode 100644 index 00000000..93273c7c --- /dev/null +++ b/internal/core/share_key.go @@ -0,0 +1,14 @@ +package core + +import "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr" + +type ( + ShareKey = dbr.ShareKey + DeleteKeySuccessOrFail = dbr.DeleteKeySuccessOrFail +) + +// share_key服务 +type ShareKeyService interface { + GetUserKeys(UserName string) ([]*ShareKey, error) + DeleteUserKey(UserName string, key string) (DeleteKeySuccessOrFail, error) +} diff --git a/internal/dao/jinzhu/dbr/share_key.go b/internal/dao/jinzhu/dbr/share_key.go new file mode 100644 index 00000000..6f1bb131 --- /dev/null +++ b/internal/dao/jinzhu/dbr/share_key.go @@ -0,0 +1,39 @@ +package dbr + +import "gorm.io/gorm" + +type ShareKey struct { + UserName string `json:"user_name"` + ShareKey string `json:"share_key"` + Name string `json:"name"` + Description string `json:"description"` + Status int `json:"status"` +} + +func (s *ShareKey) Get(db *gorm.DB) ([]ShareKey, error) { + var sks []ShareKey + + if s.UserName != "" { + db = db.Where("user_name = ? AND status = 0", s.UserName) + } + //if s.ShareKey != "" { + // db = db.Where("share_key = ?", s.ShareKey) + //} + + err := db.Table("p_share_key").Find(&sks).Error + if err != nil { + return sks, err + } + + return sks, nil +} + +type DeleteKeySuccessOrFail struct { + SuccessOrFail bool +} + +func (sf *ShareKey) POST(db *gorm.DB) (DeleteKeySuccessOrFail, error) { + var sof DeleteKeySuccessOrFail + + return sof, nil +} diff --git a/internal/dao/jinzhu/jinzhu.go b/internal/dao/jinzhu/jinzhu.go index 3ccebdb9..11415d90 100644 --- a/internal/dao/jinzhu/jinzhu.go +++ b/internal/dao/jinzhu/jinzhu.go @@ -37,6 +37,7 @@ type dataServant struct { core.ContactManageService core.SecurityService core.AttachmentCheckService + core.ShareKeyService } func NewDataService() (core.DataService, core.VersionInfo) { @@ -97,6 +98,7 @@ func NewDataService() (core.DataService, core.VersionInfo) { ContactManageService: newContactManageService(db), SecurityService: newSecurityService(db, pvs), AttachmentCheckService: security.NewAttachmentCheckService(), + ShareKeyService: NewShareKeyService(db), } return ds, ds } diff --git a/internal/dao/jinzhu/share_key.go b/internal/dao/jinzhu/share_key.go new file mode 100644 index 00000000..e9d25a9d --- /dev/null +++ b/internal/dao/jinzhu/share_key.go @@ -0,0 +1,38 @@ +package jinzhu + +import ( + "github.com/rocboss/paopao-ce/internal/core" + "gorm.io/gorm" +) + +type ShareKeyService struct { + db *gorm.DB +} + +func (s ShareKeyService) DeleteUserKey(UserName string, key string) (core.DeleteKeySuccessOrFail, error) { + var deleteKey core.DeleteKeySuccessOrFail + deleteKey.SuccessOrFail = false + //根据username和key删除相应的key + err := s.db.Table("p_share_key").Where("user_name = ? AND share_key = ?", UserName, key).Update("status", 1).Error + if err != nil { + return deleteKey, err + } + deleteKey.SuccessOrFail = true + return deleteKey, nil +} + +func (s ShareKeyService) GetUserKeys(UserName string) ([]*core.ShareKey, error) { + //根据username查询相应的keys + var keys []*core.ShareKey + err := s.db.Table("p_share_key").Where("user_name = ? and status = 0", UserName).Find(&keys).Error + if err != nil { + return nil, err + } + return keys, nil +} + +func NewShareKeyService(db *gorm.DB) *ShareKeyService { + return &ShareKeyService{ + db: db, + } +} diff --git a/internal/dao/jinzhu/wallet.go b/internal/dao/jinzhu/wallet.go index 86ce0836..102548d6 100644 --- a/internal/dao/jinzhu/wallet.go +++ b/internal/dao/jinzhu/wallet.go @@ -35,6 +35,8 @@ func (d *walletServant) GetRechargeByID(id int64) (*core.WalletRecharge, error) return recharge.Get(d.db) } + +// 点击前往支付会创建支付数据 func (d *walletServant) CreateRecharge(userId, amount int64) (*core.WalletRecharge, error) { recharge := &dbr.WalletRecharge{ UserID: userId, diff --git a/internal/model/web/share_key.go b/internal/model/web/share_key.go new file mode 100644 index 00000000..2f132d48 --- /dev/null +++ b/internal/model/web/share_key.go @@ -0,0 +1,57 @@ +package web + +import ( + "github.com/alimy/mir/v4" + "github.com/gin-gonic/gin" + "github.com/rocboss/paopao-ce/internal/servants/base" + "github.com/rocboss/paopao-ce/pkg/convert" + "github.com/rocboss/paopao-ce/pkg/xerror" +) + +// GetUserKeysReq 获取一个用户的所有key +type GetUserKeysReq struct { + UserId int64 + UserName string +} + +func (g *GetUserKeysReq) Bind(c *gin.Context) mir.Error { + uid, ok := base.UserFrom(c) + if !ok { + return xerror.UnauthorizedTokenError + } + g.UserId = uid.ID + g.UserName = uid.Username + return nil +} + +type KeyInfo struct { + ShareKey string `json:"share_key"` + Name string `json:"name"` + Description string `json:"description"` +} + +type GetUserKeysResp struct { + ShareKeys []KeyInfo `json:"shareKeys"` +} + +// 逻辑删除服务 +type DeleteKeyReq struct { + ShareKey string `json:"share_key"` + UserId int64 + UserName string +} + +func (d *DeleteKeyReq) Bind(c *gin.Context) mir.Error { + uid, ok := base.UserFrom(c) + if !ok { + return xerror.UnauthorizedTokenError + } + d.UserId = uid.ID + d.UserName = uid.Username + d.ShareKey = convert.StrTo(c.Query("share_key")).String() + return nil +} + +type DeleteKeyResp struct { + Status string +} diff --git a/internal/model/web/xerror.go b/internal/model/web/xerror.go index 6328a099..4bbb84d3 100644 --- a/internal/model/web/xerror.go +++ b/internal/model/web/xerror.go @@ -90,4 +90,8 @@ var ( ErrFileUploadFailed = xerror.NewError(10200, "文件上传失败") ErrFileInvalidExt = xerror.NewError(10201, "文件类型不合法") ErrFileInvalidSize = xerror.NewError(10202, "文件大小超限") + ErrGetUserKeysFailed = xerror.NewError(11001, "获取用户Share Key失败") + ErrDsNil = xerror.NewError(11002, "数据源为空") + ErrUserNameEmpty = xerror.NewError(11003, "用户名为空") + ErrDeleteUserKeyFailed = xerror.NewError(11004, "删除用户Share Key失败") ) diff --git a/internal/servants/web/alipay.go b/internal/servants/web/alipay.go index 4685c7f3..2a007475 100644 --- a/internal/servants/web/alipay.go +++ b/internal/servants/web/alipay.go @@ -75,7 +75,7 @@ func (s *alipayPrivSrv) UserWalletBills(req *web.UserWalletBillsReq) (*web.UserW } func (s *alipayPrivSrv) UserRechargeLink(req *web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error) { - recharge, err := s.Ds.CreateRecharge(req.User.ID, req.Amount) //天数换算成时间戳 + recharge, err := s.Ds.CreateRecharge(req.User.ID, req.Amount) //天数换算成时间戳,将数据存入p_wallet_recharge表 if err != nil { logrus.Errorf("Ds.CreateRecharge err: %v", err) return nil, web.ErrRechargeReqFail @@ -95,7 +95,9 @@ func (s *alipayPrivSrv) UserRechargeLink(req *web.UserRechargeLinkReq) (*web.Use p.OutTradeNo = fmt.Sprintf("%d", recharge.ID) p.Subject = "PaoPao用户钱包充值" p.TotalAmount = fmt.Sprintf("%.2f", float64(recharge.Amount)/100.0*a) - p.NotifyURL = "https://" + req.Host + "/v1/alipay/notify" + //p.NotifyURL = "http://" + req.Host + "/v1/alipay/notify" + //支付宝回调,如果是内网环境的话,需要增加内网穿透 + p.NotifyURL = "http://5tc4bf.natappfree.cc/v1/alipay/notify" rsp, err := s.alipayClient.TradePreCreate(p) if err != nil { logrus.Errorf("client.TradePreCreate err: %v\n", err) diff --git a/internal/servants/web/share_key.go b/internal/servants/web/share_key.go new file mode 100644 index 00000000..35ffe365 --- /dev/null +++ b/internal/servants/web/share_key.go @@ -0,0 +1,99 @@ +package web + +import ( + "fmt" + "github.com/alimy/mir/v4" + "github.com/gin-gonic/gin" + api "github.com/rocboss/paopao-ce/auto/api/v1" + "github.com/rocboss/paopao-ce/internal/model/web" + "github.com/rocboss/paopao-ce/internal/servants/base" + "github.com/rocboss/paopao-ce/internal/servants/chain" + "github.com/sirupsen/logrus" +) + +var ( + _ api.KeyQuery = (*shareKey)(nil) +) + +type shareKey struct { + api.UnimplementedShareKeyServant + *base.DaoServant +} + +func (s *shareKey) Chain() gin.HandlersChain { + return gin.HandlersChain{chain.JWT()} +} + +func (s *shareKey) GetKeyDetail(req *web.GetUserKeysReq) (*web.GetUserKeysResp, mir.Error) { + //判断GetUserKeys是否为nil + if s.Ds == nil { + logrus.Errorf("GetKeyDetail err: %s", web.ErrDsNil) + return nil, web.ErrDsNil + } else { + logrus.Info("GetKeyDetail success") + } + if req.UserName == "" { + logrus.Errorf("GetKeyDetail err: %s", web.ErrUserNameEmpty) + return nil, web.ErrUserNameEmpty + } + // 调用数据源的方法查询用户的所有key信息 + keys, err := s.Ds.GetUserKeys(req.UserName) + if err != nil { + logrus.Errorf("GetUserKeys err: %s", err) + return nil, web.ErrGetUserKeysFailed + } + + // 将查询到的key信息转换为KeyInfo结构体 + var keyInfos []web.KeyInfo + for _, key := range keys { + keyInfos = append(keyInfos, web.KeyInfo{ + ShareKey: key.ShareKey, + Name: key.Name, + Description: key.Description, + }) + } + + // 构建返回结果并返回 + resp := &web.GetUserKeysResp{ + ShareKeys: keyInfos, + } + return resp, nil +} + +func (s *shareKey) DeleteKeyDetail(req *web.DeleteKeyReq) (*web.DeleteKeyResp, mir.Error) { + //判断GetUserKeys是否为nil + if s.Ds == nil { + logrus.Errorf("GetKeyDetail err: %s", web.ErrDsNil) + return nil, web.ErrDsNil + } else { + logrus.Info("GetKeyDetail success") + } + if req.UserName == "" { + logrus.Errorf("GetKeyDetail err: %s", web.ErrUserNameEmpty) + return nil, web.ErrUserNameEmpty + } + + fmt.Print(req.UserName, req.ShareKey) + sof, err := s.Ds.DeleteUserKey(req.UserName, req.ShareKey) + if err != nil { + logrus.Errorf("DeleteUserKey err: %s", err) + return nil, web.ErrDeleteUserKeyFailed + } + if sof.SuccessOrFail == false { + logrus.Errorf("DeleteUserKey err: %s", err) + return nil, web.ErrDeleteUserKeyFailed + } + + // 构建返回结果并返回 + resp := &web.DeleteKeyResp{ + Status: "DELETE_SUCCESS", + } + return resp, nil +} + +// NewShareKeyServant 创建share_key服务 +func NewShareKeyServant(s *base.DaoServant) api.KeyQuery { + return &shareKey{ + DaoServant: s, + } +} diff --git a/internal/servants/web/web.go b/internal/servants/web/web.go index e4684a1e..f034a26e 100644 --- a/internal/servants/web/web.go +++ b/internal/servants/web/web.go @@ -32,6 +32,7 @@ func RouteWeb(e *gin.Engine) { api.RegisterLooseServant(e, newLooseSrv(ds)) api.RegisterPrivServant(e, newPrivSrv(ds, oss)) api.RegisterPubServant(e, newPubSrv(ds)) + api.RegisterKeyQueryServant(e, NewShareKeyServant(ds)) // regster servants if needed by configure cfg.In(cfg.Actions{ "Alipay": func() { diff --git a/web/src/api/shareKey.ts b/web/src/api/shareKey.ts new file mode 100644 index 00000000..c0b41278 --- /dev/null +++ b/web/src/api/shareKey.ts @@ -0,0 +1,32 @@ +import { request } from "@/utils/request"; + +//获取用户的sharekey +// export const getShareKeys = ( +// params: NetParams.UserGetShareKeys +// ): Promise => { +// return request({ +// method: "get", +// url: "/v1/user/keys", +// params, +// }); +// } +export const getShareKeys = (token: NetParams.AuthUserInfo = ""): Promise => { + return request({ + method: "get", + url: "/v1/user/keys", + headers: { + Authorization: `Bearer ${token}`, + }, + }); +} + +export const deleteThisShareKey = (params: NetParams.UserDeleteShareKey,token: NetParams.AuthUserInfo = ""): Promise => { + return request({ + method: "post", + url: "/v1/user/keys", + headers: { + Authorization: `Bearer ${token}`, + }, + params, + }); +} \ No newline at end of file diff --git a/web/src/components/sidebar.vue b/web/src/components/sidebar.vue index e4ba4303..1a4f233a 100644 --- a/web/src/components/sidebar.vue +++ b/web/src/components/sidebar.vue @@ -181,6 +181,13 @@ const menuOptions = computed(() => { href: '/setting', }); + options.push({ + label: '密钥', + key: 'sharekey', + icon: () => h(SettingsOutline), + href: '/sharekey', + }); + return store.state.userInfo.id > 0 ? options : [ diff --git a/web/src/router/index.ts b/web/src/router/index.ts index 03ed97ee..88f1eced 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -90,6 +90,14 @@ const routes = [ }, component: () => import('@/views/Setting.vue'), }, + { + path: '/sharekey', + name: 'sharekey', + meta: { + title: '密钥', + }, + component: () => import('@/views/ShareKey.vue'), + }, { path: '/404', name: '404', diff --git a/web/src/types/Item.d.ts b/web/src/types/Item.d.ts index ff8530ad..df3b13ef 100644 --- a/web/src/types/Item.d.ts +++ b/web/src/types/Item.d.ts @@ -325,4 +325,13 @@ declare module Item { change_amount: number; created_on: number; } + + //sharekey参数 + interface ShareKeyProps { + share_key: string; + //名称 + name: string; + //描述 + description: string; + } } diff --git a/web/src/types/NetParams.d.ts b/web/src/types/NetParams.d.ts index 3a7f3da8..612925df 100644 --- a/web/src/types/NetParams.d.ts +++ b/web/src/types/NetParams.d.ts @@ -58,6 +58,19 @@ declare module NetParams { page_size: number; } + //获取用户分享码请求参数 + interface UserGetShareKeys { + userId : number; + userName : string; + // page: number; + // page_size: number; + } + + //删除用户分享码请求参数 + interface UserDeleteShareKey { + share_key : string; + } + interface UserStatusReq { id: number; status: number; diff --git a/web/src/types/NetReq.d.ts b/web/src/types/NetReq.d.ts index f4e14e20..c069cc54 100644 --- a/web/src/types/NetReq.d.ts +++ b/web/src/types/NetReq.d.ts @@ -63,6 +63,18 @@ declare module NetReq { pager: Item.PagerProps; } + //用户获取分享码响应参数 + interface UserGetShareKeys { + shareKeys: Item.ShareKeyProps[]; + /** 页码信息 */ + pager: Item.PagerProps; + } + + //用户删除分享码响应参数 + interface UserDeleteShareKey { + Status: string; + } + interface UserReqRecharge { id: number; pay: string; diff --git a/web/src/views/ShareKey.vue b/web/src/views/ShareKey.vue new file mode 100644 index 00000000..5c0b6d0f --- /dev/null +++ b/web/src/views/ShareKey.vue @@ -0,0 +1,202 @@ + + + + + \ No newline at end of file