123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942 |
- package user
- import (
- "crypto/sha256"
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
- "net/http"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/gin-gonic/gin"
- "github.com/guregu/null"
- "github.com/metarare/metarare_api/auth"
- "github.com/metarare/metarare_api/common"
- "github.com/metarare/metarare_api/helpers"
- "github.com/metarare/metarare_api/helpers/gauth"
- "github.com/metarare/metarare_api/helpers/gerror"
- "github.com/metarare/metarare_api/models"
- "github.com/metarare/metarare_api/util"
- "github.com/metarare/metarare_api/view"
- "github.com/spf13/viper"
- "gorm.io/gorm"
- )
- type UserV1Router struct {
- group *gin.RouterGroup
- mDB *gorm.DB
- rDB *gorm.DB
- awsConf util.AWSConfs
- Env *viper.Viper
- }
- type AuthenticationSNS struct {
- Code string `json:"code" binding:"required"`
- Type string `json:"type" binding:"required"`
- }
- type ProfileInfo struct {
- Name string `json:"name" binding:"required"`
- Description string `json:"description" binding:"required"`
- Phone string `json:"phone"`
- Twitter string `json:"twitter"`
- }
- type Transfer struct {
- Currency string `json:"currency" binding:"required"`
- ToAddress string `json:"to_address" binding:"required"`
- Amount float64 `json:"amount" binding:"required"`
- Code string `json:"code" binding:"required"`
- }
- type CertificationBody struct {
- Currency string `json:"currency" binding:"required"`
- Amount float64 `json:"amount" binding:"required"`
- }
- func NewUserV1Router(r common.Router, basePath string) UserV1Router {
- u := UserV1Router{
- group: r.Version.Group(basePath),
- mDB: r.Db.MasterDB,
- rDB: r.Db.ReadDB,
- awsConf: util.AWSConfs{
- Region: r.Env.GetString("storage.region"),
- BucketName: r.Env.GetString("storage.bucket_name"),
- Access_key_id: r.Env.GetString("storage.access_key_id"),
- Access_key: r.Env.GetString("storage.access_key"),
- },
- Env: r.Env,
- }
- u.group.GET("redirect/url", u.getRedirectURL)
- u.group.POST("authenticate", u.userAuthentication)
- u.group.GET("authenticate/temp", u.tempAuthentication)
- u.group.GET("profile/:name", u.getUserProfile)
- u.group.PATCH("profile", u.updateUserProfile)
- u.group.POST("onsale/:name", u.getOnSaleItems)
- u.group.POST("collection/:name", u.getRelatedCollections)
- u.group.POST("like/:name", u.getLikeItems)
- u.group.POST("owned/:name", u.getOwnedItems)
- u.group.GET("activity/:name", u.getUserActivities)
- u.group.POST("bid", u.getuserBidHistory)
- u.group.GET("profile", u.getUserSimpleProfile)
- u.group.GET("duplicate/:name", u.duplicateName)
- u.group.POST("transfer", u.tokenTransfer)
- u.group.POST("certification/code", u.certificationCode)
- return u
- }
- // getRedirectURL godoc
- // @Summary sns redirect url
- // @Description SNS 로그인 버튼 클릭시 redirect_url을 받는 API, {type=google, kakao}
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param type query string true "type"
- // @Success 200 {string} redirectURL
- // @Router /user/redirect/url [get]
- func (u UserV1Router) getRedirectURL(c *gin.Context) {
- var redirectURL string
- signinType := c.Query("type")
- if signinType != "google" && signinType != "kakao" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- if signinType == "google" {
- redirectURL = auth.GetGoogleSignInURL()
- } else {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, nil)
- return
- }
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, redirectURL, nil)
- return
- }
- // tempAuthentication godoc
- // @Summary temp user authentication
- // @Description SNS로그인 테스트 이전에 동일한 로직으로 유저 회원가입, 세션 획득을 위한 임시 함수, 입력된 이메일이 없으면 회원가입 이후 로그인, 있으면 로그인
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param email query string true "email"
- // @Success 200 {string} authContainer
- // @Router /user/authenticate/temp [get]
- func (u UserV1Router) tempAuthentication(c *gin.Context) {
- request := c.Query("email")
- if request == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _auth := models.UserAuthentication{}
- if err := u.rDB.Where("email = ?", request).Find(&_auth).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- } else if _auth.ID != 0 {
- //NOTE x 상태값 확인 후 로그인 세션 생성
- _user := models.User{}
- err := u.rDB.Where("id = ?", _auth.UserID).Find(&_user).Error
- if errors.Is(err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- } else if _user.Status != "stable" {
- gerror.IntegratedResponseToRequest(c, http.StatusUnauthorized, gerror.Unauthorized, nil, errors.New(""))
- return
- }
- token := common.MakeJwtToken(_auth.UserID)
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, token, nil)
- return
- }
- //NOTE x 회원가입 이후 로그인 세션 생성
- tx := u.mDB.Begin()
- defer common.DBTransaction(tx)
- user := models.User{
- UID: common.GenerateUserUID(tx, "user_"),
- Status: "stable",
- }
- if err := tx.Save(&user).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- authentication := models.UserAuthentication{
- UserID: user.ID,
- Email: request,
- Type: null.StringFrom("google"),
- }
- if err := tx.Save(&authentication).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- profile := models.UserProfile{
- UserID: user.ID,
- Name: null.StringFrom(common.GenerateUserName(tx)),
- }
- if err := tx.Save(&profile).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- pk, addr := helpers.GenerateWallet()
- str := addr + pk + "1"
- checkSum := sha256.Sum256([]byte(str))
- wallet := models.UserWallet{
- UserID: user.ID,
- Address: addr,
- PrivateKey: pk,
- CheckSum: fmt.Sprintf("%x", checkSum),
- EncVersion: 1,
- }
- if err := tx.Save(&wallet).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- if err := tx.Commit().Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- token := common.MakeJwtToken(user.ID)
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, token, nil)
- return
- }
- // userAuthentication godoc
- // @Summary sign-in
- // @Description redirect url 호출이후 받은 코드로 기존유저라면 로그인, 새로운 유저라면 가입 후 로그인
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param AuthenticationSNS body AuthenticationSNS true "oauth data"
- // @Success 200 {string} authContainer
- // @Router /user/authenticate [post]
- func (u UserV1Router) userAuthentication(c *gin.Context) {
- var email string
- var _err error
- var req AuthenticationSNS
- if err := c.ShouldBindJSON(&req); err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, err)
- return
- }
- switch req.Type {
- case "google":
- g, err := auth.GetGoogleUserInfo(req.Code)
- if err != nil {
- _err = err
- break
- }
- email = g.Email
- default:
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("required type parameter"))
- return
- }
- if _err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.GetSNSUserInfoError, nil, _err)
- return
- }
- _auth := models.UserAuthentication{}
- if err := u.rDB.Where("email = ?", email).Find(&_auth).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, _err)
- return
- } else if _auth.ID != 0 {
- //NOTE x 상태 확인 후 로그인 세션 생성
- _user := models.User{}
- err := u.rDB.Where("id = ?", _auth.UserID).Find(&_user).Error
- if errors.Is(err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- } else if _user.Status != "stable" {
- gerror.IntegratedResponseToRequest(c, http.StatusUnauthorized, gerror.Unauthorized, nil, errors.New(""))
- return
- }
- token := common.MakeJwtToken(_auth.UserID)
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, token, nil)
- return
- }
- //NOTE x 회원가입 이후 로그인 세션 생성
- tx := u.mDB.Begin()
- defer common.DBTransaction(tx)
- user := models.User{
- UID: common.GenerateUserUID(tx, "user_"),
- Status: "stable",
- }
- if err := tx.Save(&user).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- authentication := models.UserAuthentication{
- UserID: user.ID,
- Email: email,
- Type: null.StringFrom(req.Type),
- }
- if err := tx.Save(&authentication).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- profile := models.UserProfile{
- UserID: user.ID,
- Name: null.StringFrom(common.GenerateUserName(tx)),
- }
- if err := tx.Save(&profile).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- pk, addr := helpers.GenerateWallet()
- str := addr + pk + "1"
- checkSum := sha256.Sum256([]byte(str))
- wallet := models.UserWallet{
- UserID: user.ID,
- Address: addr,
- PrivateKey: pk,
- CheckSum: fmt.Sprintf("%x", checkSum),
- EncVersion: 1,
- }
- if err := tx.Save(&wallet).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- if err := tx.Commit().Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- token := common.MakeJwtToken(user.ID)
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, token, nil)
- return
- }
- /////////////////////////////////
- func (u UserV1Router) extractFilterData(c *gin.Context) (error, common.Filter) {
- var _filter common.Filter
- if err := c.ShouldBindJSON(&_filter); err != nil {
- return err, common.Filter{}
- } else {
- return nil, _filter
- }
- }
- // getUserProfile godoc
- // @Summary user basic profile data
- // @Description 유저 기본 정보 가져오기
- // @Schemes
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param name path string true "user profile name"
- // @Success 200 {string} authContainer
- // @Router /user/profile/{name} [get]
- func (u UserV1Router) getUserProfile(c *gin.Context) {
- userID, err := gauth.GetCurrentUserIDToInt64(c)
- name := c.Param("name")
- if name == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _id, err := common.ConvertToId(u.rDB, name)
- if _id == 0 || err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.NotFoundRecord, nil, err)
- return
- }
- err, userProfile := view.SelectUserInfo(u.rDB, _id, userID)
- if errors.Is(err, gorm.ErrRecordNotFound) {
- c.AbortWithStatusJSON(http.StatusOK, gin.H{
- "message": "There is no matched user profile",
- })
- return
- }
- c.JSON(http.StatusOK, userProfile)
- }
- // updateUserProfile godoc
- // @Summary update user profile
- // @Description 유저 정보 업데이트
- // @Schemes
- // @security ApiKeyAuth
- // @Tags user
- // @Accept multipart/form-data
- // @Produce json
- // @Param thumbnailImage formData file true "thumbnail image"
- // @Param coverImage formData file true "cover image"
- // @Param json formData common.SwagStruct true "object"
- // @Success 200 {string} authContainer
- // @Router /user/profile [patch]
- func (u UserV1Router) updateUserProfile(c *gin.Context) {
- userID, err := gauth.GetCurrentUserIDToInt64(c)
- if err != nil || userID == 0 {
- gerror.IntegratedResponseToRequest(c, http.StatusUnauthorized, gerror.Unauthorized, nil, err)
- return
- }
- form, err := c.MultipartForm()
- if err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MultipartError, nil, err)
- return
- }
- _request := form.Value["json"]
- if _request == nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- request := ProfileInfo{}
- if err := json.Unmarshal([]byte(_request[0]), &request); err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, nil)
- return
- }
- thumbnailImage := form.File["thumbnailImage"]
- coverImage := form.File["coverImage"]
- profile := models.UserProfile{}
- _err := u.rDB.Where("user_id = ?", userID).Find(&profile).Error
- if errors.Is(_err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.NotFoundRecord, nil, _err)
- return
- }
- tx := u.mDB.Begin()
- defer common.DBTransaction(tx)
- var thumbnailImageURL string
- if thumbnailImage != nil {
- thumbnailImagePath := fmt.Sprintf("profile/thumbnail/%d", userID)
- for _, f := range thumbnailImage {
- thumbnailImageURL, err = util.UploadToS3(u.awsConf, thumbnailImagePath, f)
- if err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.Error3rdParty, nil, err)
- tx.Rollback()
- return
- }
- }
- profile.ThumbnailImage = null.StringFrom(thumbnailImageURL)
- }
- var coverImageURL string
- if coverImage != nil {
- coverImagePath := fmt.Sprintf("profile/cover/%d", userID)
- for _, f := range coverImage {
- coverImageURL, err = util.UploadToS3(u.awsConf, coverImagePath, f)
- if err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.Error3rdParty, nil, err)
- tx.Rollback()
- return
- }
- }
- profile.CoverImage = null.StringFrom(coverImageURL)
- }
- profile.Name = null.StringFrom(request.Name)
- profile.Description = null.StringFrom(request.Description)
- if request.Twitter != "" {
- profile.Twitter = null.StringFrom(request.Twitter)
- }
- if request.Phone != "" {
- profile.Phone = null.StringFrom(request.Phone)
- }
- if err := tx.Save(&profile).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- return
- }
- if err := tx.Commit().Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, nil, err)
- }
- // getOnSaleItems godoc
- // @Summary onesale list
- // @Description 판매중인 NFT 리스트
- // @Schemes
- // @security ApiKeyAuth
- // @Tags user
- // @Accept json
- // @Produce json
- // @Param common.Filter body common.Filter true "filter object"
- // @Param name path string true "user profile name"
- // @Success 200 {object} []common.ExpItem
- // @Router /user/onsale/{name} [post]
- func (u UserV1Router) getOnSaleItems(c *gin.Context) {
- name := c.Param("name")
- if name == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _id, err := common.ConvertToId(u.rDB, name)
- if _id == 0 || err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.NotFoundRecord, nil, err)
- return
- }
- err, filter := u.extractFilterData(c)
- if err != nil {
- c.AbortWithStatusJSON(http.StatusBadRequest, filter)
- return
- }
- err, _sales := view.SelectOnsaleItems(u.rDB, _id, filter)
- if errors.Is(err, gorm.ErrRecordNotFound) {
- c.AbortWithStatusJSON(http.StatusOK, gin.H{
- "message": "there is no onSale item",
- })
- return
- }
- c.JSON(http.StatusOK, _sales)
- }
- // getOwnedItems godoc
- // @Summary owned list
- // @Description 보유중인 NFT 리스트
- // @Schemes
- // @security ApiKeyAuth
- // @Tags user
- // @Accept json
- // @Produce json
- // @Param common.Filter body common.Filter true "filter object"
- // @Success 200 {object} []common.ExpItem
- // @Router /user/owned [post]
- func (u UserV1Router) getOwnedItems(c *gin.Context) {
- name := c.Param("name")
- if name == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _id, err := common.ConvertToId(u.rDB, name)
- if _id == 0 || err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.NotFoundRecord, nil, err)
- return
- }
- err, filter := u.extractFilterData(c)
- if err != nil {
- c.AbortWithStatusJSON(http.StatusBadRequest, filter)
- return
- }
- err, _tokenInfos := view.SelectOwnedTokens(u.rDB, _id, filter)
- if errors.Is(err, gorm.ErrRecordNotFound) {
- c.AbortWithStatusJSON(http.StatusOK, gin.H{
- "message": "NO matched tokenDatas",
- })
- return
- }
- c.JSON(http.StatusOK, _tokenInfos)
- }
- // getRelatedCollections godoc
- // @Summary collection list
- // @Description 유저 프로필 컬렉션 탭
- // @Schemes
- // @security ApiKeyAuth
- // @Tags user
- // @Accept json
- // @Produce json
- // @Param common.Filter body common.Filter true "filter object"
- // @Param name path string true "user profile name"
- // @Success 200 {object} []common.CollectionItem
- // @Router /user/collection/{name} [post]
- func (u UserV1Router) getRelatedCollections(c *gin.Context) {
- name := c.Param("name")
- if name == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _id, err := common.ConvertToId(u.rDB, name)
- if _id == 0 || err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.NotFoundRecord, nil, err)
- return
- }
- err, filter := u.extractFilterData(c)
- if err != nil {
- c.AbortWithStatusJSON(http.StatusBadRequest, filter)
- return
- }
- err, _collections := view.SelectRelatedCollection(u.rDB, _id, filter)
- if errors.Is(err, gorm.ErrRecordNotFound) {
- c.AbortWithStatusJSON(http.StatusOK, gin.H{
- "message": "No Matched collections",
- })
- return
- }
- c.JSON(http.StatusOK, _collections)
- }
- // getLikeItems godoc
- // @Summary user like list
- // @Description 유저 프로필 좋아요 탭
- // @Schemes
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param common.Filter body common.Filter true "filter object"
- // @Param name path string true "user profile name"
- // @Success 200 {object} []common.ExpItem
- // @Router /user/like/{name} [post]
- func (u UserV1Router) getLikeItems(c *gin.Context) {
- name := c.Param("name")
- if name == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _id, err := common.ConvertToId(u.rDB, name)
- if _id == 0 || err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.NotFoundRecord, nil, err)
- return
- }
- err, filter := u.extractFilterData(c)
- if err != nil {
- c.AbortWithStatusJSON(http.StatusBadRequest, filter)
- return
- }
- err, likeItems := view.SelectLikedTokens(u.rDB, _id, filter)
- if errors.Is(err, gorm.ErrRecordNotFound) {
- c.AbortWithStatusJSON(http.StatusOK, gin.H{
- "message": "There is no liked items",
- })
- return
- }
- c.JSON(http.StatusOK, likeItems)
- }
- // getUserActivities godoc
- // @Summary user activity list
- // @Description 유저 프로필 활동 탭
- // @Schemes
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param name path string true "user profile name"
- // @Success 200 {object} []common.ActivityItem
- // @Router /user/activity/{name} [get]
- func (u UserV1Router) getUserActivities(c *gin.Context) {
- name := c.Param("name")
- if name == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _id, err := common.ConvertToId(u.rDB, name)
- if _id == 0 || err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.NotFoundRecord, nil, err)
- return
- }
- err, likeItems := view.SelectUserActivities(u.rDB, _id)
- if errors.Is(err, gorm.ErrRecordNotFound) {
- c.AbortWithStatusJSON(http.StatusOK, gin.H{
- "message": "There is no liked items",
- })
- return
- }
- c.JSON(http.StatusOK, likeItems)
- }
- // getuserBidHistory godoc
- // @Summary user bid list
- // @Description 유저 경매 히스토리
- // @Schemes
- // @security ApiKeyAuth
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Success 200 {object} []common.ExpItem
- // @Router /user/bid [post]
- func (u UserV1Router) getuserBidHistory(c *gin.Context) {
- userID, err := gauth.GetCurrentUserIDToInt64(c)
- if err != nil || userID == 0 {
- gerror.IntegratedResponseToRequest(c, http.StatusUnauthorized, gerror.Unauthorized, nil, err)
- return
- }
- if err != nil {
- c.AbortWithStatus(http.StatusUnauthorized)
- return
- }
- err, filter := u.extractFilterData(c)
- if err != nil {
- c.AbortWithStatusJSON(http.StatusBadRequest, filter)
- return
- }
- err, likeItems := view.SelectUserBidHistory(u.rDB, userID, filter)
- if errors.Is(err, gorm.ErrRecordNotFound) {
- c.AbortWithStatusJSON(http.StatusOK, gin.H{
- "message": "There is no liked items",
- })
- return
- }
- c.JSON(http.StatusOK, likeItems)
- }
- // getUserSimpleProfile godoc
- // @Summary user simple profile data
- // @Description 헤더, 프로필 편집에 사용할 데이터
- // @Schemes
- // @Tags user
- // @security ApiKeyAuth
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Success 200 {object} view.SimpleProfile
- // @Router /user/profile [get]
- func (u UserV1Router) getUserSimpleProfile(c *gin.Context) {
- userID, err := gauth.GetCurrentUserIDToInt64(c)
- if err != nil || userID == 0 {
- gerror.IntegratedResponseToRequest(c, http.StatusUnauthorized, gerror.Unauthorized, nil, err)
- return
- }
- response := view.SimpleProfile{}
- _err := view.GetSimpleProfile(u.rDB, userID).Find(&response.SimpleProfile).Error
- if errors.Is(_err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, _err)
- return
- }
- _err = u.rDB.Select("setting.commission AS service_commission, setting.gas_deposit AS network_commission").Table("setting").Find(&response.Setting).Error
- if errors.Is(_err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, _err)
- return
- }
- response.SimpleProfile.EthBalance, response.SimpleProfile.AvailableEthBalance = helpers.GetSelectedBalance(u.rDB, userID, "eth", response.SimpleProfile.Address)
- response.SimpleProfile.MfBalance, response.SimpleProfile.AvailableMfBalance = helpers.GetSelectedBalance(u.rDB, userID, "mf", response.SimpleProfile.Address)
- response.SimpleProfile.MrBalance, response.SimpleProfile.AvailableMrBalance = helpers.GetSelectedBalance(u.rDB, userID, "mr", response.SimpleProfile.Address)
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, response, nil)
- }
- // duplicateName godoc
- // @Summary User profile name duplicate check.
- // @Description 유저 이름 중복체크
- // @Schemes
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param name path string true "check duplicate name"
- // @Success 200 {string} OK!
- // @Router /user/duplicate/{name} [get]
- func (u UserV1Router) duplicateName(c *gin.Context) {
- name := c.Param("name")
- if name == "" {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("invalid parameter value"))
- return
- }
- _bool, err := common.DuplicateValue(u.rDB, "user", name)
- if err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, err)
- return
- } else if _bool {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.DuplicateValue, nil, errors.New("duplicate value"))
- return
- }
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, nil, nil)
- }
- // tokenTransfer godoc
- // @Summary token transfer
- // @Description 출금하기
- // @Schemes
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param Transfer body Transfer true "currency: mf1, mr, eth"
- // @Success 200 {string} OK!
- // @Router /user/transfer [post]
- func (u UserV1Router) tokenTransfer(c *gin.Context) {
- userID, _err := gauth.GetCurrentUserIDToInt64(c)
- if _err != nil || userID == 0 {
- gerror.IntegratedResponseToRequest(c, http.StatusUnauthorized, gerror.Unauthorized, nil, _err)
- return
- }
- request := Transfer{}
- if err := c.ShouldBindJSON(&request); err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, err)
- return
- }
- wallet := models.UserWallet{}
- err := u.rDB.Where("user_id = ?", userID).Find(&wallet).Error
- if errors.Is(err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- }
- setting := models.Setting{}
- err = u.rDB.Find(&setting).Error
- if errors.Is(err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- }
- if request.Code != wallet.CertificationCode.String || request.Amount != wallet.RequestBalance.Float64 || request.Currency != wallet.RequestCurrency {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- }
- //NOTE x 가용가능한 값만 출금할 수 있다.
- if request.Currency == "eth" {
- _, availableBalance := helpers.GetSelectedBalance(u.rDB, userID, request.Currency, wallet.Address)
- if (request.Amount + setting.GasDeposit) > availableBalance {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("lack of holding balance"))
- return
- }
- } else {
- _, availableBalance := helpers.GetSelectedBalance(u.rDB, userID, request.Currency, wallet.Address)
- if request.Amount > availableBalance {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("lack of holding balance"))
- return
- }
- _, availableEthBalance := helpers.GetSelectedBalance(u.rDB, userID, "eth", wallet.Address)
- if setting.GasDeposit > availableEthBalance {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, errors.New("lack of holding balance"))
- return
- }
- }
- // ToWallet := models.UserWallet{}
- // err = u.rDB.Where("address = ?", request.ToAddress).Find(&ToWallet).Error
- // if errors.Is(err, gorm.ErrRecordNotFound) {
- // gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, err)
- // return
- // }
- var txHash *types.Transaction
- amount := int64(request.Amount * 100000)
- // //FIXME b 출금하기 함수 호출
- if request.Currency == "eth" {
- err, tx := helpers.TransferETH(wallet.PrivateKey, request.ToAddress, big.NewInt(amount).Mul(big.NewInt(amount), big.NewInt(common.Decimal13)))
- if err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- }
- txHash = tx
- } else if request.Currency == "mf" {
- err, tx := helpers.TransferMetaFinance(wallet.PrivateKey, request.ToAddress, big.NewInt(amount).Mul(big.NewInt(amount), big.NewInt(common.Decimal13)))
- if err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- }
- txHash = tx
- } else if request.Currency == "mr" {
- err, tx := helpers.TransferMetaRare(wallet.PrivateKey, request.ToAddress, big.NewInt(amount).Mul(big.NewInt(amount), big.NewInt(common.Decimal13)))
- if err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- }
- txHash = tx
- }
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, txHash.Hash().String(), nil)
- }
- // certificationCode godoc
- // @Summary send certification code
- // @Description 출금하기 2차 인증
- // @Schemes
- // @Tags user
- // @name get-string-by-int
- // @Accept json
- // @Produce json
- // @Param CertificationBody body CertificationBody true "currency: mf, mr, eth"
- // @Success 200 {string} OK!
- // @Router /user/certification/code [post]
- func (u UserV1Router) certificationCode(c *gin.Context) {
- userID, _err := gauth.GetCurrentUserIDToInt64(c)
- if _err != nil || userID == 0 {
- gerror.IntegratedResponseToRequest(c, http.StatusUnauthorized, gerror.Unauthorized, nil, _err)
- return
- }
- request := CertificationBody{}
- if err := c.ShouldBindJSON(&request); err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, err)
- return
- }
- authentication := models.UserAuthentication{}
- err := u.rDB.Where("user_id = ?", userID).Find(&authentication).Error
- if errors.Is(err, gorm.ErrRecordNotFound) {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, err)
- return
- }
- tx := u.mDB.Begin()
- defer common.DBTransaction(tx)
- _email := authentication.Email
- code, err := common.SendCertificationCode(_email, u.Env.GetString("smtp.email"), u.Env.GetString("smtp.password"))
- if err != nil {
- tx.Rollback()
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.InvalidParameterValue, nil, err)
- return
- }
- if err := u.mDB.Model(&models.UserWallet{}).Where("user_id = ?", userID).Updates(models.UserWallet{CertificationCode: null.StringFrom(code), RequestBalance: null.FloatFrom(request.Amount), RequestCurrency: request.Currency}).Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusBadRequest, gerror.InvalidParameterValue, nil, err)
- tx.Rollback()
- return
- }
- if err := tx.Commit().Error; err != nil {
- gerror.IntegratedResponseToRequest(c, http.StatusInternalServerError, gerror.MysqlSaveError, nil, err)
- tx.Rollback()
- return
- }
- gerror.IntegratedResponseToRequest(c, http.StatusOK, gerror.OK, nil, nil)
- }
|