Merge remote-tracking branch 'origin/mark' into don

This commit is contained in:
Rosy-zhudan
2019-08-08 09:14:21 +08:00
20 changed files with 538 additions and 87 deletions

View File

@@ -3,6 +3,7 @@ package weixin
import ( import (
"errors" "errors"
"git.rosy.net.cn/baseapi/platformapi/weixinapi"
"git.rosy.net.cn/jx-callback/business/auth2" "git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider" "git.rosy.net.cn/jx-callback/business/auth2/authprovider"
"git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals"
@@ -10,9 +11,9 @@ import (
) )
const ( const (
AuthTypeWeixin = "weixin" AuthTypeWeixin = "wxqrcode" // 微信扫码
AuthTypeMP = "weixinsns" AuthTypeMP = "weixinsns" // 公众号
AuthTypeMini = "weixinmini" AuthTypeMini = "weixinmini" // 小程序
) )
type Auther struct { type Auther struct {
@@ -44,9 +45,9 @@ func init() {
func (a *Auther) VerifySecret(state, code string) (authBindEx *auth2.AuthBindEx, err error) { func (a *Auther) VerifySecret(state, code string) (authBindEx *auth2.AuthBindEx, err error) {
globals.SugarLogger.Debugf("weixin VerifySecret code:%s", code) globals.SugarLogger.Debugf("weixin VerifySecret code:%s", code)
if state == "" { if state == "" {
token, err2 := api.WeixinPageAPI.SNSRetrieveToken(code) token, err2 := a.getAPI().SNSRetrieveToken(code)
if err = err2; err == nil { if err = err2; err == nil {
wxUserinfo, err2 := api.WeixinPageAPI.SNSGetUserInfo(token.AccessToken, token.OpenID) wxUserinfo, err2 := a.getAPI().SNSGetUserInfo(token.AccessToken, token.OpenID)
if err = err2; err == nil { if err = err2; err == nil {
if authBindEx, err = a.UnionFindAuthBind(a.authType, []string{AuthTypeWeixin, AuthTypeMP, AuthTypeMini}, wxUserinfo.OpenID, wxUserinfo.UnionID, wxUserinfo); err == nil { if authBindEx, err = a.UnionFindAuthBind(a.authType, []string{AuthTypeWeixin, AuthTypeMP, AuthTypeMini}, wxUserinfo.OpenID, wxUserinfo.UnionID, wxUserinfo); err == nil {
authBindEx.UserHint = &auth2.UserBasic{ authBindEx.UserHint = &auth2.UserBasic{
@@ -60,3 +61,10 @@ func (a *Auther) VerifySecret(state, code string) (authBindEx *auth2.AuthBindEx,
} }
return authBindEx, err return authBindEx, err
} }
func (a *Auther) getAPI() *weixinapi.API {
if a.authType == AuthTypeWeixin {
return api.WeixinPageAPI
}
return api.WeixinAPI
}

View File

@@ -1,10 +1,9 @@
package authz package authz
type IAuthz interface { type IAuthz interface {
AddStoreRole4User(userID string, storeID int) (err error) AddRole4User(userID string, r *RoleInfo) (err error)
DelStoreRole4User(userID string, storeID int) (err error) DeleteRole4User(userID string, r *RoleInfo) (err error)
AddRole4User(userID, roleName string) (err error) GetUserRoleList(userID string) (roleList []*RoleInfo, err error)
DelRole4User(userID, roleName string) (err error) GetRoleUserList(r *RoleInfo) (userIDList []string, err error)
GetUserRoleList(userID string) (roleList []string, err error) // GetAllRoleList() (roleList []*RoleInfo)
GetRoleUserList(roleName string) (userIDList []string, err error)
} }

View File

@@ -1,23 +1,101 @@
package authz package authz
import ( import (
"fmt"
"strings" "strings"
"git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
) )
const ( const (
StoreRoleBoss = "StoreBoss"
RoleNameSep = "/" RoleNameSep = "/"
RolePrefix = "role" RolePrefix = "Role"
StoreRolePrefix = "store" StoreRolePrefix = "Store"
) )
func GenStoreRoleName(storeID int) (roleName string) { type RoleInfo struct {
return strings.Join([]string{ Name string `json:"name"`
Description string `json:"description"`
StoreID int `json:"storeID,omitempty"` // 如果这个值非0表示门店角色
}
var (
storeRoleDescriptionMap = map[string]string{
StoreRoleBoss: "门店老板",
}
StoreRoleList = []*RoleInfo{
&RoleInfo{
Name: StoreRoleBoss,
Description: storeRoleDescriptionMap[StoreRoleBoss],
},
}
)
func GetRoleDescription(name string, storeID int) (description string) {
if storeID != 0 {
description = storeRoleDescriptionMap[name]
} else {
if confList, err := dao.QueryConfigs(dao.GetDB(), name, model.ConfigTypeRole, ""); err == nil && len(confList) > 0 {
description = confList[0].Value
}
}
return description
}
func ValidateRole(name string, storeID int) (err error) {
if GetRoleDescription(name, storeID) == "" {
err = fmt.Errorf("角色%s不合法", name)
}
return err
}
func NewRole(name string, storeID int) (r *RoleInfo) {
r = &RoleInfo{
Name: name,
StoreID: storeID,
Description: GetRoleDescription(name, storeID),
}
return r
}
func NewRoleByModel(conf *model.NewConfig) (r *RoleInfo) {
if conf.Type != model.ConfigTypeRole {
r = NewRole(conf.Key, 0)
}
return r
}
func NewRoleByFullName(fullRoleName string) (r *RoleInfo) {
strList := strings.Split(fullRoleName, RoleNameSep)
if len(strList) == 2 {
r = NewRole(strList[1], 0)
} else if len(strList) == 4 {
r = NewRole(strList[1], int(utils.Str2Int64(strList[3])))
}
return r
}
func (r *RoleInfo) GetFullName() (fullRoleName string) {
strList := []string{
RolePrefix, RolePrefix,
StoreRolePrefix, r.Name,
utils.Int2Str(storeID), }
}, RoleNameSep) if r.StoreID > 0 {
strList = append(strList, StoreRolePrefix, utils.Int2Str(r.StoreID))
}
fullRoleName = strings.Join(strList, RoleNameSep)
return fullRoleName
}
func RoleName2StoreID(roleName string) (storeID int) {
if list := strings.Split(roleName, RoleNameSep); len(list) == 4 {
storeID = int(utils.Str2Int64(list[2]))
}
return storeID
} }
func GetStoreIDFromRole(roleName string) (storeID int) { func GetStoreIDFromRole(roleName string) (storeID int) {
@@ -27,3 +105,30 @@ func GetStoreIDFromRole(roleName string) (storeID int) {
} }
return storeID return storeID
} }
func RoleList2StoreIDList(roleList []*RoleInfo) (storeIDs []int) {
for _, v := range roleList {
if v.StoreID > 0 {
storeIDs = append(storeIDs, v.StoreID)
}
}
return storeIDs
}
func FullRoleName2RoleList(fullRoleNameList []string) (roleList []*RoleInfo) {
if len(fullRoleNameList) > 0 {
roleList = make([]*RoleInfo, len(fullRoleNameList))
for k, v := range fullRoleNameList {
roleList[k] = NewRoleByFullName(v)
}
}
return roleList
}
func RoleList2Map(roleList []*RoleInfo) (roleMap map[string]*RoleInfo) {
roleMap = make(map[string]*RoleInfo)
for _, v := range roleList {
roleMap[v.Name] = v
}
return roleMap
}

View File

@@ -2,6 +2,7 @@ package casbinauth
import ( import (
"git.rosy.net.cn/jx-callback/business/authz" "git.rosy.net.cn/jx-callback/business/authz"
"git.rosy.net.cn/jx-callback/globals"
"github.com/casbin/casbin" "github.com/casbin/casbin"
) )
@@ -15,30 +16,30 @@ func New(modelFile string) (authObj authz.IAuthz, err error) {
return obj, err return obj, err
} }
func (c *CasbinAuthz) AddStoreRole4User(userID string, storeID int) (err error) { func (c *CasbinAuthz) AddRole4User(userID string, r *authz.RoleInfo) (err error) {
return c.AddRole4User(userID, authz.GenStoreRoleName(storeID)) _, err = c.enforcer.AddRoleForUser(userID, r.GetFullName())
}
func (c *CasbinAuthz) DelStoreRole4User(userID string, storeID int) (err error) {
return c.DelRole4User(userID, authz.GenStoreRoleName(storeID))
}
func (c *CasbinAuthz) AddRole4User(userID, roleName string) (err error) {
_, err = c.enforcer.AddRoleForUser(userID, roleName)
return err return err
} }
func (c *CasbinAuthz) DelRole4User(userID, roleName string) (err error) { func (c *CasbinAuthz) DeleteRole4User(userID string, r *authz.RoleInfo) (err error) {
_, err = c.enforcer.DeleteRoleForUser(userID, roleName) _, err = c.enforcer.DeleteRoleForUser(userID, r.GetFullName())
return err return err
} }
func (c *CasbinAuthz) GetUserRoleList(userID string) (roleList []string, err error) { func (c *CasbinAuthz) GetUserRoleList(userID string) (roleList []*authz.RoleInfo, err error) {
roleList, err = c.enforcer.GetRolesForUser(userID) roleNameList, err := c.enforcer.GetRolesForUser(userID)
if err == nil && len(roleNameList) > 0 {
roleList = authz.FullRoleName2RoleList(roleNameList)
}
return roleList, err return roleList, err
} }
func (c *CasbinAuthz) GetRoleUserList(roleName string) (userIDList []string, err error) { func (c *CasbinAuthz) GetRoleUserList(r *authz.RoleInfo) (userIDList []string, err error) {
userIDList, err = c.enforcer.GetUsersForRole(roleName) globals.SugarLogger.Debug(r.GetFullName())
userIDList, err = c.enforcer.GetUsersForRole(r.GetFullName())
return userIDList, err return userIDList, err
} }
// func (c *CasbinAuthz) GetAllRoleList() (roleList []*authz.RoleInfo) {
// return authz.FullRoleName2RoleList(c.enforcer.GetAllRoles())
// }

View File

@@ -701,8 +701,9 @@ func (s *DefScheduler) swtich2SelfDeliverWithRetry(savedOrderInfo *WatchOrderInf
s.updateOrderByBill(order, nil, false) s.updateOrderByBill(order, nil, false)
} }
} }
order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled // todo 之前这里为什么要设置OrderDeliveryFlagMaskScheduleDisabled标志呢
partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag"}) // order.DeliveryFlag |= model.OrderDeliveryFlagMaskScheduleDisabled
// partner.CurOrderManager.UpdateOrderFields(order, []string{"DeliveryFlag"})
partner.CurOrderManager.OnOrderMsg(order, "转商家自配送失败", errStr) partner.CurOrderManager.OnOrderMsg(order, "转商家自配送失败", errStr)
} }

View File

@@ -3,12 +3,15 @@ package cms
import ( import (
"git.rosy.net.cn/jx-callback/business/auth2" "git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
"git.rosy.net.cn/jx-callback/business/authz"
"git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/model/legacymodel" "git.rosy.net.cn/jx-callback/business/model/legacymodel"
"git.rosy.net.cn/jx-callback/globals/api2" "git.rosy.net.cn/jx-callback/globals/api2"
) )
// todo 是否需要将Store.MarketManPhone与OperatorPhone成角色
func TransferLegacyWeixins() (err error) { func TransferLegacyWeixins() (err error) {
const remark4Transfer = "transfer" const remark4Transfer = "transfer"
// DELETE t1 // DELETE t1
@@ -88,8 +91,8 @@ func TransferLegacyWeixins() (err error) {
}, },
}) })
} }
if v.JxStoreID > 0 { if v.JxStoreID > 0 && user.Type&model.UserTypeOperator == 0 { // 运营就不加到门店老板组里了
api2.RoleMan.AddStoreRole4User(user.GetID(), v.JxStoreID) api2.RoleMan.AddRole4User(user.GetID(), authz.NewRole(authz.StoreRoleBoss, v.JxStoreID))
} }
} }
} }

