作者 yangfu

Merge remote-tracking branch 'origin/dev' into test

... ... @@ -45,5 +45,5 @@ suplus_approve_host ="http://suplus-approve-dev.fjmaimaimai.com"
#阿里云
cname ="https://media.fjmaimaimai.com/"
#服务地址
VOD_SVR_ADDRESS ="http://mmm-open-api-dev.fjmaimaimai.com"
\ No newline at end of file
#企业平台
BUSINESS_ADMIN_SERVICE_HOST ="${BUSINESS_ADMIN_SERVICE_HOST||http://suplus-business-admin-dev.fjmaimaimai.com}"
\ No newline at end of file
... ...
... ... @@ -43,11 +43,8 @@ h5_host = "http://mmm-web-open-test.fjmaimaimai.com"
#审核中心
suplus_approve_host ="http://suplus-approve-dev.fjmaimaimai.com"
#阿里云 https://media.goexample.live/
cname ="https://media.fjmaimaimai.com/"
#阿里云 https://media.fjmaimaimai.com/
cname ="https://media.goexample.live/"
#企业平台
BUSINESS_ADMIN_SERVICE_HOST ="${BUSINESS_ADMIN_SERVICE_HOST||http://suplus-business-admin-test.fjmaimaimai.com}"
#服务地址
VOD_SVR_ADDRESS ="http://mmm-open-api-dev.fjmaimaimai.com"
\ No newline at end of file
BUSINESS_ADMIN_SERVICE_HOST ="${BUSINESS_ADMIN_SERVICE_HOST||http://suplus-business-admin-dev.fjmaimaimai.com}"
\ No newline at end of file
... ...
... ... @@ -46,7 +46,4 @@ suplus_approve_host ="https://public-interface.fjmaimaimai.com/approve"
BUSINESS_ADMIN_SERVICE_HOST ="${BUSINESS_ADMIN_SERVICE_HOST||http://suplus-business-admin-prd.fjmaimaimai.com}"
#阿里云
cname ="https://media.fjmaimaimai.com/"
#服务地址
VOD_SVR_ADDRESS ="http://mmm-open-api-prd.fjmaimaimai.com"
\ No newline at end of file
cname ="https://media.fjmaimaimai.com/"
\ No newline at end of file
... ...
[prod]
#数据库相关
mysql_user = "${MYSQL_USER||suplus_user}"
mysql_password = "${MYSQL_PASSWORD||suplus2019!}"
mysql_host = "${MYSQL_HOST||rm-bp17e26y39qravmwxmo.mysql.rds.aliyuncs.com}"
mysql_port = "${MYSQL_PORT||3306}"
mysql_db_name = "${MYSQL_DB_NAME||opportunity}"
#日志
log_level = "${LOG_LEVEL||debug}"
aliyun_logs_access ="${aliyun_logs_access||app.log}"
#redis相关配置
redis_add = "${REDIS_HOST||127.0.0.1}"
redis_add_port = "${REDIS_PORT||6379}"
redis_auth = "123456"
#sms相关配置
yunpian_sms_sdk_url ="https://sms.yunpian.com/v2/sms/single_send.json"
yunpian_app_key ="0bf6fb10a11a68a95dee80901eb545b5"
#存储 http:https://public-interface.fjmaimaimai.com/opportunity/ http://mmm-opp-prd.fjmaimaimai.com/
source_host ="https://mmm-opp-prd.fjmaimaimai.com/"
source_virtual_path=file/opp
source_path ="${aliyun_file_access||/var/www/opp/file/opportunity}"
#网易云信 IM
net_im_base_url ="https://api.netease.im/nimserver"
net_im_app_secret ="a8d231f5c13a"
net_im_app_key ="9c5410602597a7fe367aeeebd8210262"
#统一用户中心 39aefef9e22744a3b2d2d3791824ae7b
user_center_url ="https://public-interface.fjmaimaimai.com/ucenter"
user_center_salt ="rsF0pL!6DwjBO735"
user_center_app_key ="39aefef9e22744a3b2d2d3791824ae7b"
user_center_app_secret ="cykbjnfqgctn"
#Html5
h5_host = "https://web-open.fjmaimaimai.com"
#审核中心
suplus_approve_host ="https://public-interface.fjmaimaimai.com/approve"
#企业平台
BUSINESS_ADMIN_SERVICE_HOST ="${BUSINESS_ADMIN_SERVICE_HOST||http://suplus-business-admin-prd.fjmaimaimai.com}"
#阿里云
cname ="https://media.fjmaimaimai.com/"
\ No newline at end of file
... ...
... ... @@ -202,6 +202,7 @@ func CheckToken(ctx *context.Context) (result bool) {
if strings.HasSuffix(ctx.Request.RequestURI, "loginModule") ||
strings.HasSuffix(ctx.Request.RequestURI, "accessToken") ||
strings.HasSuffix(ctx.Request.RequestURI, "refreshToken") ||
strings.HasSuffix(ctx.Request.RequestURI, "authorize") ||
strings.HasSuffix(ctx.Request.RequestURI, "smsCode") {
return true
}
... ...
... ... @@ -43,6 +43,27 @@ func (this *AuthController) Login() {
msg = protocol.NewReturnResponse(auth.Login(header, request))
}
//Authorize 模块认证 (登录V2版本)
// @router /authorize [post]
func (this *AuthController) Authorize() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.AuthorizeRequest
if err := json.Unmarshal(this.ByteBody, &request); err != nil {
log.Error(err)
msg = protocol.BadRequestParam(1)
return
}
if b, m := this.Valid(request); !b {
msg = m
return
}
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(auth.Authorize(header, request))
}
//SmsCode
// @router /smsCode [post]
func (this *AuthController) SmsCode() {
... ...
... ... @@ -34,24 +34,3 @@ func (this *ConfigController) GetConfigScore() {
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(config.GetConfigScore(header, request))
}
//ServiceConfig 服务配置
//@router /service [post]
func (this *ConfigController) ServiceConfig() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.ServiceConfigRequest
if err := json.Unmarshal(this.ByteBody, &request); err != nil {
log.Error(err)
msg = protocol.BadRequestParam(1)
return
}
if b, m := this.Valid(request); !b {
msg = m
return
}
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(config.ServiceConfig(header, request))
}
... ...
... ... @@ -59,6 +59,18 @@ type LoginResponse struct {
AuthCode string `json:"authCode"`
}
/*Authorize 模块认证 (登录V2版本)*/
type AuthorizeRequest struct {
Token string `json:"credentials" valid:"Required;"` //登录凭证
ClientId string `json:"clientId"` //客户端密钥
Uid int64 `json:"cuid" valid:"Required;"` //统一用户中心用户 UID
Cid int64 `json:"cid" valid:"Required;"` //统一用户中心公司 ID
Muid int64 `json:"muid" valid:"Required;"` //企业平台中的用户 UID
}
type AuthorizeResponse struct {
AuthCode string `json:"authCode"`
}
/*统一用户中心登录*/
type UserCenterLoginRequest struct {
Phone string `json:"phone"`
... ...
... ... @@ -548,6 +548,10 @@ type Picture struct {
//JobId string `json:"job_id"`
}
type Avatar struct {
Path string `json:"path"`
}
//视频
type Video struct {
Path string `json:"path"`
... ...
... ... @@ -32,19 +32,3 @@ type ScoreRange struct {
Max float64 `json:"max"` //最大分
Step float64 `json:"step"` //步长
}
/*ServiceConfig 服务配置*/
type ServiceConfigRequest struct {
}
type ServiceConfigResponse struct {
ServeConfig *ServeConfig `json:"serveConfig"` //服务配置
}
type ServeConfig struct {
VodAddress string `json:"vodSvrAddress"` //视频服务地址
}
func (s *ServeConfig) SetVodAddress(addr string) *ServeConfig {
s.VodAddress = addr
return s
}
... ...
... ... @@ -13,6 +13,10 @@ var errmessge ErrorMap = map[int]string{
5: "繁忙,请稍后再试",
101: "clientId或clientSecret无效",
113: "签名验证失败",
502: "用户不存在",
503: "用户被禁用",
601: "公司被禁用",
602: "用户无模块权限",
1009: "验证码已失效",
1011: "获取验证码次数超出限制,请联系管理员",
1012: "请输入正确的验证码",
... ... @@ -63,6 +67,16 @@ var errmessge ErrorMap = map[int]string{
//评论相关
5601: "评论不存在",
//企业平台
10001: "用户不存在",
10002: "登录凭证已过期,请重新登录",
10003: "验证码不能为空",
10004: "登录凭证不能为空",
10005: "密码不能为空",
10006: "用户不存在",
10007: "用户已被禁用",
10008: "用户无模块权限",
}
const (
... ...
... ... @@ -64,13 +64,14 @@ type UserStatisticsResponse struct {
}
type User struct {
UserId int64 `json:"uid"`
Name string `json:"uname"`
Phone string `json:"phone"`
Image Picture `json:"image"`
Department Dep `json:"dep"`
Position Job `json:"job"`
ImToken string `json:"imToken"`
UserId int64 `json:"uid"`
MUserId int64 `json:"muid"` //中台用户ID
Name string `json:"uname"`
Phone string `json:"phone"`
Image Avatar `json:"image"`
Department Dep `json:"dep"`
Position Job `json:"job"`
ImToken string `json:"imToken"`
//companys
CompanyId int `json:"companyId"`
... ...
... ... @@ -49,6 +49,14 @@ func init() {
beego.GlobalControllerRouter["opp/controllers/v1:AuthController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:AuthController"],
beego.ControllerComments{
Method: "Authorize",
Router: `/authorize`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:AuthController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:AuthController"],
beego.ControllerComments{
Method: "Login",
Router: `/loginModule`,
AllowHTTPMethods: []string{"post"},
... ... @@ -407,14 +415,6 @@ func init() {
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:ConfigController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ConfigController"],
beego.ControllerComments{
Method: "ServiceConfig",
Router: `/service`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:DepartmentController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:DepartmentController"],
beego.ControllerComments{
Method: "Departments",
... ...
... ... @@ -161,6 +161,35 @@ func CheckUserModuleAuth(uid int64) (auth bool) {
return response.UserAuth
}
func GetUserModuleAuth(uid int64) (message *protocol.Message, auth bool) {
var req = NewRequest(fmt.Sprintf("%v%v", beego.AppConfig.String("BUSINESS_ADMIN_SERVICE_HOST"), MethodUserAuth), http.MethodPost)
message = &protocol.Message{}
auth = false
var request = struct {
UserId string `json:"userId"`
PlatformId string `json:"platformId"`
}{UserId: fmt.Sprintf("%v", uid), PlatformId: "3"} //平台id:1素+;2问题;3机会;18价值
var response = struct {
UserAuth bool `json:"userAuth"`
}{}
if data, err := req.ActionDefault(request, &message); err != nil {
log.Error(err)
return
} else {
log.Debug(req.Url, uid, string(data))
}
if message.Errno != 0 {
log.Debug("CheckUserModuleAuth :", message.Errno, message.Errmsg)
return
}
if err := json.Unmarshal(message.Data, &response); err != nil {
log.Error(err, message, string(message.Data))
return
}
auth = response.UserAuth
return
}
type Request struct {
HttpReq *httplib.BeegoHTTPRequest
Url string
... ...
... ... @@ -281,6 +281,177 @@ Success:
return
}
//模块认证 (登录V2版本)
func Authorize(header *protocol.RequestHeader, request *protocol.AuthorizeRequest) (rsp *protocol.AuthorizeResponse, err error) {
var ()
rsp = &protocol.AuthorizeResponse{}
var (
user *models.User
userAuth *models.UserAuth
id = request.Uid
getUserRequest *protocol.UCenterServerLoginRequest = &protocol.UCenterServerLoginRequest{
Uid: id,
Token: request.Token,
Type: 2,
CompanyId: request.Cid, //当前登录的公司编号
}
getUserResponse *protocol.UCenterGetUserResponse
message *protocol.Message
//currentCompany *models.Company
//companys []*models.Company
userCompany *models.UserCompany
company *models.Company
)
//验证 当前登录的公司是否有模块权限
if err = CheckBusinessAuth(header, request.Muid); err != nil {
log.Error(request.Muid, err)
return
}
//判断用户是否添加
user, err = models.GetUserByUcenterId(id)
if err != nil {
log.Error(err)
err = protocol.NewErrWithMessage(2002, err) //账号不存在
return
}
//判断用户所属公司是否有权限
//if companys, err = models.GetCompanyByPermission(user.Id); err != nil {
// log.Error(err)
// err = protocol.NewErrWithMessage(2002, err) //账号不存在
// return
//}
//if len(companys) == 0 {
// err = protocol.NewErrWithMessage(2002, err) //账号不存在
// return
//}
//权限验证 判断用户公司是否存在
if userCompany, err = models.GetUserCompanyById(request.Muid); err != nil {
log.Error(err, request.Muid)
err = protocol.NewErrWithMessage(10008, err) //用户无模块权限
return
}
if userCompany.Enable != 1 {
err = protocol.NewErrWithMessage(10006, err) //用户已禁用
log.Error(err)
return
}
if company, err = models.GetCompanyById(request.Cid); err != nil {
log.Error(err, request.Cid)
err = protocol.NewErrWithMessage(10007, err) //企业已禁用
return
}
if company.Enable != 1 {
err = protocol.NewErrWithMessage(10007, err) ///企业已禁用
log.Error(err)
return
}
if !utils.ValidVersion(header.Version, protocol.RequireVersion) {
log.Warn(fmt.Sprintf("版本不足 当前手机版本:%v 需要版本大于:%v", header.Version, protocol.RequireVersion))
err = protocol.NewCustomMessage(2002, "版本不足,请升级app") //账号不存在
return
}
//获取最后一次公司编号给统一用户中心
//if u, e := models.GetUserAuthByUserId(user.Id, protocol.DeviceType); e == nil && user.UserCenterId == id {
// if currentCompany, e = models.GetCompanyById(u.CurrentCompanyId); e == nil {
// getUserRequest.CompanyId = currentCompany.UserCenterId
// }
//}
//从用户中心获取用户信息
if _, err = agg.RequestUserCenter(protocol.MethodServerLogin, http.MethodPost, getUserRequest, &message); err != nil {
log.Error(err)
return
}
log.Debug(fmt.Sprintf("ucenter_id:%v user_id:%v getuser response:", request.Uid, request.Muid), message.Errno, message.Errmsg)
if message.Errno == 0 && message.Errmsg == "ok" {
if err = message.Unmarshal(&getUserResponse); err != nil {
log.Error(err)
return
}
}
switch message.Errno {
case -1:
err = protocol.NewErrWithMessage(2002, err) //账号不存在
return
case 0:
goto Success
case 2002:
err = protocol.NewErrWithMessage(2002, err) //账号不存在
return
case 10001:
err = protocol.NewErrWithMessage(2002, err) //账号不存在
return
case 10003:
err = protocol.NewErrWithMessage(4140, err) //账号不存在
return
default:
log.Error(fmt.Sprintf("error_no:%v msg:%v", message.Errno, message.Errmsg))
err = protocol.NewErrWithMessage(4140, err)
return
}
Success:
{
userAuth, err = models.GetUserAuthByUserId(user.Id, 1)
if err != nil {
if err == orm.ErrNoRows {
err = nil
userAuth = &models.UserAuth{
UserId: user.Id,
DeviceType: 1, //int8(header.DeviceType),
CurrentCompanyId: request.Muid,
CurrentUserCompanyId: request.Cid,
}
models.AddUserAuth(userAuth)
} else {
log.Error(err)
return
}
}
userAuth.AuthCode = uid.NewV1().StringNoDash()
userAuth.CurrentCompanyId = request.Cid
userAuth.CurrentUserCompanyId = request.Muid
/*更新用户信息*/
user.CsAccount = getUserResponse.CustomerAccount
user.ImToken = getUserResponse.ImToken
user.Icon = getUserResponse.Avatar
user.NickName = getUserResponse.NickName
user.Accid = getUserResponse.Accid
user.UserCenterId = getUserResponse.Id
if err = models.UpdateUsersById(user); err != nil {
log.Error(err)
return
}
userAuth.AuthCodeExp = time.Now().Add(time.Second * protocol.TokenExpire)
if err = models.UpdateUserAuthById(userAuth); err != nil {
return
}
rsp = &protocol.AuthorizeResponse{AuthCode: userAuth.AuthCode}
}
err = protocol.NewSuccessWithMessage("登录成功")
return
}
//检查企业平台权限
func CheckBusinessAuth(header *protocol.RequestHeader, muid int64) (err error) {
var (
hasAuth bool
authMessage *protocol.Message
)
if authMessage, hasAuth = agg.GetUserModuleAuth(muid); !hasAuth {
err = protocol.NewCustomMessage(authMessage.Errno, authMessage.Errmsg) //账号不存在
return
}
if authMessage.Errno != 0 {
err = protocol.NewCustomMessage(authMessage.Errno, authMessage.Errmsg) //账号不存在
return
}
return
}
//统一用户中心登录
func UCenterLogin(header *protocol.RequestHeader, request *protocol.UCenterLoginRequest) (rsp *protocol.UCenterLoginResponse, err error) {
var (
... ...
... ... @@ -2,7 +2,6 @@ package config
import (
"encoding/json"
"github.com/astaxie/beego"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"opp/models"
"opp/protocol"
... ... @@ -23,13 +22,3 @@ func GetConfigScore(header *protocol.RequestHeader, request *protocol.GetConfigS
}
return
}
//ServiceConfig 服务配置
func ServiceConfig(header *protocol.RequestHeader, request *protocol.ServiceConfigRequest) (rsp *protocol.ServiceConfigResponse, err error) {
var ()
rsp = &protocol.ServiceConfigResponse{
ServeConfig: new(protocol.ServeConfig),
}
rsp.ServeConfig.SetVodAddress(beego.AppConfig.String("VOD_SVR_ADDRESS"))
return
}
... ...
... ... @@ -69,3 +69,25 @@ func Test_FixPath(t *testing.T) {
}
}
}
func Test_UploadImage(t *testing.T) {
input := "https://upfile.asqql.com/2009pasdfasdfic2009s305985-ts/2019-12/2019123019514565723.gif"
var (
err error
auth *aliyun.CreateUploadImageResponse
vodc *vod.Client
)
vodc, err = aliyun.DefaultVodClient()
if err != nil {
t.Fatal(err)
}
auth, err = aliyun.CreateUploadImage(vodc, &aliyun.CreateUploadImageRequest{FileName: fixPath("https://mmm-opp-prd.fjmaimaimai.com/file/opp/image/20200325/1585134451_FrdwfRHEMc33JwX7FtJAY4baMyD7J6pP.jpg")})
if err != nil {
t.Fatal(err)
}
err = upload(fixPath(input), auth.UploadAddress, auth.UploadAuth)
if err != nil {
t.Fatal(err)
}
t.Log(fmt.Sprintf("%v -> %v", input, auth.ImageURL), UploadSuccess)
}
... ...
... ... @@ -357,13 +357,12 @@ func UserInfo(header *protocol.RequestHeader, request *protocol.UserInfoRequest)
}
rsp = &protocol.UserInfoResponse{
User: protocol.User{
UserId: header.UserId,
Name: userBaseAgg.User.NickName,
Phone: userBaseAgg.User.Phone,
Image: protocol.Picture{
UserId: header.UserId,
MUserId: header.UserId,
Name: userBaseAgg.User.NickName,
Phone: userBaseAgg.User.Phone,
Image: protocol.Avatar{
Path: userBaseAgg.User.Icon,
H: 0,
W: 0,
},
ImToken: userBaseAgg.User.ImToken,
CompanyId: int(companyId),
... ... @@ -474,13 +473,12 @@ func UserInfoV3(header *protocol.RequestHeader, request *protocol.UserInfoReques
}
rsp = &protocol.UserInfoResponse{
User: protocol.User{
UserId: header.UserId,
Name: userBaseAgg.User.NickName,
Phone: userBaseAgg.User.Phone,
Image: protocol.Picture{
UserId: header.UserId,
MUserId: header.UserId,
Name: userBaseAgg.User.NickName,
Phone: userBaseAgg.User.Phone,
Image: protocol.Avatar{
Path: userBaseAgg.User.Icon,
H: 0,
W: 0,
},
ImToken: userBaseAgg.User.ImToken,
CompanyId: int(companyId),
... ...