From 2483b33dc148ce709aac366086e43ac0125d85cd Mon Sep 17 00:00:00 2001 From: gazebo Date: Thu, 17 Oct 2019 13:54:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7=E9=85=8D?= =?UTF-8?q?=E9=80=81=E5=9C=B0=E5=9D=80=E7=AE=A1=E7=90=86API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxstore/cms/user2.go | 134 ++++++++++++++++++++++++++ business/model/dao/dao_user2.go | 61 +++++++++++- business/model/user.go | 49 +++++++--- controllers/cms_user2.go | 76 +++++++++++++++ globals/beegodb/beegodb.go | 1 + routers/commentsRouter_controllers.go | 36 +++++++ 6 files changed, 344 insertions(+), 13 deletions(-) diff --git a/business/jxstore/cms/user2.go b/business/jxstore/cms/user2.go index 55365478f..7cca16dd3 100644 --- a/business/jxstore/cms/user2.go +++ b/business/jxstore/cms/user2.go @@ -499,3 +499,137 @@ func DeleteUsers4Role(ctx *jxcontext.Context, r *authz.RoleInfo, userIDList []st } return errList.GetErrListAsOne() } + +func getAddressInfoFromCoord(db *dao.DaoDB, lng, lat float64) (formattedAddress string, districtCode, cityCode int, err error) { + regeoInfo, err := api.AutonaviAPI.GeoCodeRegeoSingle(lng, lat, 0, false, nil, 0, 0) + if err == nil { + formattedAddress = regeoInfo.FormattedAddress + districtCode = int(utils.Str2Int64(regeoInfo.AddressComponent.Adcode)) + if districtInfo, err2 := dao.GetPlaceByCode(db, districtCode); err2 == nil { + cityCode = districtInfo.ParentCode + } + } + return formattedAddress, districtCode, cityCode, err +} + +func AddUserDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAddress) (outAddress *model.UserDeliveryAddress, err error) { + if address.UserID == "" { + return nil, fmt.Errorf("操作用户配送地址时必须指定UserID") + } + db := dao.GetDB() + lng := address.Lng + lat := address.Lat + address.AutoAddress, address.DistrictCode, address.CityCode, err = getAddressInfoFromCoord(db, lng, lat) + if err == nil { + dao.Begin(db) + defer func() { + if r := recover(); r != nil { + dao.Rollback(db) + panic(r) + } + }() + dao.WrapAddIDCULDEntity(address, ctx.GetUserName()) + if address.IsDefault == 1 { + if err = dao.ClearUserDeliveryAddressDefault(db, address.UserID, 0); err != nil { + dao.Rollback(db) + return nil, err + } + } + if err = dao.CreateEntity(db, address); err == nil { + dao.Commit(db) + outAddress = address + } else { + dao.Rollback(db) + } + } + return outAddress, err +} + +func AddMyDeliveryAddress(ctx *jxcontext.Context, address *model.UserDeliveryAddress) (outAddress *model.UserDeliveryAddress, err error) { + _, address.UserID = ctx.GetMobileAndUserID() + return AddUserDeliveryAddress(ctx, address) +} + +func DeleteUserDeliveryAddress(ctx *jxcontext.Context, userID string, addressID int) (err error) { + num, err := dao.DeleteEntityLogically(dao.GetDB(), &model.UserDeliveryAddress{}, nil, ctx.GetUserName(), map[string]interface{}{ + model.FieldID: addressID, + "UserID": userID, + }) + if err == nil { + if num == 0 { + err = fmt.Errorf("地址ID:%d不存在", addressID) + } + } + return err +} + +func DeleteMyDeliveryAddress(ctx *jxcontext.Context, addressID int) (err error) { + _, userID := ctx.GetMobileAndUserID() + return DeleteUserDeliveryAddress(ctx, userID, addressID) +} + +func UpdateUserDeliveryAddress(ctx *jxcontext.Context, userID string, addressID int, payload map[string]interface{}) (err error) { + if userID == "" { + return fmt.Errorf("操作用户配送地址时必须指定UserID") + } + address := &model.UserDeliveryAddress{ + UserID: userID, + } + address.ID = addressID + db := dao.GetDB() + if err = dao.GetEntity(db, address, model.FieldID, "UserID"); err == nil { + valid := dao.StrictMakeMapByStructObject(payload, address, ctx.GetUserName()) + delete(valid, "autoAddress") + delete(valid, "districtCode") + delete(valid, "cityCode") + if len(valid) > 0 { + if valid["lng"] != nil || valid["lat"] != nil { + valid["autoAddress"], valid["districtCode"], valid["cityCode"], err = getAddressInfoFromCoord(db, utils.MustInterface2Float64(valid["lng"]), utils.MustInterface2Float64(valid["lat"])) + if err != nil { + return err + } + } + dao.Begin(db) + defer func() { + if r := recover(); r != nil { + dao.Rollback(db) + panic(r) + } + }() + if utils.ForceInterface2Int64(valid["isDefault"]) == 1 { + if err = dao.ClearUserDeliveryAddressDefault(db, userID, 0); err != nil { + dao.Rollback(db) + return err + } + } + if _, err = dao.UpdateEntityLogically(db, address, valid, ctx.GetUserName(), nil); err == nil { + dao.Commit(db) + } else { + dao.Rollback(db) + } + } + } + return err +} + +func UpdateMyDeliveryAddress(ctx *jxcontext.Context, addressID int, payload map[string]interface{}) (err error) { + _, userID := ctx.GetMobileAndUserID() + return UpdateUserDeliveryAddress(ctx, userID, addressID, payload) +} + +func QueryUserDeliveryAddress(ctx *jxcontext.Context, userIDs []string, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { + addressList, totalCount, err := dao.QueryUserDeliveryAddress(dao.GetDB(), userIDs, offset, pageSize) + if err == nil { + pagedInfo = &model.PagedInfo{ + TotalCount: totalCount, + Data: addressList, + } + } + return pagedInfo, err +} + +func QueryMyDeliveryAddress(ctx *jxcontext.Context) (addressList []*dao.UserDeliveryAddressEx, err error) { + _, userID := ctx.GetMobileAndUserID() + addressList, _, err = dao.QueryUserDeliveryAddress(dao.GetDB(), []string{userID}, 0, model.UnlimitedPageSize) + return addressList, err +} diff --git a/business/model/dao/dao_user2.go b/business/model/dao/dao_user2.go index 009ab8f40..d66d7ec98 100644 --- a/business/model/dao/dao_user2.go +++ b/business/model/dao/dao_user2.go @@ -13,6 +13,14 @@ type StoreWithCityName struct { CityName string `json:"cityName"` } +type UserDeliveryAddressEx struct { + model.UserDeliveryAddress + + UserName string + CityName string + DistrictName string +} + func GetUserByID(db *DaoDB, fieldName, fieldValue string) (user *model.User, err error) { sql := fmt.Sprintf(` SELECT * @@ -64,7 +72,7 @@ func GetUsers(db *DaoDB, userType int, keyword string, userIDs []string, userID2 sql += " LIMIT ? OFFSET ?" sqlParams = append(sqlParams, pageSize, offset) Begin(db) - defer Rollback(db) + defer Commit(db) if err = GetRows(db, &userList, sql, sqlParams...); err == nil { totalCount = GetLastTotalRowCount(db) } @@ -149,3 +157,54 @@ func GetStoreListByMobileOrStoreIDs(db *DaoDB, mobile string, shortRoleNameList err = GetRows(db, &storeList, sql, sqlParams...) return storeList, err } + +func QueryUserDeliveryAddress(db *DaoDB, userIDs []string, offset, pageSize int) (addressList []*UserDeliveryAddressEx, totalCount int, err error) { + sql := ` + SELECT SQL_CALC_FOUND_ROWS + t1.*, + t2.name user_name, + district.name district_name, + city.name city_name + FROM user_delivery_address t1 + LEFT JOIN user t2 ON t2.user_id = t1.user_id + LEFT JOIN place district ON district.code = t1.district_code + LEFT JOIN place city ON city.code = t1.city_code + WHERE t1.deleted_at = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + } + if len(userIDs) > 0 { + sql += " AND t1.user_id IN (" + GenQuestionMarks(len(userIDs)) + ")" + sqlParams = append(sqlParams, userIDs) + } + offset = FormalizePageOffset(offset) + pageSize = FormalizePageSize(pageSize) + sql += " LIMIT ? OFFSET ?" + sqlParams = append(sqlParams, pageSize, offset) + + Begin(db) + defer Commit(db) + if err = GetRows(db, &addressList, sql, sqlParams...); err == nil { + totalCount = GetLastTotalRowCount(db) + } + return addressList, totalCount, err +} + +func ClearUserDeliveryAddressDefault(db *DaoDB, userID string, defAddressID int) (err error) { + sql := ` + UPDATE user_delivery_address t1 + SET t1.is_default = 0 + WHERE t1.deleted_at = ? AND t1.user_id = ? + ` + sqlParams := []interface{}{ + utils.DefaultTimeValue, + userID, + } + if defAddressID > 0 { + sql += " AND t1.id <> ?" + sqlParams = append(sqlParams, defAddressID) + } + _, err = ExecuteSQL(db, sql, sqlParams...) + return err +} diff --git a/business/model/user.go b/business/model/user.go index 583264a79..cb2d01de7 100644 --- a/business/model/user.go +++ b/business/model/user.go @@ -112,17 +112,42 @@ type UserDeliveryAddress struct { ModelIDCULD UserID string `orm:"size(48);column(user_id)" json:"userID"` // 内部唯一标识 - Name string `orm:"size(255)" json:"name"` - Tag string `orm:"size(32)" json:"tag"` - ConsigneeName string `orm:"size(32)" json:"consigneeName"` - ConsigneeMobile string `orm:"size(32)" json:"consigneeMobile"` - AutoAddress string `orm:"size(255)" json:"autoAddress"` // 这个是通过坐标自动获取的结构化的地址 - Address string `orm:"size(255)" json:"address"` // 这个是用户手输入的详细地址 - CityCode int `orm:"default(0);null" json:"cityCode"` // todo ? - DistrictCode int `orm:"default(0);null" json:"districtCode"` // todo ? - Lng int `json:"-"` // 乘了10的6次方 - Lat int `json:"-"` // 乘了10的6次方 - Remark string `orm:"type(text)" json:"-"` - IsDefault int8 `json:"isDefault"` + Tag string `orm:"size(32)" json:"tag"` + ConsigneeName string `orm:"size(32)" json:"consigneeName"` + ConsigneeMobile string `orm:"size(32)" json:"consigneeMobile"` + Address string `orm:"size(255)" json:"address"` // 这个是用户手输入的详细地址 + Lng float64 `orm:"digits(10);decimals(6)" json:"lng"` // 乘了10的6次方 + Lat float64 `orm:"digits(10);decimals(6)" json:"lat"` // 乘了10的6次方 + + AutoAddress string `orm:"size(255)" json:"autoAddress"` // 这个是通过坐标自动获取的结构化的地址 + CityCode int `orm:"default(0);null" json:"cityCode"` // 根据坐标获得 + DistrictCode int `orm:"default(0);null" json:"districtCode"` // 根据坐标获得 + + Remark string `orm:"type(text)" json:"remark"` + IsDefault int8 `json:"isDefault"` +} + +func (*UserDeliveryAddress) TableUnique() [][]string { + return [][]string{ + // []string{"UserID", "ConsigneeMobile", "DeletedAt"}, + } +} + +type UserCartItem struct { + ModelIDCUL + + UserID string `orm:"size(48);column(user_id)" json:"userID"` + StoreID int `orm:"column(store_id)" json:"storeID"` + SkuID int `orm:"column(sku_id)"` + ActID int `orm:"column(act_id)" json:"actID"` + + Count int `json:"count"` + AddedAt time.Time `orm:"auto_now_add;type(datetime)" json:"addedAt"` +} + +func (*UserCartItem) TableUnique() [][]string { + return [][]string{ + []string{"UserID", "StoreID", "SkuID", "ActID"}, + } } diff --git a/controllers/cms_user2.go b/controllers/cms_user2.go index d907a8d56..bad7de7fc 100644 --- a/controllers/cms_user2.go +++ b/controllers/cms_user2.go @@ -1,6 +1,7 @@ package controllers import ( + "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/auth2" "git.rosy.net.cn/jx-callback/business/authz" "git.rosy.net.cn/jx-callback/business/authz/autils" @@ -248,3 +249,78 @@ func (c *User2Controller) TransferLegacyWeixins() { return retVal, "", err }) } + +// @Title 用户自己增加配送地址 +// @Description 用户自己增加配送地址 +// @Param token header string true "认证token" +// @Param consigneeName formData string true "收货人" +// @Param consigneeMobile formData string true "收货人手机" +// @Param address formData string true "详细地址" +// @Param lng formData float64 true "经度" +// @Param lat formData float64 true "纬度" +// @Param tag formData string false "标签" +// @Param remark formData string false "备注" +// @Param isDefault formData bool false "是否是默认" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /AddMyDeliveryAddress [post] +func (c *User2Controller) AddMyDeliveryAddress() { + c.callAddMyDeliveryAddress(func(params *tUser2AddMyDeliveryAddressParams) (retVal interface{}, errCode string, err error) { + var address *model.UserDeliveryAddress + params.MapData["isDefault"] = utils.Bool2Int(params.IsDefault) + if err = utils.Map2StructByJson(params.MapData, &address, true); err == nil { + retVal, err = cms.AddMyDeliveryAddress(params.Ctx, address) + } + return retVal, "", err + }) +} + +// @Title 用户自己删除配送地址 +// @Description 用户自己删除送地址 +// @Param token header string true "认证token" +// @Param addressID query int true "地址ID" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /DeleteMyDeliveryAddress [delete] +func (c *User2Controller) DeleteMyDeliveryAddress() { + c.callDeleteMyDeliveryAddress(func(params *tUser2DeleteMyDeliveryAddressParams) (retVal interface{}, errCode string, err error) { + err = cms.DeleteMyDeliveryAddress(params.Ctx, params.AddressID) + return retVal, "", err + }) +} + +// @Title 用户自己修改配送地址 +// @Description 用户自己修改配送地址 +// @Param token header string true "认证token" +// @Param addressID formData int true "地址ID" +// @Param consigneeName formData string false "收货人" +// @Param consigneeMobile formData string false "收货人手机" +// @Param address formData string false "详细地址" +// @Param lng formData float64 false "经度" +// @Param lat formData float64 false "纬度" +// @Param tag formData string false "标签" +// @Param remark formData string false "备注" +// @Param isDefault formData bool false "是否是默认" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /UpdateMyDeliveryAddress [put] +func (c *User2Controller) UpdateMyDeliveryAddress() { + c.callUpdateMyDeliveryAddress(func(params *tUser2UpdateMyDeliveryAddressParams) (retVal interface{}, errCode string, err error) { + params.MapData["isDefault"] = utils.Bool2Int(params.IsDefault) + err = cms.UpdateMyDeliveryAddress(params.Ctx, params.AddressID, params.MapData) + return retVal, "", err + }) +} + +// @Title 用户查询自己的配送地址 +// @Description 用户查询自己的配送地址 +// @Param token header string true "认证token" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /QueryMyDeliveryAddress [get] +func (c *User2Controller) QueryMyDeliveryAddress() { + c.callQueryMyDeliveryAddress(func(params *tUser2QueryMyDeliveryAddressParams) (retVal interface{}, errCode string, err error) { + retVal, err = cms.QueryMyDeliveryAddress(params.Ctx) + return retVal, "", err + }) +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index eded1d8e9..f9b462331 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -59,6 +59,7 @@ func Init() { orm.RegisterModel(&model.FoodRecipe{}, &model.FoodRecipeStep{}, &model.FoodRecipeItem{}, &model.FoodRecipeItemChoice{}, &model.FoodRecipeUser{}) orm.RegisterModel(&model.DataResource{}) + orm.RegisterModel(&model.UserDeliveryAddress{}) // create table orm.RunSyncdb("default", false, true) } diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index dc64e2804..2621dd933 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -1746,6 +1746,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], + beego.ControllerComments{ + Method: "AddMyDeliveryAddress", + Router: `/AddMyDeliveryAddress`, + AllowHTTPMethods: []string{"post"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], beego.ControllerComments{ Method: "AddRoles4User", @@ -1764,6 +1773,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], + beego.ControllerComments{ + Method: "DeleteMyDeliveryAddress", + Router: `/DeleteMyDeliveryAddress`, + AllowHTTPMethods: []string{"delete"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], beego.ControllerComments{ Method: "DeleteRoles4User", @@ -1845,6 +1863,15 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], + beego.ControllerComments{ + Method: "QueryMyDeliveryAddress", + Router: `/QueryMyDeliveryAddress`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], beego.ControllerComments{ Method: "RegisterUser", @@ -1863,4 +1890,13 @@ func init() { Filters: nil, Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"], + beego.ControllerComments{ + Method: "UpdateMyDeliveryAddress", + Router: `/UpdateMyDeliveryAddress`, + AllowHTTPMethods: []string{"put"}, + MethodParams: param.Make(), + Filters: nil, + Params: nil}) + }