View File

@@ -6,6 +6,7 @@ import (
"git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/globals/api2" "git.rosy.net.cn/jx-callback/globals/api2"
"git.rosy.net.cn/jx-callback/business/authz"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai" _ "git.rosy.net.cn/jx-callback/business/partner/purchase/ebai"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm" _ "git.rosy.net.cn/jx-callback/business/partner/purchase/elm"
_ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd" _ "git.rosy.net.cn/jx-callback/business/partner/purchase/jd"
@@ -21,7 +22,7 @@ func TestTransferLegacyWeixins(t *testing.T) {
} }
func TestCasbin(t *testing.T) { func TestCasbin(t *testing.T) {
userList, err := api2.RoleMan.GetRoleUserList("role/store/100324") userList, err := api2.RoleMan.GetRoleUserList(authz.NewRole(authz.StoreRoleBoss, 100324))
t.Log(utils.Format4Output(userList, false)) t.Log(utils.Format4Output(userList, false))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -6,9 +6,12 @@ import (
"strings" "strings"
"time" "time"
"git.rosy.net.cn/jx-callback/globals/api2"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi" "git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/mobile" "git.rosy.net.cn/jx-callback/business/auth2/authprovider/mobile"
"git.rosy.net.cn/jx-callback/business/authz"
"git.rosy.net.cn/jx-callback/business/jxutils/msg" "git.rosy.net.cn/jx-callback/business/jxutils/msg"
"git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/business/partner"
@@ -216,6 +219,7 @@ func checkConfig(configType, key, value string) (err error) {
err = fmt.Errorf("此银行代码:%s不支持请联系开发", value) err = fmt.Errorf("此银行代码:%s不支持请联系开发", value)
} }
} }
case model.ConfigTypeRole:
default: default:
err = fmt.Errorf("当前只支持配置:%s, 传入的配置类型:%s", utils.Format4Output(model.ConfigTypeName, true), configType) err = fmt.Errorf("当前只支持配置:%s, 传入的配置类型:%s", utils.Format4Output(model.ConfigTypeName, true), configType)
} }
@@ -245,21 +249,32 @@ func DeleteConfig(ctx *jxcontext.Context, key, configType string) (err error) {
switch configType { switch configType {
case model.ConfigTypePricePack: case model.ConfigTypePricePack:
storeMapList, err := dao.GetStoresMapList(db, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key) storeMapList, err := dao.GetStoresMapList(db, nil, nil, model.StoreStatusAll, model.StoreIsSyncYes, key)
if err != nil { if err == nil {
return err if len(storeMapList) > 0 {
} var storeInfo []string
if len(storeMapList) > 0 { for _, v := range storeMapList {
var storeInfo []string storeInfo = append(storeInfo, fmt.Sprintf("门店:%d, 平台:%s", v.StoreID, model.VendorChineseNames[v.VendorID]))
for _, v := range storeMapList { }
storeInfo = append(storeInfo, fmt.Sprintf("门店:%d, 平台:%s", v.StoreID, model.VendorChineseNames[v.VendorID])) err = fmt.Errorf("还有门店在使用价格包:%s门店信息:%s", key, strings.Join(storeInfo, ","))
}
}
case model.ConfigTypeRole:
userIDs, err2 := api2.RoleMan.GetRoleUserList(authz.NewRole(key, 0))
if err = err2; err == nil {
if len(userIDs) > 0 {
userList, err2 := GetUsers(ctx, 0, "", userIDs, "", "")
if err = err2; err == nil {
err = fmt.Errorf("还有人员在使用角色:%s人员信息:%s", key, utils.MustMarshal(utils.Struct2Map(userList, "compact")))
}
} }
return fmt.Errorf("还有门店在使用价格包:%s门店信息:%s", key, strings.Join(storeInfo, ","))
} }
} }
_, err = dao.DeleteEntityLogically(db, &model.NewConfig{}, nil, ctx.GetUserName(), map[string]interface{}{ if err == nil {
"Key": key, _, err = dao.DeleteEntityLogically(db, &model.NewConfig{}, nil, ctx.GetUserName(), map[string]interface{}{
"Type": configType, "Key": key,
}) "Type": configType,
})
}
return err return err
} }

