|
@@ -0,0 +1,469 @@
|
|
|
+package front
|
|
|
+
|
|
|
+import (
|
|
|
+ "github.com/go-xweb/xweb"
|
|
|
+ "qfw/util"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+ "log"
|
|
|
+ "github.com/go-xweb/httpsession"
|
|
|
+ "jfw/jyutil"
|
|
|
+ "fmt"
|
|
|
+ "qfw/util/redis"
|
|
|
+ "net/url"
|
|
|
+ "encoding/base64"
|
|
|
+ "jfw/config"
|
|
|
+)
|
|
|
+
|
|
|
+type PcHelper struct {
|
|
|
+ *xweb.Action
|
|
|
+ login xweb.Mapper `xweb:"/jypc/login"` //pc助手登录
|
|
|
+ getWxUT xweb.Mapper `xweb:"/jcpc/getWxUT"` //微信登录后token
|
|
|
+ getSubscribeToken xweb.Mapper `xweb:"/jypc/getST"` //获取订阅记录token
|
|
|
+ pushView xweb.Mapper `xweb:"/jypc/pushView"` //订阅记录列表
|
|
|
+ logout xweb.Mapper `xweb:"/jypc/logout"` //退出登录
|
|
|
+ needUpdate xweb.Mapper `xweb:"/jypc/needUpdate"` //是否需要更新pc助手
|
|
|
+ toAct xweb.Mapper `xweb:"/jypc/toAct/([^.]*)"` //
|
|
|
+ toPushView xweb.Mapper `xweb:"/jypc/toPushView"` //跳转到订阅记录页面
|
|
|
+ toSearch xweb.Mapper `xweb:"/jypc/toSearch"` //跳转到招标搜索页面
|
|
|
+}
|
|
|
+
|
|
|
+func init() {
|
|
|
+ xweb.AddAction(&PcHelper{})
|
|
|
+}
|
|
|
+
|
|
|
+var (
|
|
|
+ redisKeyPrefix_PPVOpenid = "pc_push_view_openid_"
|
|
|
+ redisPool = "other"
|
|
|
+ pcHelperConfig = config.Sysconfig["pcHelper"].(map[string]interface{})
|
|
|
+ timeout = int(pcHelperConfig["subscribeTokenTimeout"].(float64))
|
|
|
+ version = pcHelperConfig["version"].(string)
|
|
|
+ redisKey_pcOpenid = "pc_s_m_openid"
|
|
|
+ othSep = "____"
|
|
|
+ md5EncryptSep = "&"
|
|
|
+ logPrefix = "PcHelper"
|
|
|
+)
|
|
|
+
|
|
|
+func (l *PcHelper) NeedUpdate() error {
|
|
|
+ defer util.Catch()
|
|
|
+ versionP := l.GetString("version")
|
|
|
+ updateFlag := false //不需要更新
|
|
|
+ if versionP != "" && versionP != version {
|
|
|
+ updateFlag = true
|
|
|
+ }
|
|
|
+ result := map[string]interface{}{
|
|
|
+ "needUpdate": updateFlag,
|
|
|
+ "version": version,
|
|
|
+ }
|
|
|
+ l.ServeJson(result)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) Login() error {
|
|
|
+ defer util.Catch()
|
|
|
+ //登录页面
|
|
|
+ //if l.Method() == "GET" {
|
|
|
+ // return l.Render("/pchelper/login.html", nil)
|
|
|
+ //}
|
|
|
+ mac := l.GetString("mac")
|
|
|
+ if mac == "" {
|
|
|
+ return l.Render("/pchelper/login.html", nil)
|
|
|
+ }
|
|
|
+ reToken := ""
|
|
|
+ reOpenId := ""
|
|
|
+ reNickname := ""
|
|
|
+ status := func() int {
|
|
|
+ reqType := l.GetString("reqType")
|
|
|
+ if reqType == "phoneLogin" {
|
|
|
+ phone := l.GetString("phone")
|
|
|
+ password := l.GetString("password")
|
|
|
+ if strings.TrimSpace(phone) == "" || strings.TrimSpace(password) == "" {
|
|
|
+ return -1
|
|
|
+ }
|
|
|
+ query := map[string]interface{}{
|
|
|
+ "i_appid": 2,
|
|
|
+ "s_m_openid": phone,
|
|
|
+ "i_type": 1, //app用户(手机号注册用户)
|
|
|
+ "s_password": util.GetMd5String(password),
|
|
|
+ }
|
|
|
+ user, ok := mongodb.FindOne("user", query)
|
|
|
+ //登录成功
|
|
|
+ if ok && user != nil && len(*user) > 0 {
|
|
|
+ if (*user)["s_m_openid"] != nil {
|
|
|
+ reOpenId = (*user)["s_m_openid"].(string)
|
|
|
+ }
|
|
|
+ if (*user)["s_nickname"] != nil {
|
|
|
+ reNickname = (*user)["s_nickname"].(string)
|
|
|
+ } else if (*user)["s_phone"] != nil {
|
|
|
+ reNickname = (*user)["s_phone"].(string)
|
|
|
+ }
|
|
|
+ reToken = getUToken(mac, phone)
|
|
|
+ return 1
|
|
|
+ }
|
|
|
+ return -1 //用户名或密码不正确
|
|
|
+ } else if reqType == "identCodeLogin" {
|
|
|
+ phone, _ := l.GetSession("identCodeKey").(string)
|
|
|
+ if phone == "" || l.GetSession("identCodeValue") == nil || l.GetString("identCode") != l.GetSession("identCodeValue") { //验证码不正确
|
|
|
+ return -1
|
|
|
+ } else {
|
|
|
+ query := map[string]interface{}{
|
|
|
+ "i_appid": 2,
|
|
|
+ "s_m_openid": phone,
|
|
|
+ "i_type": 1,
|
|
|
+ }
|
|
|
+ user, ok := mongodb.FindOne("user", query)
|
|
|
+ if ok {
|
|
|
+ //用户不存在
|
|
|
+ if user == nil || len(*user) == 0 {
|
|
|
+ data := map[string]interface{}{
|
|
|
+ "i_source": 1, //pc助手注册 add 20181119
|
|
|
+ "i_type": 1, //手机注册
|
|
|
+ "i_appid": 2,
|
|
|
+ "i_ispush": 1,
|
|
|
+ "s_m_openid": phone,
|
|
|
+ "s_unionid": phone,
|
|
|
+ "s_phone": phone,
|
|
|
+ "s_password": "",
|
|
|
+ "l_registedate": time.Now().Unix(),
|
|
|
+ "i_ts_guide": 2,
|
|
|
+ "o_jy": map[string]interface{}{
|
|
|
+ "i_mode": 1,
|
|
|
+ "i_ratemode": 2,
|
|
|
+ "l_modifydate": time.Now().Unix(),
|
|
|
+ },
|
|
|
+ "o_log": reqPhoneInfo(l.Request),
|
|
|
+ }
|
|
|
+ _id := mongodb.Save("user", data)
|
|
|
+ if _id != "" {
|
|
|
+ deleteIdentSession_(l.Session())
|
|
|
+ reToken = getUToken(mac, phone)
|
|
|
+ reOpenId = phone
|
|
|
+ reNickname = phone
|
|
|
+ return 1
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ deleteIdentSession_(l.Session())
|
|
|
+ if (*user)["s_m_openid"] != nil {
|
|
|
+ reOpenId = (*user)["s_m_openid"].(string)
|
|
|
+ }
|
|
|
+ if (*user)["s_nickname"] != nil {
|
|
|
+ reNickname = (*user)["s_nickname"].(string)
|
|
|
+ } else if (*user)["s_phone"] != nil {
|
|
|
+ reNickname = (*user)["s_phone"].(string)
|
|
|
+ }
|
|
|
+ reToken = getUToken(mac, phone)
|
|
|
+ return 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if reqType == "sendIdentCode" {
|
|
|
+ //phone := jyutil.CheckSendMsg(l.GetString("token"))
|
|
|
+ phone := l.GetString("phone")
|
|
|
+ //手机号验证不通过
|
|
|
+
|
|
|
+ if phone == "" {
|
|
|
+ return -2
|
|
|
+ } else if !phoneReg.MatchString(phone) {
|
|
|
+ return -1
|
|
|
+ } else if SendIdentCode(phone, l.Session()) {
|
|
|
+ return 1
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+ } else if reqType == "autoLogin" {
|
|
|
+ token := l.GetString("token")
|
|
|
+ deMac, phone := decryptUToken(token)
|
|
|
+ if phone != "" && mac == deMac {
|
|
|
+ query := map[string]interface{}{
|
|
|
+ "i_appid": 2,
|
|
|
+ "s_m_openid": phone,
|
|
|
+ }
|
|
|
+ user, ok := mongodb.FindOne("user", query)
|
|
|
+ if ok && user != nil && len(*user) > 0 {
|
|
|
+ if (*user)["s_m_openid"] != nil {
|
|
|
+ reOpenId = (*user)["s_m_openid"].(string)
|
|
|
+ }
|
|
|
+ if (*user)["s_nickname"] != nil {
|
|
|
+ reNickname = (*user)["s_nickname"].(string)
|
|
|
+ } else if (*user)["s_phone"] != nil {
|
|
|
+ reNickname = (*user)["s_phone"].(string)
|
|
|
+ }
|
|
|
+ reToken = getUToken(mac, phone)
|
|
|
+ return 1
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return -1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+ }()
|
|
|
+
|
|
|
+ result := map[string]interface{}{
|
|
|
+ "status": status,
|
|
|
+ }
|
|
|
+ if status == 1 {
|
|
|
+ result["token"] = reToken
|
|
|
+ }
|
|
|
+ result["openid"] = se.EncodeString(reOpenId)
|
|
|
+ result["nickname"] = reNickname
|
|
|
+ l.ServeJson(result)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) Logout() {
|
|
|
+ defer util.Catch()
|
|
|
+ //wx-login
|
|
|
+ l.DelSession("nickname")
|
|
|
+ l.DelSession("s_nickname")
|
|
|
+ l.DelSession("s_m_openid")
|
|
|
+ l.DelSession("user")
|
|
|
+ l.DelSession("rpcBackUserInfo")
|
|
|
+ //pcHelper-login
|
|
|
+ l.DelSession(redisKey_pcOpenid)
|
|
|
+ deleteIdentSession_(l.Session())
|
|
|
+ l.ServeJson(map[string]interface{}{
|
|
|
+ "status": 1,
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) GetWxUT() error {
|
|
|
+ defer util.Catch()
|
|
|
+ mac := l.GetString("mac")
|
|
|
+ reToken := ""
|
|
|
+ status := 0
|
|
|
+ if mac != "" {
|
|
|
+ reToken = getUToken(mac, l.GetSession("s_m_openid").(string))
|
|
|
+ status = 1
|
|
|
+ }
|
|
|
+ result := map[string]interface{}{
|
|
|
+ "token": reToken,
|
|
|
+ "status": status,
|
|
|
+ }
|
|
|
+ l.ServeJson(result)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) GetSubscribeToken() error {
|
|
|
+ defer util.Catch()
|
|
|
+ mac := l.GetString("mac")
|
|
|
+ token := l.GetString("token")
|
|
|
+ deMac, phone := decryptUToken(token)
|
|
|
+ reToken := ""
|
|
|
+ status := 0
|
|
|
+ if phone != "" && mac == deMac {
|
|
|
+ reToken = getSToken(deMac, phone)
|
|
|
+ redis.Put(redisPool, redisKeyPrefix_PPVOpenid+phone, 1, timeout)
|
|
|
+ status = 1 //success
|
|
|
+ }
|
|
|
+ result := map[string]interface{}{
|
|
|
+ "token": reToken,
|
|
|
+ "status": status,
|
|
|
+ }
|
|
|
+ l.ServeJson(result)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) ToAct(token string) error {
|
|
|
+ defer util.Catch()
|
|
|
+ act := l.GetString("act")
|
|
|
+ token = strings.TrimPrefix(l.Url(), "/jypc/toAct/")
|
|
|
+ token = strings.TrimSuffix(token,"?act="+act)
|
|
|
+ if token != "" && act != "" {
|
|
|
+ deMac, phone := decryptSToken(token)
|
|
|
+ b, err := redis.Exists(redisPool, redisKeyPrefix_PPVOpenid+phone)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "Error redis key "+redisKeyPrefix_PPVOpenid+phone, err.Error())
|
|
|
+ } else {
|
|
|
+ if b {
|
|
|
+ if phone != "" && deMac != "" {
|
|
|
+ l.SetSession(redisKey_pcOpenid, phone)
|
|
|
+ LoginInfo("", phone, l.Session())
|
|
|
+ sessUser := l.GetSession("user").(map[string]interface{})
|
|
|
+ if sessUser != nil {
|
|
|
+ if sessUser["s_nickname"] == nil || sessUser["s_nickname"] == "" {
|
|
|
+ hNickname := phone
|
|
|
+ if len(phone) == 11 {
|
|
|
+ hNickname = phone[0:3] + "****" + phone[7:]
|
|
|
+ }
|
|
|
+ sessUser["s_nickname"] = hNickname
|
|
|
+ l.SetSession("user", sessUser)
|
|
|
+ l.SetSession("nickname", hNickname)
|
|
|
+ l.SetSession("s_nickname", hNickname)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return l.Redirect("/jypc/" + act)
|
|
|
+ } else {
|
|
|
+ log.Println(logPrefix, "ToAct-token解析异常", "token:", token)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.Println(logPrefix, "redis key "+redisKeyPrefix_PPVOpenid+phone, "不存在")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return l.Redirect("/")
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) ToPushView() error {
|
|
|
+ defer util.Catch()
|
|
|
+ return l.Render("/pchelper/pushView.html")
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) ToSearch() error {
|
|
|
+ defer util.Catch()
|
|
|
+ return l.Redirect("/jylab/supsearch/index.html")
|
|
|
+}
|
|
|
+
|
|
|
+func (l *PcHelper) PushView() error {
|
|
|
+ defer util.Catch()
|
|
|
+ lasttime, _ := l.GetInt("lasttime")
|
|
|
+ myopenid := ""
|
|
|
+ if l.GetSession(redisKey_pcOpenid) != nil {
|
|
|
+ myopenid, _ = l.GetSession(redisKey_pcOpenid).(string)
|
|
|
+ }
|
|
|
+ log.Println(logPrefix, "PushView-param", "lasttime:", lasttime, "openid:", myopenid)
|
|
|
+ res := map[string]interface{}{}
|
|
|
+ res["success"] = false
|
|
|
+ if myopenid != "" && lasttime > 0 {
|
|
|
+ if lasttime == 1 {
|
|
|
+ lasttime = time.Now().Local().Unix()
|
|
|
+ }
|
|
|
+ thistime, list := getHistorypush(lasttime, 0, myopenid, nil, 0)
|
|
|
+ log.Println(logPrefix, "PushView-getHistorypush-size", len(*list))
|
|
|
+ if list != nil && len(*list) > 0 {
|
|
|
+ res["success"] = true
|
|
|
+ res["data"] = &list
|
|
|
+ res["thistime"] = thistime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ l.ServeJson(&res)
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+//发送验证码
|
|
|
+func SendIdentCode(phone string, session *httpsession.Session) bool {
|
|
|
+ lastSentTime, _ := session.Get("identCodeTime").(int64)
|
|
|
+ //60秒之内不允许重复发
|
|
|
+ if lastSentTime > 0 && time.Now().Unix()-lastSentTime <= 60 {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ s_ranNum := util.GetRandom(6) //生成随机数
|
|
|
+ session.Set("identCodeValue", s_ranNum)
|
|
|
+ session.Set("identCodeKey", phone)
|
|
|
+ session.Set("identCodeTime", time.Now().Unix())
|
|
|
+ //发送短信
|
|
|
+ param := make(map[string]string)
|
|
|
+ param["code"] = s_ranNum
|
|
|
+ log.Println("验证码", phone, s_ranNum)
|
|
|
+ jyutil.SendSMS("2175916", phone, param)
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
+//删除短信验证码有关的session
|
|
|
+func deleteIdentSession_(session *httpsession.Session) {
|
|
|
+ session.Del("identCodeValue")
|
|
|
+ session.Del("identCodeKey")
|
|
|
+ session.Del("identCodeTime")
|
|
|
+}
|
|
|
+
|
|
|
+func getSToken(params ...string) string {
|
|
|
+ if params != nil {
|
|
|
+ mac := params[0]
|
|
|
+ phone := params[1]
|
|
|
+ now := time.Now()
|
|
|
+ date := util.FormatDate(&now, util.Date_Full_Layout)
|
|
|
+ phone = base64.StdEncoding.EncodeToString([]byte(phone))
|
|
|
+ mxE := util.GetMd5String(mac + md5EncryptSep + phone + md5EncryptSep + date)
|
|
|
+ v := se.EncodeString(mac + othSep + phone + othSep + date + othSep + mxE)
|
|
|
+ return url.QueryEscape(v)
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+func decryptSToken(token string) (string, string) {
|
|
|
+ if token == "" {
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ log.Println(logPrefix, "SToken解析前token", token)
|
|
|
+ v, err := url.QueryUnescape(token)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "SToken QueryUnescape error", err)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ v = se.DecodeString(v)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "SToken Decrypt se error", err)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ log.Println(logPrefix, "SToken解析后token", v)
|
|
|
+ vs := strings.Split(v, othSep)
|
|
|
+ if len(vs) != 4 {
|
|
|
+ log.Println(logPrefix, "SToken Decrypt length error", vs)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ if vs[3] != util.GetMd5String(fmt.Sprintf("%s"+md5EncryptSep+"%s"+md5EncryptSep+"%s", vs[0], vs[1], vs[2])) {
|
|
|
+ log.Println(logPrefix, "SToken Decrypt mx error", vs)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ byt, err := base64.StdEncoding.DecodeString(vs[1])
|
|
|
+ openid := ""
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "UToken openid base64 decode error", err.Error())
|
|
|
+ } else {
|
|
|
+ openid = string(byt)
|
|
|
+ }
|
|
|
+ return vs[0], openid
|
|
|
+}
|
|
|
+
|
|
|
+//登录成功后的token
|
|
|
+func getUToken(params ...string) string {
|
|
|
+ if params != nil {
|
|
|
+ mac := params[0]
|
|
|
+ phone := params[1]
|
|
|
+ now := time.Now()
|
|
|
+ date := util.FormatDate(&now, util.Date_Full_Layout)
|
|
|
+ phone = base64.StdEncoding.EncodeToString([]byte(phone))
|
|
|
+ mxE := util.GetMd5String(mac + md5EncryptSep + phone + md5EncryptSep + date)
|
|
|
+ v, err := jyutil.AC.Encrypt(mac + othSep + phone + othSep + date + othSep + mxE)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "UToken Encrypt error", err)
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ return url.QueryEscape(v)
|
|
|
+ }
|
|
|
+ return ""
|
|
|
+}
|
|
|
+
|
|
|
+//返回mac phone
|
|
|
+func decryptUToken(token string) (string, string) {
|
|
|
+ if token == "" {
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ log.Println(logPrefix, "UToken解析前token", token)
|
|
|
+ v, err := url.QueryUnescape(token)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "UToken QueryUnescape error", err)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ v, err = jyutil.AC.Decrypt(v)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "UToken Decrypt aes error", err)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ log.Println(logPrefix, "UToken解析后token", v)
|
|
|
+ vs := strings.Split(v, othSep)
|
|
|
+ if len(vs) != 4 {
|
|
|
+ log.Println(logPrefix, "UToken Decrypt length error", vs)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ if vs[3] != util.GetMd5String(fmt.Sprintf("%s"+md5EncryptSep+"%s"+md5EncryptSep+"%s", vs[0], vs[1], vs[2])) {
|
|
|
+ log.Println(logPrefix, "UToken Decrypt mx error", vs)
|
|
|
+ return "", ""
|
|
|
+ }
|
|
|
+ byt, err := base64.StdEncoding.DecodeString(vs[1])
|
|
|
+ openid := ""
|
|
|
+ if err != nil {
|
|
|
+ log.Println(logPrefix, "UToken openid base64 decode error", err.Error())
|
|
|
+ } else {
|
|
|
+ openid = string(byt)
|
|
|
+ }
|
|
|
+ return vs[0], openid
|
|
|
+}
|