Browse Source

初始化

wangchuanjin 2 years ago
parent
commit
2fa7ce4bfc
5 changed files with 847 additions and 0 deletions
  1. 179 0
      jyutil/jyCms.go
  2. 230 0
      jyutil/jyutil.go
  3. 241 0
      jyutil/sessionEncryption.go
  4. 170 0
      jyutil/sessionkeep.go
  5. 27 0
      jyutil/sort.go

+ 179 - 0
jyutil/jyCms.go

@@ -0,0 +1,179 @@
+package jyutil
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"html/template"
+	"jy/src/jfw/config"
+	"regexp"
+	"strconv"
+	"time"
+
+	util "app.yhyue.com/moapp/jybase/common"
+	. "app.yhyue.com/moapp/jybase/date"
+	elastic "app.yhyue.com/moapp/jybase/esv1"
+	. "app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"app.yhyue.com/moapp/jypkg/public"
+)
+
+const (
+	jyMsgFirstCache     = "jyMsg_%s_%d"
+	jyMsgFirstCacheTime = 5 * 60
+)
+
+//GetFirstJyCms 获取首评信息
+func GetFirstJyCms(contentType string, size int) (r []map[string]interface{}) {
+	// 默认剑鱼博客栏目
+	contentType = util.If(contentType == "", "jybk", contentType).(string)
+	redisKey := fmt.Sprintf(jyMsgFirstCache, contentType, size)
+	if data, ok := redis.Get("other", redisKey).([]interface{}); ok && data != nil && len(data) > 0 {
+		r = util.ObjArrToMapArr(data)
+	} else {
+		rs, _ := JyCmsSearch(map[string]string{
+			"contentType": contentType,
+			"perPage":     fmt.Sprintf("%d", size),
+		})
+		if rs != nil {
+			for _, v := range *rs {
+				delete(v, "praise")
+				delete(v, "s_contenttype")
+				delete(v, "s_source")
+			}
+			r = *rs
+		}
+		redis.Put("other", redisKey, r, jyMsgFirstCacheTime)
+	}
+	return r
+}
+
+// JyCmsSearch 剑鱼文章检索
+func JyCmsSearch(query map[string]string) (*[]map[string]interface{}, *[]interface{}) {
+	perPage, _ := strconv.Atoi(query["perPage"])
+	currentPage, _ := strconv.Atoi(query["currentPage"])
+	//修复
+	if perPage == 0 {
+		perPage = 5
+	}
+	if currentPage < 1 {
+		currentPage = 1
+	}
+	contentType := query["contentType"]
+	queryStr := query["query"]
+
+	queryMap := map[string]interface{}{
+		"s_contenttype": contentType,
+	}
+
+	if queryStr != "" {
+		queryMap["$or"] = []interface{}{
+			map[string]interface{}{
+				"s_title": map[string]interface{}{"$regex": queryStr},
+			},
+			map[string]interface{}{
+				"s_content": map[string]interface{}{"$regex": queryStr},
+			},
+		}
+	}
+
+	total := public.MQFW.Count("content", queryMap)
+
+	//查询列表数据
+	client := elastic.GetEsConn()
+	defer elastic.DestoryEsConn(client)
+	if client == nil {
+		return nil, nil
+	}
+	searchResult, _ := public.MQFW.Find("content", queryMap, `{"releasetime":-1}`, `{"s_title":1,"s_contenttype":1,"s_content":1,"releasetime":1,"s_description":1,"praise":1,"s_source":1,"s_pic":1,"s_pic1":1,"l_createdate":1,"_id":1,"s_author":1}`, false, (currentPage-1)*perPage, perPage)
+
+	var res []map[string]interface{}
+	if searchResult != nil && len(*searchResult) > 0 {
+		for _, m := range *searchResult {
+			s_content, _ := m["s_content"].(string)
+			if len(s_content) > 500 {
+				m["s_content"] = ""
+			} else {
+				con, _ := regexp.Compile("^[^<]*?>")
+				content := con.ReplaceAllString(s_content, "")
+				con1, _ := regexp.Compile("<[^>]*$")
+				m["s_content"] = template.HTML(con1.ReplaceAllString(content, ""))
+			}
+
+			s_title, _ := m["s_title"].(string)
+			m["s_title"] = template.HTML(s_title)
+
+			tmpdate, _ := m["l_createdate"]
+			m["l_createdate"] = util.TimeDiff(time.Unix(util.Int64All(tmpdate), 0))
+			tmpdate1, _ := m["releasetime"]
+			m["releasetime"] = util.TimeDiff(time.Unix(util.Int64All(tmpdate1), 0))
+			reltime := time.Unix(util.Int64All(tmpdate1), 0)
+			m["time"] = reltime.Format(Date_Short_Layout) //首页展示
+			s_pic, _ := m["s_pic"].(string)
+			if s_pic != "" {
+				s_pic = config.Seoconfig["jyadd"].(string) + s_pic
+			}
+			m["s_pic"] = s_pic
+			s_pic1, _ := m["s_pic1"].(string)
+			if s_pic1 != "" {
+				s_pic1 = config.Seoconfig["jyadd"].(string) + s_pic1
+			}
+			m["s_pic1"] = s_pic1
+			m["_id"] = se.EncodeString(BsonIdToSId(m["_id"]))
+			res = append(res, m)
+		}
+	}
+	//生成分页
+	pagination := MakePagination(perPage, currentPage, int(total), query, "/jyblog/index_%s.html")
+	return &res, &pagination
+}
+
+//计算分页,分页显示规则
+func MakePagination(perPage, currentPage, total int, param map[string]string, urltpl string) []interface{} {
+	var totalPages int //总页数
+	if total == 0 {
+		totalPages = 1
+	} else {
+		totalPages = (total - 1 + perPage) / perPage //总页数
+	}
+
+	ret := make([]interface{}, 3)
+	index := 0
+	prePage, nextPage := currentPage-1, currentPage+1
+	if prePage < 1 {
+		prePage = 1
+	}
+	if nextPage > totalPages {
+		nextPage = totalPages
+	}
+	param["currentPage"] = strconv.Itoa(prePage)
+	bs, _ := json.Marshal(param)
+	paramstr := base64.StdEncoding.EncodeToString(bs)
+	url := fmt.Sprintf(urltpl, paramstr)
+	iscurrent := currentPage == 1
+	ret[index] = map[string]interface{}{"page": "< 上一页", "url": url, "iscurrent": iscurrent}
+	index = index + 1
+	param["currentPage"] = strconv.Itoa(currentPage)
+	bs, _ = json.Marshal(param)
+	paramstr = base64.StdEncoding.EncodeToString(bs)
+	url = fmt.Sprintf(urltpl, paramstr)
+	iscurrent = currentPage == currentPage
+	ret[index] = map[string]interface{}{"page": currentPage, "url": url, "iscurrent": iscurrent}
+	index = index + 1
+	param["currentPage"] = strconv.Itoa(nextPage)
+	bs, _ = json.Marshal(param)
+	paramstr = base64.StdEncoding.EncodeToString(bs)
+	url = fmt.Sprintf(urltpl, paramstr)
+	iscurrent = currentPage == totalPages
+	ret[index] = map[string]interface{}{"page": "下一页 >", "url": url, "iscurrent": iscurrent}
+
+	//
+	u := map[string]interface{}{
+		"currentPage": 1,
+		"query":       "招标",
+		"contentType": param["contentType"],
+	}
+	bs, _ = json.Marshal(u)
+	paramstr = base64.StdEncoding.EncodeToString(bs)
+	return ret
+}