View File

@@ -218,6 +218,12 @@ func sku2Update(vendorID int, sku *dao.StoreSkuSyncInfo, syncStatus int8) (item
// kvs[model.FieldDeletedAt] = time.Now() // kvs[model.FieldDeletedAt] = time.Now()
// } // }
} }
} else if syncStatus&model.SyncFlagStockMask != 0 {
if isStoreSkuSyncNeedDelete(sku) {
sku.StoreSkuSyncStatus = 0
} else {
sku.StoreSkuSyncStatus = sku.StoreSkuSyncStatus & (model.SyncFlagPriceMask | model.SyncFlagSaleMask)
}
} else { } else {
sku.StoreSkuSyncStatus = sku.StoreSkuSyncStatus & ^syncStatus sku.StoreSkuSyncStatus = sku.StoreSkuSyncStatus & ^syncStatus
} }
@@ -287,8 +293,15 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
} else if model.IsSyncStatusNew(sku.StoreSkuSyncStatus) { } else if model.IsSyncStatusNew(sku.StoreSkuSyncStatus) {
calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)) calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage))
if singleStoreHandler == nil { if singleStoreHandler == nil {
bareSku = storeSkuSyncInfo2Bare(sku) sku.StoreSkuSyncStatus |= model.SyncFlagSaleMask | model.SyncFlagPriceMask
bareSku = storeSkuSyncInfo2Bare(calVendorPrice4StoreSku(sku, storeDetail.PricePercentagePackObj, int(storeDetail.PricePercentage)))
stockList = append(stockList, bareSku) stockList = append(stockList, bareSku)
priceList = append(priceList, bareSku)
if sku.MergedStatus == model.SkuStatusNormal {
onlineList = append(onlineList, bareSku)
} else {
offlineList = append(offlineList, bareSku)
}
} else { } else {
if sku.MergedStatus == model.SkuStatusNormal /*&& !dao.IsVendorThingIDEmpty(sku.VendorCatID)*/ { if sku.MergedStatus == model.SkuStatusNormal /*&& !dao.IsVendorThingIDEmpty(sku.VendorCatID)*/ {
createList = append(createList, sku) createList = append(createList, sku)
@@ -412,7 +425,7 @@ func syncStoreSkuNew(ctx *jxcontext.Context, parentTask tasksch.ITask, isFull bo
successList = batchedStoreSkuList successList = batchedStoreSkuList
} }
if k == 0 && len(successList) > 0 { if k == 0 && len(successList) > 0 {
updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagModifiedMask) // ? updateStoreSku(dao.GetDB(), vendorID, bareSku2Sync(successList), model.SyncFlagStockMask)
} }
return nil, len(successList), err return nil, len(successList), err
}, ctx, task, list, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), isContinueWhenError) }, ctx, task, list, storeSkuHandler.GetStoreSkusBatchSize(partner.FuncUpdateStoreSkusStock), isContinueWhenError)

