作者 yangfu

登录

... ... @@ -30,4 +30,6 @@ net_im_app_secret ="a8d231f5c13a"
net_im_app_key ="9c5410602597a7fe367aeeebd8210262"
#统一用户中心
user_center_url ="http://user.fjmaimaimai.com"
\ No newline at end of file
user_center_url ="http://suplus-ucenter-dev.fjmaimaimai.com"
user_center_salt ="rsF0pL!6DwjBO735"
user_center_app_key ="39aefef9e22744a3b2d2d3791824ae7b"
\ No newline at end of file
... ...
... ... @@ -2,12 +2,20 @@ package controllers
import (
"fmt"
redigo "github.com/gomodule/redigo/redis"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/redis"
"log"
"opp/protocol"
"opp/tests"
"reflect"
"testing"
"time"
)
func init() {
tests.Init()
}
func Test_GenMessage(t *testing.T) {
input := []struct {
Rsp interface{}
... ... @@ -52,3 +60,69 @@ func Test_Valid(t *testing.T) {
}
DefaultController.Valid(req)
}
func Test_RedisSubPub(t *testing.T) {
c := redis.NewClient()
defer c.Close()
/*redis 订阅*/
go subscribe()
go subscribe()
go subscribe()
for {
var s string
s = time.Now().String()
_, err := c.Do("PUBLISH", "chat", s)
if err != nil {
fmt.Println("pub err: ", err)
return
}
time.Sleep(time.Second * 5)
}
}
func subscribe() {
psc := redis.NewPubsubClient()
defer func() {
psc.Conn.Close()
psc.Unsubscribe("chat")
}()
psc.Subscribe("chat")
for {
switch v := psc.Receive().(type) {
case redigo.Message:
log.Println(fmt.Printf("%s: message: %s\n", v.Channel, v.Data))
case redigo.Subscription:
log.Println(fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count))
case error:
log.Println("error:", v)
return
}
}
}
//redis lock
func Test_RedisLock(t *testing.T) {
//key :="opp:chance:1456872"
//go func(){
// mutext :=redis.NewMutex(key)
// mutext.Lock()
// defer mutext.UnLock()
// time.Sleep(time.Second*10)
//}()
//time.Sleep(time.Second*1)
//go func(){
// mutext :=redis.NewMutex(key)
// defer mutext.UnLock()
// if !mutext.TryLock(3){
// t.Log("fail to get lock",key)
// return
// }
// t.Log("get lock...")
// time.Sleep(time.Second*3)
// t.Log("release lock...")
//}()
//time.Sleep(11*time.Second)
}
... ...
... ... @@ -5,6 +5,7 @@ go 1.12
require (
github.com/astaxie/beego v1.10.0
github.com/go-sql-driver/mysql v1.4.1
github.com/gomodule/redigo v1.7.0
github.com/gorilla/websocket v1.4.1
github.com/klauspost/cpuid v1.2.1 // indirect
github.com/prometheus/client_golang v1.1.0
... ...
... ... @@ -76,7 +76,7 @@ func DeleteUserDepartment(id int64) (err error) {
func GetUserDepartments(userId int64, companyId int64, v interface{}) (err error) {
o := orm.NewOrm()
sql := `
select a.department_id,b.name,b.parent_id,b.managers
select a.department_id,b.name,b.parent_id,b.managers,b.relation,a.create_time
from user_department a INNER JOIN department b on a.department_id = b.id
where a.user_id =? and a.company_id =? and enable_status =1 and b.delete_at =0`
if _, err = o.Raw(sql, userId, companyId).QueryRows(v); err == nil {
... ...
... ... @@ -73,14 +73,13 @@ func DeleteUserPosition(id int) (err error) {
return
}
func GetUserPositions(userId int64, companyId int64, v interface{}) (err error) {
o := orm.NewOrm()
sql := `
select a.position_id,b.name
select a.position_id,b.name,b.relation,a.create_at
from user_position a INNER JOIN position b on a.position_id = b.id
where a.user_id =? and a.company_id =? and a.enable_status =1 and b.enable_status =1`
if _, err = o.Raw(sql,userId, companyId).QueryRows(v); err == nil {
if _, err = o.Raw(sql, userId, companyId).QueryRows(v); err == nil {
return
}
return
... ...
... ... @@ -22,6 +22,8 @@ type User struct {
LastLoginTime time.Time `orm:"column(last_login_time);type(timestamp);auto_now_add" description:"最后一次登录时间"`
CreateAt time.Time `orm:"column(create_at);type(timestamp);auto_now_add" description:"创建时间"`
EnableStatus int8 `orm:"column(enable_status)" description:"是否有效"`
Accid int64 `orm:"column(accid)" description:"网易云id"`
UserCenterId int64 `orm:"column(user_center_id)" description:"统一用户中心用户id"`
}
func (t *User) TableName() string {
... ...
package protocol
import "opp/models"
import (
"opp/models"
"time"
)
//聚合数据
... ... @@ -16,4 +19,6 @@ type UserBaseInfoAggregation struct {
type Position struct {
PositionId int `orm:"column(position_id)`
Name string `orm:"column(name)`
Relation string `orm:"column(relation)" json:"-"`
CreateTime time.Time `orm:"column(create_time)" json:"-"`
}
... ...
... ... @@ -37,18 +37,19 @@ type LoginResponse struct {
}
/*统一用户中心登录*/
type LoginUserCenterRequest struct {
type UserCenterLoginRequest struct {
Phone string `json:"phone"`
PassWord string `json:"password"`
}
type LoginUserCenterResponse struct {
type UserCenterLoginResponse struct {
Id int64 `json:"id"`
Phone string `json:"phone"`
NickName string `json:"nickname"`
Avatar string `json:"avatar"`
Token string `json:"token"`
Accid string `json:"accid"`
CustomerAccount string `json:"customerAccount"`
}
/*SmsCode*/
... ...
package protocol
const RelateSplit = "/"
... ...
package protocol
import "time"
const (
DepartmentAll = iota + 1 //公司所有部门
DepartmentUser //用户所有部门
... ... @@ -18,6 +20,8 @@ type Department struct {
Name string `orm:"column(name)" json:"name"`
PId int `orm:"column(parent_id)" json:"-"`
ManagerString string `orm:"column(managers)" json:"-"`
Relation string `orm:"column(relation)" json:"-"`
CreateTime time.Time `orm:"column(create_time)" json:"-"`
Managers []int `json:"-"`
Departments []*Department `json:"departments,omitempty"`
}
... ...
package protocol
import (
"encoding/json"
)
var errmessge ErrorMap = map[int]string{
0: "成功",
1: "系统异常",
... ... @@ -22,6 +26,8 @@ var errmessge ErrorMap = map[int]string{
4140: "refreshToken过期,需要重新登录授权",
4141: "accessToken过期或无效,需要进行重新获取令牌",
4142: "Uuid已存在,请求失败",
5000: "繁忙,请稍后再试",
}
/*MessageCenter */
... ... @@ -72,3 +78,15 @@ type UserMsg struct {
IsRead int `json:"isRead"`
//机会 //评论
}
type Message struct {
ErrorCode
Data json.RawMessage `json:"data"`
}
func (m Message) Unmarshal(v interface{}) error {
if len(m.Data) == 0 {
m.Data = []byte("{}")
}
return json.Unmarshal(m.Data, v)
}
... ...
... ... @@ -8,6 +8,7 @@ import (
"opp/internal/utils"
"opp/models"
"opp/protocol"
"strings"
"sync"
)
... ... @@ -60,13 +61,67 @@ func GetUserBaseInfo(uid int64, companyId int64) (v *protocol.BaseUserInfo, err
v = &protocol.BaseUserInfo{
UserId: agg.User.Id,
NickName: agg.User.NickName,
Department: agg.Department[0].Name,
Position: agg.Position[0].Name,
Department: GetTopDepartment(agg.Department).Name,
Position: GetTopPosition(agg.Position).Name,
CompanyName: agg.Company.Name,
}
return
}
//获取最高层级部门
func GetTopDepartment(departments []*protocol.Department) *protocol.Department {
var top *protocol.Department
var countTop, countTmp = 0, 0
for i := range departments {
tmp := departments[i]
if i == 0 {
top = tmp
continue
}
countTop = strings.Count(top.Relation, protocol.RelateSplit)
countTmp = strings.Count(tmp.Relation, protocol.RelateSplit)
//层级越高 关系越少
if countTmp > countTop {
continue
}
if countTmp < countTop {
top = tmp
continue
}
if tmp.CreateTime.Unix() < top.CreateTime.Unix() {
top = tmp
}
}
return top
}
//获取最高层级职位
func GetTopPosition(positions []*protocol.Position) *protocol.Position {
var top *protocol.Position
var countTop, countTmp = 0, 0
for i := range positions {
tmp := positions[i]
if i == 0 {
top = tmp
continue
}
countTop = strings.Count(top.Relation, protocol.RelateSplit)
countTmp = strings.Count(tmp.Relation, protocol.RelateSplit)
//层级越高 关系越少
if countTmp > countTop {
continue
}
if countTmp < countTop {
top = tmp
continue
}
if tmp.CreateTime.Unix() < top.CreateTime.Unix() {
top = tmp
}
}
return top
}
func GetChance(chanceId int64, companyId int64) (v *protocol.ChanceDetail, err error) {
var (
c *models.Chance
... ...
package agg
import (
"opp/protocol"
"testing"
"time"
)
func Test_GetTopDepartment(t *testing.T) {
input := []*protocol.Department{
&protocol.Department{
DepartmentId: 1,
Relation: "1",
CreateTime: time.Unix(1575968581, 0),
},
&protocol.Department{
DepartmentId: 4,
Relation: "2/3/4",
CreateTime: time.Unix(1575968581, 0),
},
&protocol.Department{
DepartmentId: 5,
Relation: "2/3/5",
CreateTime: time.Unix(1575968580, 0),
},
}
out := GetTopDepartment(input)
if out.DepartmentId != 1 {
t.Fatal("top department error")
}
}
func Test_GetTopPosition(t *testing.T) {
input := []*protocol.Position{
&protocol.Position{
PositionId: 1,
Relation: "1/2/3/4",
CreateTime: time.Unix(1575968581, 0),
},
&protocol.Position{
PositionId: 4,
Relation: "2/3/4",
CreateTime: time.Unix(1575968581, 0),
},
&protocol.Position{
PositionId: 5,
Relation: "2/3/5",
CreateTime: time.Unix(1575968580, 0),
},
}
out := GetTopPosition(input)
if out.PositionId != 5 {
t.Fatal("top department error")
}
}
... ...
... ... @@ -2,13 +2,18 @@ package auth
import (
"bytes"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/astaxie/beego/httplib"
"github.com/astaxie/beego/orm"
"html/template"
"io/ioutil"
"math/rand"
"net/http"
"opp/internal/utils"
"strings"
"strconv"
"time"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/identity/uid"
... ... @@ -38,7 +43,8 @@ func Login(header *protocol.RequestHeader, request *protocol.LoginRequest) (rsp
user *models.User
userAuth *models.UserAuth
result bool
checkImResponse *protocol.CheckImResponse
//checkImResponse *protocol.CheckImResponse
userCenterLogin *protocol.UserCenterLoginResponse
)
user, err = repository.User.GetUsersByMobile(request.Phone)
if err != nil {
... ... @@ -48,16 +54,24 @@ func Login(header *protocol.RequestHeader, request *protocol.LoginRequest) (rsp
}
switch request.GrantType {
case protocol.LoginTypePassPord:
if beego.BConfig.RunMode != "dev" {
}
if strings.Compare(user.Passwd, request.PassWord) == 0 {
goto Success
} else {
err = protocol.NewErrWithMessage(2021, err) //登录密码错误
//if beego.BConfig.RunMode == "prod" {
//
//}
if userCenterLogin, err = userCenterAuthLogin(&protocol.UserCenterLoginRequest{
Phone: request.Phone,
PassWord: request.PassWord,
}); err != nil {
log.Error(err)
return
}
break
goto Success
//if strings.Compare(user.Passwd, request.PassWord) == 0 {
// goto Success
//} else {
// err = protocol.NewErrWithMessage(2021, err) //登录密码错误
// return
//}
//break
case protocol.LoginTypeSmdcode:
//if beego.BConfig.RunMode =="dev"{
// goto Success
... ... @@ -93,20 +107,32 @@ Success:
}
}
userAuth.AuthCode = uid.NewV1().StringNoDash()
if checkImResponse, err = CheckIm(&protocol.CheckImRequest{
Uid: fmt.Sprintf("%v", user.Id),
Uname: user.NickName,
Icon: user.Icon,
IsCreated: user.ImToken != "",
}); err != nil {
//if checkImResponse, err = CheckIm(&protocol.CheckImRequest{
// Uid: fmt.Sprintf("%v", user.Id),
// Uname: user.NickName,
// Icon: user.Icon,
// IsCreated: user.ImToken != "",
//}); err != nil {
// return
//}
//if checkImResponse != nil && checkImResponse.ImToken != "" {
// user.ImToken = checkImResponse.ImToken
//}
//if user.CsAccount == 0 {
// user.CsAccount = imGetRandomCSAccount()
//}
/*更新用户信息*/
user.CsAccount, _ = strconv.ParseInt(userCenterLogin.CustomerAccount, 10, 64)
user.ImToken = userCenterLogin.Token
user.Icon = userCenterLogin.Avatar
user.NickName = userCenterLogin.NickName
user.Accid, _ = strconv.ParseInt(userCenterLogin.Accid, 10, 64)
user.UserCenterId = userCenterLogin.Id
if err = repository.User.UpdateUserInfo(user); err != nil {
log.Error(err)
return
}
if checkImResponse != nil && checkImResponse.ImToken != "" {
user.ImToken = checkImResponse.ImToken
}
if user.CsAccount == 0 {
user.CsAccount = imGetRandomCSAccount()
}
userAuth.AuthCodeExp = time.Now().Add(time.Second * protocol.TokenExpire)
if err = repository.UserAuth.UpdateUserAuthById(userAuth); err != nil {
return
... ... @@ -489,3 +515,56 @@ func imGetRandomCSAccount() (acid int64) {
acid = kefus[index].Id //Accid
return acid
}
//用户中心密码登录
func userCenterAuthLogin(request *protocol.UserCenterLoginRequest) (rsp *protocol.UserCenterLoginResponse, err error) {
var (
loginMethod = "/auth/login"
httpRsp *http.Response
data []byte
curTime = fmt.Sprintf("%v", time.Now().Unix())
appKey = beego.AppConfig.String("user_center_app_key")
salt = beego.AppConfig.String("user_center_salt")
)
rsp = &protocol.UserCenterLoginResponse{}
httpReq := httplib.Post(beego.AppConfig.String("user_center_url") + loginMethod)
httpReq.JSONBody(request)
httpReq.Header("appKey", appKey)
httpReq.Header("curTime", curTime)
httpReq.Header("checkSum", getUserCenterCheckSum(curTime, "", appKey, salt))
if httpRsp, err = httpReq.DoRequest(); err != nil {
log.Error(err)
return
}
data, err = ioutil.ReadAll(httpRsp.Body)
defer httpRsp.Body.Close()
if err != nil {
log.Error(err)
return
}
log.Info(fmt.Sprintf("simnum:%v login user-center response:%v", request.Phone, string(data)))
type msg struct {
protocol.ErrorCode
Data *protocol.UserCenterLoginResponse `json:"data"`
}
var message protocol.Message
if err = json.Unmarshal(data, &message); err != nil {
log.Error(err)
return
}
if message.Errno == 0 && message.Errmsg == "ok" {
if err = message.Unmarshal(&rsp); err != nil {
log.Error(err)
return
}
} else {
err = fmt.Errorf("error_no:%v msg:%v", message.Errno, message.Errmsg)
}
return
}
func getUserCenterCheckSum(curTime, nonce, appKey, salt string) string {
sha1 := sha1.New()
sum := sha1.Sum([]byte(fmt.Sprintf("%s%s%s%s", curTime, nonce, appKey, salt)))
return hex.EncodeToString(sum)
}
... ...
package auth
import (
"gitlab.fjmaimaimai.com/mmm-go/gocomm/common"
"opp/internal/repository"
"testing"
... ... @@ -66,3 +67,16 @@ func Test_RefreshToken(t *testing.T) {
t.Fatal(err, rsp)
}
}
//测试用户中心登录
func Test_UserCenterAuthLogin(t *testing.T) {
if rsp, err := userCenterAuthLogin(&protocol.UserCenterLoginRequest{
Phone: "18065048301",
PassWord: "123456",
}); err != nil {
t.Log(err)
return
} else {
t.Log(common.AssertJson(rsp))
}
}
... ...
... ... @@ -211,7 +211,7 @@ func ChanceSubmit(header *protocol.RequestHeader, request *protocol.ChanceSubmit
)
//1.模板是否存在
if template, err = models.GetAuditTemplateById(request.AuditTemplateId); err != nil {
log.Error(err)
log.Error("模板不存在:", request.AuditTemplateId, err)
return
}
auditConfig = &protocol.AuditConfig{NoApprover: template.NoApprover}
... ...
... ... @@ -37,9 +37,8 @@ func Commend(header *protocol.RequestHeader, request *protocol.CommendRequest) (
Honored: protocol.BaseUserInfo{
UserId: c.UserId,
NickName: user.NickName,
//TODO:out index
Department: userBaseInfo.Department[0].Name,
Position: userBaseInfo.Position[0].Name,
Department: agg.GetTopDepartment(userBaseInfo.Department).Name,
Position: agg.GetTopPosition(userBaseInfo.Position).Name,
},
}
rsp.Lists = append(rsp.Lists, cInfo)
... ...
... ... @@ -27,7 +27,7 @@ func Init() {
beego.LoadAppConfig("ini", filepath.Join(path, "conf", filename))
log.InitLog(config.Logger{
Filename: "app.log",
Level: "3", //7
Level: "7", //7 单元test时 可以把级别设置低一点 减少日志
})
err := redis.InitWithDb(100, beego.AppConfig.String("redis_add_port"), beego.AppConfig.String("redis_auth"), "0")
if err != nil {
... ...