+ 230 - 0
jyutil/jyutil.go

@@ -0,0 +1,230 @@
+package jyutil
+
+import (
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"jy/src/jfw/config"
+	"log"
+	"net/http"
+	"reflect"
+	"regexp"
+	"sort"
+
+	"app.yhyue.com/moapp/jypkg/public"
+
+	util "app.yhyue.com/moapp/jybase/common"
+	"app.yhyue.com/moapp/jybase/encrypt"
+	. "app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jybase/redis"
+
+	"strings"
+	"time"
+)
+
+var mongodb = public.MQFW
+var se = &encrypt.SimpleEncrypt{Key: "topnet2015topnet2015"}
+
+var AC = &encrypt.AES_CBC{
+	Key: "mGlAgnIBB8bx2nch",
+	Iv:  "1389461544135476",
+}
+
+//
+func FindMyShareId(activecode, openid string) string {
+	defer util.Catch()
+	ret, bres := mongodb.Find("person_share", "{'s_openid':'"+openid+"','s_businesscode':'"+activecode+"'}", `{"l_timestamp":-1}`, nil, true, -1, -1)
+	var shareid string
+	if bres {
+		var shareData = make(map[string]interface{})
+		var str = ""
+		for _, v := range *ret {
+			str = util.ObjToString(v["i_shareid"])
+		}
+		var tt = `^\d+$`
+		a, _ := regexp.Compile(tt)
+		if str == "" || a.MatchString(str) {
+			data := make(map[string]interface{})
+			data["s_openid"] = openid
+			data["s_businesscode"] = activecode
+			data["i_shareid"] = se.EncodeString(openid + "---" + activecode)
+			data["l_timestamp"] = time.Now().Unix()
+			mongodb.Save("person_share", data)
+			shareid = openid + "---" + activecode
+		} else {
+			shareid = se.DecodeString(str)
+		}
+		odata := redis.Get("sso", "p_shareData_"+shareid)
+		if odata == nil {
+			shareData["action"] = "32"
+			redis.Put("sso", "p_shareData_"+shareid, shareData, 24*60*60)
+		}
+	}
+	return shareid
+}
+
+//获取用户openid
+func Getopenid(code string) (openid string) {
+	defer util.Catch()
+	recturl := fmt.Sprintf(config.Wxoauthinfo, code)
+	resp, err := http.Get(recturl)
+	if err != nil {
+		log.Println(err.Error())
+		return
+	}
+	defer resp.Body.Close()
+	bs, _ := ioutil.ReadAll(resp.Body)
+	data := map[string]interface{}{}
+	json.Unmarshal(bs, &data)
+	openid, _ = data["openid"].(string)
+	return
+}
+
+//
+func GetSessionVal(q map[string]interface{}) (*map[string]interface{}, map[string]interface{}) {
+	person, ok := public.MQFW.FindOneByField("user", q, `{"_id":1,"i_shareknow":1,"s_m_openid":1,"s_nickname":1,"s_headimage":1,"s_headimageurl":1,"s_phone":1,"s_m_phone":1,"l_registedate":1,"b_merge_remind":1,"i_ispush":1,"i_unlimited":1,"s_jyname":1,"base_user_id":1}`)
+	sessionVal := make(map[string]interface{})
+	if !ok || person == nil || len(*person) == 0 {
+		return nil, sessionVal
+	}
+	sessionVal["user"] = *person
+	if (*person)["i_shareknow"] != nil {
+		sessionVal["shareknow"] = (*person)["i_shareknow"]
+	}
+	sessionVal["userId"] = BsonIdToSId((*person)["_id"])
+	nickName, _ := (*person)["s_nickname"].(string)
+	phone := util.ObjToString((*person)["s_phone"])
+	if nickName == "" {
+		if phone != "" && len(phone) > 3 {
+			nickName = string(phone[0:3]) + "****" + string(phone[len(phone)-4:])
+		}
+	}
+	if util.ObjToString((*person)["s_jyname"]) != "" {
+		sessionVal["s_jyname"] = util.ObjToString((*person)["s_jyname"])
+	}
+	sessionVal["s_nickname"] = nickName
+	sessionVal["nickname"] = nickName
+	avatar, _ := (*person)["s_headimageurl"].(string)
+	if avatar == "" {
+		avatar, _ = (*person)["s_headimage"].(string)
+	}
+	sessionVal["s_avatar"] = strings.Replace(avatar, "http://", "https://", 1)
+	sessionVal["s_m_openid"], _ = (*person)["s_m_openid"].(string)
+	sessionVal["openid"] = sessionVal["s_m_openid"]
+	if phone == "" {
+		phone = util.ObjToString((*person)["s_m_phone"])
+	}
+	if phone != "" {
+		//企业信息存session
+		sql := `SELECT a.id,a.name,a.startdate,a.enddate,a.quota,c.id as dept_id,b.id as user_id from entniche_info a 
+			INNER JOIN entniche_user b on (b.phone=? and a.id=b.ent_id) 
+			INNER JOIN entniche_department c on (c.pid=0 and a.id=c.ent_id) 
+			LEFT JOIN entniche_user_role d on (d.role_id=? and b.id=d.user_id)  
+			order by a.status DESC,b.power desc,a.auth_status DESC,d.role_id desc,a.createtime desc`
+		list := public.Mysql.SelectBySql(sql, phone, 1)
+		if list != nil {
+			for _, v := range *list {
+				if util.IntAll(v["id"]) == 0 {
+					break
+				}
+				sessionVal["entId"] = util.IntAll(v["id"])
+				sessionVal["entName"] = util.ObjToString(v["name"])
+				sessionVal["entUserId"] = util.IntAll(v["user_id"])
+				sessionVal["frameworkEntId"] = util.IntAll(v["id"])
+				sessionVal["frameworkEntName"] = util.ObjToString(v["name"])
+				break
+			}
+		}
+	}
+	sessionVal["phone"] = phone
+	sessionVal["i_unlimited"] = util.IntAll((*person)["i_unlimited"])
+	base_uid := util.IntAllDef((*person)["base_user_id"], 0)
+	if base_uid != 0 {
+		sessionVal["base_user_id"] = base_uid //用户中台的uid
+	}
+	return person, sessionVal
+}
+
+//value 用户sessionid
+func LoginRedisKey(userid string) string {
+	return fmt.Sprintf("login_%s", userid)
+}
+
+// 排序 排序键必须为数字类型
+type SortBy struct {
+	Data    []map[string]interface{}
+	Sortkey string
+}
+
+func (a SortBy) Len() int { return len(a.Data) }
+
+func (a SortBy) Swap(i, j int) {
+	a.Data[i], a.Data[j] = a.Data[j], a.Data[i]
+}
+
+func (a SortBy) Less(i, j int) bool {
+	//return Float64(a.Data[i][a.Sortkey]) < Float64(a.Data[j][a.Sortkey])
+	m := a.Data[i][a.Sortkey]
+	n := a.Data[j][a.Sortkey]
+	w := reflect.ValueOf(m)
+	v := reflect.ValueOf(n)
+	switch v.Kind() {
+	case reflect.String:
+		return w.String() < v.String()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return w.Int() < v.Int()
+	case reflect.Float64, reflect.Float32:
+		return w.Float() < v.Float()
+	default:
+		return fmt.Sprintf("%v", w) < fmt.Sprintf("%v", v)
+	}
+}
+
+// ture  倒序3, 2, 1
+//fmt.Println(m)
+func SortData(data interface{}, sortkey string, reverse bool) {
+	//func SortData(data interface{}, sortkey string, reverse bool) {
+	var db []map[string]interface{}
+	err := Bind(data, &db)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	stb := SortBy{db, sortkey}
+	if !reverse {
+		sort.Sort(stb)
+	} else {
+		sort.Sort(sort.Reverse(stb))
+	}
+	err = Bind(stb.Data, data)
+	if err != nil {
+		fmt.Println(err)
+	}
+
+}
+
+// data 转换成ret
+func Bind(data interface{}, ret interface{}) error {
+	v := reflect.ValueOf(ret)
+	if v.Kind() != reflect.Ptr {
+		return fmt.Errorf("ptr input ret needed as type as input type %s", v.Kind())
+	}
+	havdata := false
+	var bk interface{}
+	if v.Elem().Kind() == reflect.Slice {
+		t := reflect.Zero(reflect.TypeOf(v.Elem().Interface()))
+		bk = v.Elem().Interface()
+		v.Elem().Set(t)
+		havdata = true
+	}
+	_data, _ := json.MarshalIndent(data, "", "    ")
+	err := json.Unmarshal(_data, ret)
+	if err != nil {
+		fmt.Println(err)
+		if havdata {
+			v.Elem().Set(reflect.ValueOf(bk))
+		}
+		return err
+	}
+	return nil
+}