View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/jxcallback/auth" "git.rosy.net.cn/jx-callback/business/jxcallback/auth"
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/mobile" "git.rosy.net.cn/jx-callback/business/jxcallback/auth/mobile"
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/weixin" "git.rosy.net.cn/jx-callback/business/jxcallback/auth/weixin"
@@ -66,26 +65,8 @@ func GetSelfInfo(ctx *jxcontext.Context) (storeUserInfo *dao.StoreUserInfo, err
return storeUserInfo, err return storeUserInfo, err
} }
func getMobileFromCtx(ctx *jxcontext.Context) (mobile string) {
token := ctx.GetToken()
if auth2.IsV2Token(token) {
authInfo, err2 := auth2.GetTokenInfo(token)
if err2 == nil {
if authInfo.TokenType == auth2.TokenTypeNormal {
mobile = authInfo.GetMobile()
}
}
} else {
userInfo, err2 := auth.GetUserInfo(token)
if err2 == nil {
mobile = userInfo.GetAuthID()
}
}
return mobile
}
func GetMyStoreList(ctx *jxcontext.Context) (storeList []*dao.StoreWithCityName, err error) { func GetMyStoreList(ctx *jxcontext.Context) (storeList []*dao.StoreWithCityName, err error) {
mobileNum := getMobileFromCtx(ctx) mobileNum, _ := ctx.GetMobileAndUserID()
if mobileNum == "" { if mobileNum == "" {
return nil, fmt.Errorf("不能得到用户手机号") return nil, fmt.Errorf("不能得到用户手机号")
} }

View File

@@ -2,16 +2,21 @@ package cms
import ( import (
"errors" "errors"
"fmt"
"git.rosy.net.cn/baseapi/utils/errlist"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi" "git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/auth2" "git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/dingding" "git.rosy.net.cn/jx-callback/business/auth2/authprovider/dingding"
"git.rosy.net.cn/jx-callback/business/authz"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals" "git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api" "git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/jx-callback/globals/api2"
) )
var ( var (
@@ -156,3 +161,76 @@ func OnDingDingMsg(msg map[string]interface{}) (callbackResponse *dingdingapi.Ca
func GetUsers(ctx *jxcontext.Context, userType int, keyword string, userIDs []string, userID2, mobile string) (userList []*model.User, err error) { func GetUsers(ctx *jxcontext.Context, userType int, keyword string, userIDs []string, userID2, mobile string) (userList []*model.User, err error) {
return dao.GetUsers(dao.GetDB(), userType, keyword, userIDs, userID2, mobile) return dao.GetUsers(dao.GetDB(), userType, keyword, userIDs, userID2, mobile)
} }
func GetMyStoreListNew(ctx *jxcontext.Context) (storeList []*dao.StoreWithCityName, err error) {
mobileNum, userID := ctx.GetMobileAndUserID()
if mobileNum == "" {
return nil, fmt.Errorf("不能得到用户手机号")
}
roleList, err := api2.RoleMan.GetUserRoleList(userID)
if err != nil {
return nil, err
}
storeList, err = dao.GetStoreListByMobileOrStoreIDs(dao.GetDB(), mobileNum, authz.RoleList2StoreIDList(roleList))
return storeList, err
}
func GetStoreRoleList(ctx *jxcontext.Context) (roleList []*authz.RoleInfo, err error) {
return authz.StoreRoleList, nil
}
func GetUserRoleList(ctx *jxcontext.Context, userID string) (roleList []*authz.RoleInfo, err error) {
return api2.RoleMan.GetUserRoleList(userID)
}
func GetRoleUserList(ctx *jxcontext.Context, r *authz.RoleInfo) (userIDList []string, err error) {
return api2.RoleMan.GetRoleUserList(r)
}
func AddRoles4User(ctx *jxcontext.Context, userID string, rList []*authz.RoleInfo) (err error) {
errList := errlist.New()
for _, v := range rList {
if err = authz.ValidateRole(v.Name, v.StoreID); err == nil {
if err = api2.RoleMan.AddRole4User(userID, v); err != nil {
errList.AddErr(err)
}
} else {
errList.AddErr(err)
}
}
return errList.GetErrListAsOne()
}
func DeleteRoles4User(ctx *jxcontext.Context, userID string, rList []*authz.RoleInfo) (err error) {
errList := errlist.New()
for _, v := range rList {
if err = api2.RoleMan.DeleteRole4User(userID, v); err != nil {
errList.AddErr(err)
}
}
return errList.GetErrListAsOne()
}
func AddUsers4Role(ctx *jxcontext.Context, r *authz.RoleInfo, userIDList []string) (err error) {
if err = authz.ValidateRole(r.Name, r.StoreID); err != nil {
return err
}
errList := errlist.New()
for _, v := range userIDList {
if err = api2.RoleMan.AddRole4User(v, r); err != nil {
errList.AddErr(err)
}
}
return errList.GetErrListAsOne()
}
func DeleteUsers4Role(ctx *jxcontext.Context, r *authz.RoleInfo, userIDList []string) (err error) {
errList := errlist.New()
for _, v := range userIDList {
if err = api2.RoleMan.DeleteRole4User(v, r); err != nil {
errList.AddErr(err)
}
}
return errList.GetErrListAsOne()
}

View File

@@ -129,3 +129,22 @@ func (ctx *Context) GetV2AuthInfo() (authInfo *auth2.AuthInfo, err error) {
func (ctx *Context) GetTrackInfo() string { func (ctx *Context) GetTrackInfo() string {
return ctx.Context.GetTrackInfo() + "," + ctx.GetUserName() return ctx.Context.GetTrackInfo() + "," + ctx.GetUserName()
} }
func (ctx *Context) GetMobileAndUserID() (mobile, userID string) {
token := ctx.GetToken()
if auth2.IsV2Token(token) {
authInfo, err2 := auth2.GetTokenInfo(token)
if err2 == nil {
if authInfo.TokenType == auth2.TokenTypeNormal {
mobile = authInfo.GetMobile()
userID = authInfo.GetID()
}
}
} else {
userInfo, err2 := auth.GetUserInfo(token)
if err2 == nil {
mobile = userInfo.GetAuthID()
}
}
return mobile, userID
}

View File

@@ -153,3 +153,25 @@ func GetStoreListByMobile(db *DaoDB, mobile string) (storeList []*StoreWithCityN
} }
return storeList, err return storeList, err
} }
func GetStoreListByMobileOrStoreIDs(db *DaoDB, mobile string, storeIDs []int) (storeList []*StoreWithCityName, err error) {
sql := `
SELECT t1.*, t2.name city_name
FROM store t1
LEFT JOIN place t2 ON t2.code = t1.city_code
WHERE t1.deleted_at = ? AND ( 1 = 0`
sqlParams := []interface{}{
utils.DefaultTimeValue,
}
if mobile != "" {
sql += " OR t1.market_man_phone = ? OR t1.operator_phone = ?"
sqlParams = append(sqlParams, mobile, mobile)
}
if len(storeIDs) > 0 {
sql += " OR t1.id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
sqlParams = append(sqlParams, storeIDs)
}
sql += ")"
err = GetRows(db, &storeList, sql, sqlParams...)
return storeList, err
}

View File

@@ -73,9 +73,10 @@ const (
SyncFlagSaleMask = 8 // 改了门店商品可售状态必须设置此标志 SyncFlagSaleMask = 8 // 改了门店商品可售状态必须设置此标志
SyncFlagPriceMask = 16 // 改了门店商品价格必须设置此标志 SyncFlagPriceMask = 16 // 改了门店商品价格必须设置此标志
SyncFlagSpecMask = 32 SyncFlagStockMask = 32 // 修改库存同步标识,当前只有多门店平台才会用到
SyncFlagSpecMask = 64 // 原值32
SyncFlagStoreSkuOnlyMask = SyncFlagSaleMask | SyncFlagPriceMask SyncFlagStoreSkuOnlyMask = SyncFlagSaleMask | SyncFlagPriceMask | SyncFlagStockMask
SyncFlagStoreSkuModifiedMask = SyncFlagStoreSkuOnlyMask | SyncFlagModifiedMask SyncFlagStoreSkuModifiedMask = SyncFlagStoreSkuOnlyMask | SyncFlagModifiedMask
SyncFlagChangedMask = SyncFlagSpecMask | SyncFlagNewMask | SyncFlagDeletedMask | SyncFlagStoreSkuModifiedMask SyncFlagChangedMask = SyncFlagSpecMask | SyncFlagNewMask | SyncFlagDeletedMask | SyncFlagStoreSkuModifiedMask

View File

@@ -4,6 +4,7 @@ const (
ConfigTypeSys = "Sys" ConfigTypeSys = "Sys"
ConfigTypePricePack = "PricePack" ConfigTypePricePack = "PricePack"
ConfigTypeBank = "Bank" ConfigTypeBank = "Bank"
ConfigTypeRole = "Role"
) )
var ( var (
@@ -11,6 +12,7 @@ var (
ConfigTypeSys: "系统", ConfigTypeSys: "系统",
ConfigTypePricePack: "价格包", ConfigTypePricePack: "价格包",
ConfigTypeBank: "银行", ConfigTypeBank: "银行",
ConfigTypeRole: "角色",
} }
) )

View File

@@ -23,14 +23,14 @@ var (
type User struct { type User struct {
ModelIDCULD ModelIDCULD
UserID string `orm:"size(48);column(user_id)" json:"userID"` // 内部唯一标识 UserID string `orm:"size(48);column(user_id)" json:"userID" compact:"userID"` // 内部唯一标识
UserID2 string `orm:"size(48);column(user_id2)" json:"userID2"` // 外部唯一标识(一般用于登录) UserID2 string `orm:"size(48);column(user_id2)" json:"userID2" compact:"userID2"` // 外部唯一标识(一般用于登录)
Name string `orm:"size(48);index" json:"name"` // 外部唯一显示 标识(一般用于显示) Name string `orm:"size(48);index" json:"name" compact:"name"` // 外部唯一显示 标识(一般用于显示)
Mobile string `orm:"size(32)" json:"mobile"` Mobile string `orm:"size(32)" json:"mobile" compact:"mobile"`
Email string `orm:"size(32);index" json:"email"` Email string `orm:"size(32);index" json:"email" compact:"email"`
Status int8 `json:"status"` Status int8 `json:"status" compact:"status"`
Type int8 `json:"type"` // 用户类型 Type int8 `json:"type" compact:"type"` // 用户类型
IDCardNo string `orm:"size(18);column(id_card_no)" json:"idCardNo"` // 身份证号 IDCardNo string `orm:"size(18);column(id_card_no)" json:"idCardNo" compact:"idCardNo"` // 身份证号
Remark string `orm:"size(255)" json:"remark"` Remark string `orm:"size(255)" json:"remark"`
} }

View File

@@ -261,6 +261,7 @@ dadaSourceID = "73753"
weixinAppID = "wx2bb99eb5d2c9b82c" weixinAppID = "wx2bb99eb5d2c9b82c"
weixinSecret = "6bbbed1443cc062c20a015a64c07a531" weixinSecret = "6bbbed1443cc062c20a015a64c07a531"
getWeixinTokenURL = "http://www.jxc4.com/v2/sys/GetWXToken"
mtwmCallbackURL = "http://callback.alpha.jxc4.com" mtwmCallbackURL = "http://callback.alpha.jxc4.com"
@@ -272,8 +273,6 @@ enableEbaiStoreWrite = true
enableMtwmStoreWrite = true enableMtwmStoreWrite = true
enableWscStoreWrite = false enableWscStoreWrite = false
getWeixinTokenURL = "http://www.jxc4.com/v2/sys/GetWXToken"
[beta] [beta]
enableStoreWrite = false enableStoreWrite = false
enableJdStoreWrite = false enableJdStoreWrite = false
@@ -303,5 +302,6 @@ dadaSourceID = "6660"
weixinAppID = "wx2bb99eb5d2c9b82c" weixinAppID = "wx2bb99eb5d2c9b82c"
weixinSecret = "6bbbed1443cc062c20a015a64c07a531" weixinSecret = "6bbbed1443cc062c20a015a64c07a531"
getWeixinTokenURL = "http://www.jxc4.com/v2/sys/GetWXToken"
dbConnectStr = "root:WebServer@1@tcp(127.0.0.1:3306)/jxd_dev_0?charset=utf8mb4&loc=Local&parseTime=true" dbConnectStr = "root:WebServer@1@tcp(127.0.0.1:3306)/jxd_dev_0?charset=utf8mb4&loc=Local&parseTime=true"

View File

@@ -93,8 +93,8 @@ func (c *Auth2Controller) GetTokenInfo() {
}) })
} }
// @Title 微信认证回调接口 // @Title 微信扫码认证回调接口
// @Description 微信认证回调接口,自己不能直接调用 // @Description 微信扫码认证回调接口,自己不能直接调用
// @Param code query string true "客户同意后得到的code" // @Param code query string true "客户同意后得到的code"
// @Param block query string true "回调地址" // @Param block query string true "回调地址"
// @Param state query string false "微信回调的登录状态" // @Param state query string false "微信回调的登录状态"