+ 241 - 0
jyutil/sessionEncryption.go

@@ -0,0 +1,241 @@
+package jyutil
+
+import (
+	"bytes"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/json"
+	"encoding/pem"
+	"jy/src/jfw/config"
+	"jy/src/jfw/nodemgr"
+	"log"
+	"sync"
+	"time"
+
+	util "app.yhyue.com/moapp/jybase/common"
+	. "app.yhyue.com/moapp/jybase/date"
+	"app.yhyue.com/moapp/jybase/redis"
+	"github.com/robfig/cron/v3"
+)
+
+//
+type RsaStruct struct {
+	Sign       string
+	PrivateKey *rsa.PrivateKey
+	PublicKey  *rsa.PublicKey
+	RsaConfig  *RsaConfig
+}
+
+type RsaConfig struct {
+	RsaSignflag   string
+	PrivateKeyStr string
+	PublicKeyStr  string
+}
+
+type MyWrite struct {
+	Byte *bytes.Buffer
+}
+
+func (m MyWrite) Write(p []byte) (n int, err error) {
+	n, err = m.Byte.Write(p)
+	return
+}
+
+func getNewRsaConfig() *RsaConfig {
+	//私钥-----
+	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
+	if err != nil {
+		log.Println(err)
+	}
+	X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
+	privateBlock := pem.Block{Type: "RSA Private Key", Bytes: X509PrivateKey}
+	privateWrite := MyWrite{Byte: bytes.NewBuffer([]byte(""))}
+	pem.Encode(privateWrite, &privateBlock)
+	privateKeyByte := privateWrite.Byte.Bytes()
+
+	//公钥----
+	publicKey := privateKey.PublicKey
+	X509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
+	if err != nil {
+		log.Println(err)
+	}
+	publicBlock := pem.Block{Type: "RSA Public Key", Bytes: X509PublicKey}
+	publicWrite := MyWrite{Byte: bytes.NewBuffer([]byte(""))}
+	pem.Encode(publicWrite, &publicBlock)
+	publicKeyByte := publicWrite.Byte.Bytes()
+
+	return &RsaConfig{
+		RsaSignflag:   time.Now().Format(Date_Full_Layout),
+		PrivateKeyStr: string(privateKeyByte),
+		PublicKeyStr:  string(publicKeyByte),
+	}
+}
+
+func initRsa(config *RsaConfig) *RsaStruct {
+	//初始化私钥
+	private_block, _ := pem.Decode([]byte(config.PrivateKeyStr))
+	private, err := x509.ParsePKCS1PrivateKey(private_block.Bytes)
+	if err != nil {
+		log.Println(err)
+	}
+	//初始化公钥
+	public_block, _ := pem.Decode([]byte(config.PublicKeyStr))
+	publicKeyInterface, err := x509.ParsePKIXPublicKey(public_block.Bytes)
+	if err != nil {
+		log.Println(err)
+	}
+	public := publicKeyInterface.(*rsa.PublicKey)
+	return &RsaStruct{
+		Sign:       config.RsaSignflag,
+		RsaConfig:  config,
+		PrivateKey: private,
+		PublicKey:  public,
+	}
+}
+
+//加密
+func (r *RsaStruct) Encrypt(str string) string {
+	enStrByte, err := rsa.EncryptPKCS1v15(rand.Reader, r.PublicKey, []byte(str))
+	if err != nil {
+		log.Printf("%s加密失败%v", str, err)
+	}
+	return string(enStrByte)
+}
+
+//解密
+func (r *RsaStruct) Decrypt(enStr string) string {
+	deStrByte, err := rsa.DecryptPKCS1v15(rand.Reader, r.PrivateKey, []byte(enStr))
+	if err != nil {
+		log.Printf("%s解密失败%v", enStr, err)
+	}
+	return string(deStrByte)
+}
+
+type EncryptionStruct struct {
+	RsaStruct_Now  *RsaStruct
+	MapRsa         map[string]*RsaStruct
+	EncryptionConf *EncryptionConf
+	Lock           *sync.Mutex
+}
+
+type EncryptionConf struct {
+	Now        string
+	MapRsaConf map[string]*RsaConfig
+}
+
+//首次启动加载秘钥
+func InitEncryptionStruct() *EncryptionStruct {
+	encryStruct := EncryptionStruct{EncryptionConf: &EncryptionConf{}, Lock: &sync.Mutex{}}
+	//	log.Println("xxxxxx", redis.GetInt("other", "jynode_"+nodemgr.NodeName))
+	//	isMaster := util.If(redis.GetInt("other", "jynode_"+nodemgr.NodeName) == 1, true, false).(bool)
+	go func() {
+		cn := cron.New()
+		str := util.ObjToString(config.Sysconfig["sessionEnctryFlushCorn"])
+		cn.AddFunc(str, func() {
+			encryStruct.Flush()
+		})
+		cn.Start()
+	}()
+
+	//for {
+	redis_obj := util.ObjToString(redis.Get("session", "sessionEncryption"))
+	if redis_obj != "" {
+		encryconf := EncryptionConf{}
+		err := json.Unmarshal([]byte(redis_obj), &encryconf)
+		if err != nil {
+			log.Println("InitEncryptionStruct Unmarshal redis err", err)
+		} else {
+			encryStruct.EncryptionConf = &encryconf
+			encryStruct.initAllRsa()
+			log.Println("从redis中加载EncryptionStruct")
+			return &encryStruct
+		}
+	}
+
+	log.Println("主结点首次创建EncryptionStruct")
+	newRsaConf := getNewRsaConfig()
+	encryStruct.EncryptionConf.Now = newRsaConf.RsaSignflag
+	encryStruct.EncryptionConf.MapRsaConf = map[string]*RsaConfig{newRsaConf.RsaSignflag: newRsaConf}
+	encryStruct.initAllRsa()
+	go func() {
+		//存入redis
+		byteArr, err := json.Marshal(encryStruct.EncryptionConf)
+		log.Println(string(byteArr))
+		if err != nil {
+			log.Printf("InitEncryptionStruct save %s redis err %:v\n", byteArr, err)
+			return
+		}
+		redis.Put("session", "sessionEncryption", string(byteArr), -1)
+	}()
+	return &encryStruct
+}
+
+func (e *EncryptionStruct) initAllRsa() {
+	e.Lock.Lock()
+	defer e.Lock.Unlock()
+	e.MapRsa = map[string]*RsaStruct{}
+	for k, v := range e.EncryptionConf.MapRsaConf {
+		thisRsa := initRsa(v)
+		e.MapRsa[k] = thisRsa
+		if k == e.EncryptionConf.Now {
+			e.RsaStruct_Now = thisRsa
+		}
+	}
+}
+
+//定时更新秘钥
+func (e *EncryptionStruct) Flush() {
+	isMaster := util.If(redis.GetInt("other", "jynode_"+nodemgr.NodeName) == 1, true, false).(bool)
+	if !isMaster {
+		//从节点从redis中更新秘钥
+		for {
+			redis_obj := util.ObjToString(redis.Get("session", "sessionEncryption"))
+			if redis_obj != "" {
+				encryconf := EncryptionConf{}
+				err := json.Unmarshal([]byte(redis_obj), &encryconf)
+				if e.RsaStruct_Now.Sign == encryconf.Now {
+					log.Println("从节点定时更新EncryptionStruct失败,一分钟后重试", e.RsaStruct_Now.Sign)
+					time.Sleep(time.Minute)
+					if redis.GetInt("other", "jynode_"+nodemgr.NodeName) == 1 {
+						break
+					} else {
+						continue
+					}
+				}
+				if err != nil {
+					log.Println("InitEncryptionStruct Unmarshal redis err", err)
+				} else {
+					e.EncryptionConf = &encryconf
+					e.initAllRsa()
+					log.Println("从节点定时更新EncryptionStruct")
+					return
+				}
+			}
+		}
+	} else {
+		e.Lock.Lock()
+		//主结点生成秘钥 存入redis
+		log.Printf("主结点更新EncryptionStruct before  %+v", e.MapRsa)
+		last := e.RsaStruct_Now
+		newRsa := initRsa(getNewRsaConfig())
+		//更新map
+		e.MapRsa = map[string]*RsaStruct{newRsa.Sign: newRsa, last.Sign: last}
+		//更新默认加密
+		e.RsaStruct_Now = newRsa
+		log.Printf("after  %+v", e.MapRsa)
+		e.Lock.Unlock()
+		//更新redis
+		func() {
+			e.EncryptionConf.Now = e.RsaStruct_Now.Sign
+			e.EncryptionConf.MapRsaConf = map[string]*RsaConfig{newRsa.Sign: newRsa.RsaConfig, last.Sign: last.RsaConfig}
+			byteArr, err := json.Marshal(e.EncryptionConf)
+			log.Println("主结点更新sessionEncryption", string(byteArr))
+			if err != nil {
+				log.Printf("InitEncryptionStruct save %s redis err %:v\n", byteArr, err)
+				return
+			}
+			redis.Put("session", "sessionEncryption", string(byteArr), -1)
+		}()
+	}
+}

+ 170 - 0
jyutil/sessionkeep.go

@@ -0,0 +1,170 @@
+package jyutil
+
+import (
+	"encoding/base64"
+	"fmt"
+	"net/http"
+	"regexp"
+	"strings"
+	"time"
+
+	"app.yhyue.com/moapp/jybase/redis"
+
+	. "app.yhyue.com/moapp/jybase/mongodb"
+
+	"app.yhyue.com/moapp/jybase/go-xweb/httpsession"
+)
+
+const (
+	SKCookieName = "userid_secure"
+)
+
+var (
+	Encryption = InitEncryptionStruct()
+	//过滤器
+	//爬虫百度、谷歌、雅虎、新浪、搜狗、搜搜、网易有道
+	//var reg = regexp.MustCompile(`(baidu|google|yahoo|iask|sogou|soso|youdao|Android|Mobile)`)
+	reg = regexp.MustCompile(`(Android|Mobile)`)
+)
+
+// SessionKeep session保持
+type SessionKeep struct {
+	W          http.ResponseWriter
+	R          *http.Request
+	Session    *httpsession.Session
+	GetSession map[string]interface{}
+	SetSession map[string]interface{}
+}
+
+func (sk *SessionKeep) Do() bool {
+	defer func() {
+		if len(sk.SetSession) > 0 {
+			sk.Session.SetMultiple(sk.SetSession)
+		}
+	}()
+	rqu := sk.R.URL.Path
+	if strings.HasSuffix(rqu, "/notin/page") || strings.HasSuffix(rqu, "/swordfish/about") || strings.HasSuffix(rqu, "/orgstructure/invpage") || strings.Contains(rqu, "/exhibition/") {
+		return true
+	} else {
+		rhd := sk.R.Header
+		rhdua := "" //UA
+		if len(rhd["User-Agent"]) > 0 {
+			rhdua = rhd["User-Agent"][0]
+		}
+		ck, err := sk.R.Cookie(SKCookieName)
+		userid := sk.GetSession["userId"]
+		enuserid := ""
+		rhost := sk.R.Host
+		RURL := "" //当前url
+		sk.SetSession["User-Agent"] = rhdua
+		//当前页 模块
+		if strings.HasSuffix(rqu, ".html") {
+			RURL = fmt.Sprintf("%s%s%s", "https://", rhost, sk.R.RequestURI)
+			sk.SetSession["RURL"] = RURL
+		}
+		deuserid := ""
+		flag := 0
+		if userid != nil && userid != "" { //只有有session,就更新cookie失效时间
+			deuserid, _ = userid.(string)
+			enuserid = sk.EncodeString(deuserid)
+			flag = 1
+		} else if err == nil {
+			enuserid = ck.Value //"解密的userid"
+			deuserid = sk.DecodeString(enuserid)
+			flag = 2
+		}
+		if deuserid != "" {
+			b, _ := redis.Exists("sso", "req_"+deuserid)
+			if b {
+				http.Redirect(sk.W, sk.R, "/not/not", 302)
+			} else {
+				if flag == 2 {
+					_, sessionVal := GetSessionVal(map[string]interface{}{"_id": StringTOBsonId(deuserid)})
+					//未登陆账号
+					if i_unlimited, ok := sessionVal["i_unlimited"].(int); i_unlimited > 0 && ok {
+						http.SetCookie(sk.W, sk.cookie("", SKCookieName))
+						http.Redirect(sk.W, sk.R, "/", 302)
+						return false
+					}
+					for k, v := range sessionVal {
+						sk.SetSession[k] = v
+					}
+				}
+				http.SetCookie(sk.W, sk.cookie(enuserid, SKCookieName))
+				http.SetCookie(sk.W, sk.cookie(se.EncodeString(deuserid), "ud_safe"))
+			}
+		} else {
+			if strings.HasPrefix(rqu, "/article/") {
+				if strings.HasPrefix(rqu, "/article/mailprivate") || strings.HasPrefix(rqu, "/article/bdprivate") || strings.HasPrefix(rqu, "/article/bdcontent") || reg.MatchString(rhdua) || strings.HasPrefix(rqu, "/article/indexcontent") {
+					return true
+				} else { //只处理pc
+					sk.SetSession["referer"] = sk.R.RequestURI
+					http.Redirect(sk.W, sk.R, "/notin/page", 302)
+					return false
+				}
+			} else if strings.HasPrefix(rqu, "/front/dataExport") || strings.HasPrefix(rqu, "/front/dataPack") {
+				//数据预览图片导出,需要去掉session拦截
+				sk.SetSession["referer"] = sk.R.RequestURI
+				http.Redirect(sk.W, sk.R, "/notin/page", 302)
+				return false
+			} else if strings.HasPrefix(rqu, "/front/dataReport") {
+				if rqu == "/front/dataReport/payCallback" {
+					return true
+				}
+				http.Redirect(sk.W, sk.R, "/", 302)
+				return false
+			} else if strings.HasPrefix(rqu, "/front/vipsubscribe/") {
+				http.Redirect(sk.W, sk.R, "/swordfish/about", 302)
+				//查找不到此用户信息,(用户合并微信登录防止跳转)
+				return true
+			}
+		}
+	}
+	return true
+}
+
+// 生成cookie
+func (sk *SessionKeep) cookie(userid, keyname string) *http.Cookie {
+	maxAge := int(time.Hour * 72 / time.Second) //3天,单位秒
+	expires := time.Now().Add(72 * time.Hour)
+	cookie := &http.Cookie{
+		Name:     keyname,
+		Value:    userid,
+		Path:     "/",
+		HttpOnly: false,
+		MaxAge:   maxAge,
+		Expires:  expires,
+		Domain:   httpsession.Domain,
+	}
+	return cookie
+}
+
+// DecodeString 解密
+func (sk *SessionKeep) DecodeString(encodeStr string) string {
+	byteArr, err := base64.StdEncoding.DecodeString(encodeStr)
+	if err != nil {
+		fmt.Println("base64解密出错", encodeStr)
+		return ""
+	}
+	//获取加密字段和加密标识
+	ctxArr := strings.Split(string(byteArr), "***")
+	if len(ctxArr) != 2 {
+		return ""
+	}
+
+	enuserid := ctxArr[0]
+	signFlsg := ctxArr[1]
+	rs := Encryption.MapRsa[signFlsg]
+	if rs == nil {
+		fmt.Printf("sign %s不存在\n", signFlsg)
+		return ""
+	}
+	str := Encryption.MapRsa[signFlsg].Decrypt(enuserid)
+	return str
+}
+
+// EncodeString 加密
+func (sk *SessionKeep) EncodeString(userid string) string {
+	str := Encryption.RsaStruct_Now.Encrypt(userid) + "***" + Encryption.RsaStruct_Now.Sign
+	return base64.StdEncoding.EncodeToString([]byte(str))
+}

+ 27 - 0
jyutil/sort.go

@@ -0,0 +1,27 @@
+// sort
+package jyutil
+
+type ObjectMap struct {
+	Key string `json:"key"` //
+	Num int    `json:"num"` //
+
+}
+type ObjSort []*ObjectMap
+
+func (list ObjSort) Len() int {
+	return len(list)
+}
+
+func (list ObjSort) Less(i, j int) bool {
+	if list[i].Num > list[j].Num {
+		return true
+	} else {
+		return false
+	}
+}
+
+func (list ObjSort) Swap(i, j int) {
+	var temp *ObjectMap = list[i]
+	list[i] = list[j]
+	list[j] = temp
+}