View File

@@ -2,6 +2,7 @@ package controllers
import ( import (
"git.rosy.net.cn/jx-callback/business/auth2" "git.rosy.net.cn/jx-callback/business/auth2"
"git.rosy.net.cn/jx-callback/business/authz"
"git.rosy.net.cn/jx-callback/business/jxstore/cms" "git.rosy.net.cn/jx-callback/business/jxstore/cms"
"git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model"
@@ -71,3 +72,132 @@ func (c *User2Controller) GetUsers() {
return retVal, "", err return retVal, "", err
}) })
} }
// @Title 得到用户自己的门店列表
// @Description 得到用户自己的门店列表
// @Param token header string true "认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetMyStoreList [get]
func (c *User2Controller) GetMyStoreList() {
c.callGetMyStoreList(func(params *tUser2GetMyStoreListParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.GetMyStoreListNew(params.Ctx)
return retVal, "", err
})
}
// @Title 得到可用的门店角色列表
// @Description 得到可用的门店角色列表
// @Param token header string true "认证token"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetStoreRoleList [get]
func (c *User2Controller) GetStoreRoleList() {
c.callGetStoreRoleList(func(params *tUser2GetStoreRoleListParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.GetStoreRoleList(params.Ctx)
return retVal, "", err
})
}
// @Title 得到用户所具有的角色列表
// @Description 得到用户所具有的角色列表
// @Param token header string true "认证token"
// @Param userID query string true "用户i"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetUserRoleList [get]
func (c *User2Controller) GetUserRoleList() {
c.callGetUserRoleList(func(params *tUser2GetUserRoleListParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.GetUserRoleList(params.Ctx, params.UserID)
return retVal, "", err
})
}
// @Title 得到角色包括的用户列表
// @Description 得到角色包括的用户列表
// @Param token header string true "认证token"
// @Param roleName query string true "角色名"
// @Param storeID query int false "门店ID如果是全局角色不用填"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /GetRoleUserList [get]
func (c *User2Controller) GetRoleUserList() {
c.callGetRoleUserList(func(params *tUser2GetRoleUserListParams) (retVal interface{}, errCode string, err error) {
retVal, err = cms.GetRoleUserList(params.Ctx, authz.NewRole(params.RoleName, params.StoreID))
return retVal, "", err
})
}
// @Title 给指定用户添加角色列表
// @Description 给指定用户添加角色列表
// @Param token header string true "认证token"
// @Param userID query string true "用户ID"
// @Param roleList query string true "角色列表"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /AddRoles4User [post]
func (c *User2Controller) AddRoles4User() {
c.callAddRoles4User(func(params *tUser2AddRoles4UserParams) (retVal interface{}, errCode string, err error) {
var roleList []*authz.RoleInfo
if err = jxutils.Strings2Objs(params.RoleList, &roleList); err == nil {
err = cms.AddRoles4User(params.Ctx, params.UserID, roleList)
}
return retVal, "", err
})
}
// @Title 给指定用户删除角色列表
// @Description 给指定用户删除角色列表
// @Param token header string true "认证token"
// @Param userID query string true "用户ID"
// @Param roleList query string true "角色列表"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /DeleteRoles4User [delete]
func (c *User2Controller) DeleteRoles4User() {
c.callDeleteRoles4User(func(params *tUser2DeleteRoles4UserParams) (retVal interface{}, errCode string, err error) {
var roleList []*authz.RoleInfo
if err = jxutils.Strings2Objs(params.RoleList, &roleList); err == nil {
err = cms.DeleteRoles4User(params.Ctx, params.UserID, roleList)
}
return retVal, "", err
})
}
// @Title 给指定角色添加用户列表
// @Description 给指定角色添加用户列表
// @Param token header string true "认证token"
// @Param roleName query string true "角色名"
// @Param storeID query int false "门店ID"
// @Param userIDs query string true "用户ID列表"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /AddUsers4Role [post]
func (c *User2Controller) AddUsers4Role() {
c.callAddUsers4Role(func(params *tUser2AddUsers4RoleParams) (retVal interface{}, errCode string, err error) {
var userIDs []string
if err = jxutils.Strings2Objs(params.UserIDs, &userIDs); err == nil {
err = cms.AddUsers4Role(params.Ctx, authz.NewRole(params.RoleName, params.StoreID), userIDs)
}
return retVal, "", err
})
}
// @Title 给指定角色删除用户列表
// @Description 给指定角色删除用户列表
// @Param token header string true "认证token"
// @Param roleName query string true "角色名"
// @Param storeID query int false "门店ID"
// @Param userIDs query string true "用户ID列表"
// @Success 200 {object} controllers.CallResult
// @Failure 200 {object} controllers.CallResult
// @router /DeleteUsers4Role [delete]
func (c *User2Controller) DeleteUsers4Role() {
c.callDeleteUsers4Role(func(params *tUser2DeleteUsers4RoleParams) (retVal interface{}, errCode string, err error) {
var userIDs []string
if err = jxutils.Strings2Objs(params.UserIDs, &userIDs); err == nil {
err = cms.DeleteUsers4Role(params.Ctx, authz.NewRole(params.RoleName, params.StoreID), userIDs)
}
return retVal, "", err
})
}

View File

@@ -1717,6 +1717,42 @@ func init() {
Filters: nil, Filters: nil,
Params: 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",
Router: `/AddRoles4User`,
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: "AddUsers4Role",
Router: `/AddUsers4Role`,
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: "DeleteRoles4User",
Router: `/DeleteRoles4User`,
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: "DeleteUsers4Role",
Router: `/DeleteUsers4Role`,
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.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"],
beego.ControllerComments{ beego.ControllerComments{
Method: "GetBindAuthInfo", Method: "GetBindAuthInfo",
@@ -1726,6 +1762,42 @@ func init() {
Filters: nil, Filters: nil,
Params: 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: "GetMyStoreList",
Router: `/GetMyStoreList`,
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: "GetRoleUserList",
Router: `/GetRoleUserList`,
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: "GetStoreRoleList",
Router: `/GetStoreRoleList`,
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: "GetUserRoleList",
Router: `/GetUserRoleList`,
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.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:User2Controller"],
beego.ControllerComments{ beego.ControllerComments{
Method: "GetUsers", Method: "GetUsers",